Browse Source

added doc

Toan Quach 10 months ago
parent
commit
1936c4a082

+ 17 - 14
taipy/core/reason/reason.py

@@ -14,19 +14,25 @@ from typing import Any, Optional
 
 
 class Reason:
 class Reason:
     """
     """
-    A reason holds the reason why specific actions cannot be performed.
+    A reason explains why a specific action cannot be performed.
+
+    This is a parent class aiming at being implemented by specific sub-classes.
+
+    Because Taipy applications are natively multiuser, asynchronous, and dynamic,
+    some functions might not be called in some specific contexts. You can protect
+    such calls by calling other methods that return a Reasons object. It acts like a
+    boolean: True if the operation can be performed and False otherwise.
+    If the action cannot be performed, the Reasons object holds all the `reasons as a list
+    of `Reason` objects. Each `Reason` holds an explanation of why the operation cannot be
+    performed.
 
 
     Attributes:
     Attributes:
-        reason (str): The reason why the action cannot be performed.
+        reason (str): The English representation of the reason why the action cannot be performed.
     """
     """
 
 
     def __init__(self, reason: str):
     def __init__(self, reason: str):
         self._reason = reason
         self._reason = reason
 
 
-    @property
-    def reason(self) -> str:
-        return self._reason
-
     def __str__(self) -> str:
     def __str__(self) -> str:
         return self._reason
         return self._reason
 
 
@@ -53,8 +59,7 @@ class _DataNodeReasonMixin:
 
 
 class DataNodeEditInProgress(Reason, _DataNodeReasonMixin):
 class DataNodeEditInProgress(Reason, _DataNodeReasonMixin):
     """
     """
-    DataNodeEditInProgress holds the reason a `DataNode^` is being edited,
-    which prevents specific actions from being performed.
+    A `DataNode^` is being edited, which prevents specific actions from being performed.
 
 
     Attributes:
     Attributes:
         datanode_id (str): The identifier of the `DataNode^`.
         datanode_id (str): The identifier of the `DataNode^`.
@@ -67,8 +72,7 @@ class DataNodeEditInProgress(Reason, _DataNodeReasonMixin):
 
 
 class DataNodeIsNotWritten(Reason, _DataNodeReasonMixin):
 class DataNodeIsNotWritten(Reason, _DataNodeReasonMixin):
     """
     """
-    DataNodeIsNotWritten holds the reason a `DataNode^` is not yet written,
-    which prevents specific actions from being performed.
+    A `DataNode^` has never been written, which prevents specific actions from being performed.
 
 
     Attributes:
     Attributes:
         datanode_id (str): The identifier of the `DataNode^`.
         datanode_id (str): The identifier of the `DataNode^`.
@@ -81,7 +85,7 @@ class DataNodeIsNotWritten(Reason, _DataNodeReasonMixin):
 
 
 class EntityIsNotSubmittableEntity(Reason):
 class EntityIsNotSubmittableEntity(Reason):
     """
     """
-    EntityIsNotSubmittableEntity holds the reason an entity is not submittable.
+    An entity is not a submittable entity, which prevents specific actions from being performed.
 
 
     Attributes:
     Attributes:
         entity_id (str): The identifier of the `Entity^`.
         entity_id (str): The identifier of the `Entity^`.
@@ -93,7 +97,7 @@ class EntityIsNotSubmittableEntity(Reason):
 
 
 class WrongConfigType(Reason):
 class WrongConfigType(Reason):
     """
     """
-    WrongConfigType holds the reason the provided config is not the valid config expected.
+    A config id is not a valid expected config, which prevents specific actions from being performed.
 
 
     Attributes:
     Attributes:
         config_id (str): The identifier of the config.
         config_id (str): The identifier of the config.
@@ -111,8 +115,7 @@ class WrongConfigType(Reason):
 
 
 class NotGlobalScope(Reason):
 class NotGlobalScope(Reason):
     """
     """
-    NotGlobalScope holds the reason the data node config does not have a GLOBAL scope,
-    which prevents certain actions from being performed.
+    A data node config does not have a GLOBAL scope, which prevents specific actions from being performed.
 
 
     Attributes:
     Attributes:
         config_id (str): The identifier of the config.
         config_id (str): The identifier of the config.

+ 5 - 0
taipy/core/reason/reasons.py

@@ -46,6 +46,11 @@ class Reasons:
 
 
     @property
     @property
     def reasons(self) -> str:
     def reasons(self) -> str:
+        """Retrieves a collections of reasons as a string that explains why the action cannot be performed.
+
+        Returns:
+            A string that contains all the reasons why the action cannot be performed.
+        """
         if self._reasons:
         if self._reasons:
             return "; ".join("; ".join([str(reason) for reason in reasons]) for reasons in self._reasons.values()) + "."
             return "; ".join("; ".join([str(reason) for reason in reasons]) for reasons in self._reasons.values()) + "."
         return ""
         return ""

+ 2 - 2
tests/core/data/test_data_manager.py

@@ -64,14 +64,14 @@ class TestDataManager:
         assert bool(reasons) is False
         assert bool(reasons) is False
         assert reasons._reasons[dn_config.id] == {NotGlobalScope(dn_config.id)}
         assert reasons._reasons[dn_config.id] == {NotGlobalScope(dn_config.id)}
         assert (
         assert (
-            list(reasons._reasons[dn_config.id])[0].reason
+            str(list(reasons._reasons[dn_config.id])[0])
             == f'Data node config "{dn_config.id}" does not have GLOBAL scope'
             == f'Data node config "{dn_config.id}" does not have GLOBAL scope'
         )
         )
 
 
         reasons = _DataManager._can_create(1)
         reasons = _DataManager._can_create(1)
         assert bool(reasons) is False
         assert bool(reasons) is False
         assert reasons._reasons["1"] == {WrongConfigType("1", DataNodeConfig.__name__)}
         assert reasons._reasons["1"] == {WrongConfigType("1", DataNodeConfig.__name__)}
-        assert list(reasons._reasons["1"])[0].reason == 'Object "1" must be a valid DataNodeConfig'
+        assert str(list(reasons._reasons["1"])[0]) == 'Object "1" must be a valid DataNodeConfig'
 
 
     def test_create_data_node_with_name_provided(self):
     def test_create_data_node_with_name_provided(self):
         dn_config = Config.configure_data_node(id="dn", foo="bar", name="acb")
         dn_config = Config.configure_data_node(id="dn", foo="bar", name="acb")

+ 1 - 1
tests/core/scenario/test_scenario_manager.py

@@ -391,7 +391,7 @@ def test_can_create():
     reasons = _ScenarioManager._can_create(1)
     reasons = _ScenarioManager._can_create(1)
     assert bool(reasons) is False
     assert bool(reasons) is False
     assert reasons._reasons["1"] == {WrongConfigType(1, ScenarioConfig.__name__)}
     assert reasons._reasons["1"] == {WrongConfigType(1, ScenarioConfig.__name__)}
-    assert list(reasons._reasons["1"])[0].reason == 'Object "1" must be a valid ScenarioConfig'
+    assert str(list(reasons._reasons["1"])[0]) == 'Object "1" must be a valid ScenarioConfig'
     with pytest.raises(AttributeError):
     with pytest.raises(AttributeError):
         _ScenarioManager._create(1)
         _ScenarioManager._create(1)