Browse Source

Merge pull request #636 from Avaiga/feature/#493-use-mypy

Feature/#493 - Enable mypy type checker
Đỗ Trường Giang 1 year ago
parent
commit
d46f2ece10
94 changed files with 283 additions and 268 deletions
  1. 0 1
      .github/workflows/partial-tests.yml
  2. 16 0
      .pre-commit-config.yaml
  3. 2 1
      doc/gui/examples/charts/advanced-selection.py
  4. 2 1
      doc/gui/examples/charts/continuous-error-multiple.py
  5. 4 2
      doc/gui/examples/charts/heatmap-annotated.py
  6. 1 1
      doc/gui/examples/charts/histogram-nbins.py
  7. 4 2
      doc/gui/examples/charts/map-lines.py
  8. 3 1
      doc/gui/examples/charts/radar-multiple.py
  9. 3 1
      doc/gui/examples/charts/radar-simple.py
  10. 3 3
      doc/gui/examples/charts/treemap-hierarchical-values.py
  11. 3 3
      doc/gui/examples/charts/waterfall-styling.py
  12. 1 1
      doc/gui/examples/controls/file_download-dynamic-temp-file.py
  13. 1 1
      doc/gui/examples/controls/file_download-dynamic.py
  14. 12 1
      doc/gui/extension/example_library/example_library.py
  15. 7 0
      pyproject.toml
  16. 0 63
      ruff.toml
  17. 3 4
      taipy/_run.py
  18. 1 1
      taipy/config/__init__.py
  19. 4 4
      taipy/config/checker/_checker.py
  20. 16 0
      taipy/config/common/typing.py
  21. 2 2
      taipy/core/_orchestrator/_dispatcher/_job_dispatcher.py
  22. 3 3
      taipy/core/_orchestrator/_dispatcher/_standalone_job_dispatcher.py
  23. 1 1
      taipy/core/_repository/_base_taipy_model.py
  24. 1 1
      taipy/core/_version/_cli/_version_cli.py
  25. 2 2
      taipy/core/_version/_version_converter.py
  26. 3 3
      taipy/core/_version/_version_manager.py
  27. 1 1
      taipy/core/_version/_version_model.py
  28. 1 0
      taipy/core/config/checkers/_config_id_checker.py
  29. 2 2
      taipy/core/config/checkers/_core_section_checker.py
  30. 6 3
      taipy/core/config/checkers/_data_node_config_checker.py
  31. 5 2
      taipy/core/config/checkers/_job_config_checker.py
  32. 1 1
      taipy/core/config/checkers/_migration_config_checker.py
  33. 4 1
      taipy/core/config/checkers/_scenario_config_checker.py
  34. 2 2
      taipy/core/config/checkers/_task_config_checker.py
  35. 1 1
      taipy/core/config/core_section.py
  36. 3 6
      taipy/core/config/scenario_config.py
  37. 7 4
      taipy/core/config/task_config.py
  38. 0 1
      taipy/core/data/data_node.py
  39. 2 2
      taipy/core/data/excel.py
  40. 2 2
      taipy/gui/_gui_section.py
  41. 6 3
      taipy/gui/data/decimator/scatter_decimator.py
  42. 3 5
      taipy/gui/data/pandas_data_accessor.py
  43. 1 1
      taipy/gui/gui.py
  44. 1 2
      taipy/gui/utils/_evaluator.py
  45. 3 2
      taipy/gui_core/_context.py
  46. 1 1
      taipy/rest/api/resources/cycle.py
  47. 2 1
      taipy/rest/api/resources/datanode.py
  48. 1 1
      taipy/rest/api/resources/job.py
  49. 2 1
      taipy/rest/api/resources/scenario.py
  50. 2 1
      taipy/rest/api/resources/sequence.py
  51. 2 1
      taipy/rest/api/resources/task.py
  52. 11 10
      tests/core/_orchestrator/_dispatcher/mock_standalone_dispatcher.py
  53. 1 1
      tests/gui/actions/test_download.py
  54. 1 1
      tests/gui/actions/test_get_state_id.py
  55. 1 1
      tests/gui/actions/test_hold_control.py
  56. 1 1
      tests/gui/actions/test_invoke_callback.py
  57. 1 1
      tests/gui/actions/test_navigate.py
  58. 1 1
      tests/gui/actions/test_notify.py
  59. 1 1
      tests/gui/actions/test_resume_control.py
  60. 1 1
      tests/gui/builder/control/test_button.py
  61. 5 5
      tests/gui/builder/control/test_chart.py
  62. 2 2
      tests/gui/builder/control/test_date.py
  63. 3 3
      tests/gui/builder/control/test_dialog.py
  64. 2 2
      tests/gui/builder/control/test_expandable.py
  65. 4 4
      tests/gui/builder/control/test_file_download.py
  66. 1 1
      tests/gui/builder/control/test_file_selector.py
  67. 4 4
      tests/gui/builder/control/test_image.py
  68. 1 1
      tests/gui/builder/control/test_indicator.py
  69. 2 2
      tests/gui/builder/control/test_input.py
  70. 2 2
      tests/gui/builder/control/test_layout.py
  71. 1 1
      tests/gui/builder/control/test_menu.py
  72. 1 1
      tests/gui/builder/control/test_navbar.py
  73. 2 2
      tests/gui/builder/control/test_number.py
  74. 4 4
      tests/gui/builder/control/test_pane.py
  75. 2 2
      tests/gui/builder/control/test_part.py
  76. 3 3
      tests/gui/builder/control/test_selector.py
  77. 7 7
      tests/gui/builder/control/test_slider.py
  78. 1 1
      tests/gui/builder/control/test_status.py
  79. 3 3
      tests/gui/builder/control/test_table.py
  80. 2 2
      tests/gui/builder/control/test_text.py
  81. 3 3
      tests/gui/builder/control/test_toggle.py
  82. 3 3
      tests/gui/builder/control/test_tree.py
  83. 4 0
      tests/gui/gui_specific/test_gui.py
  84. 3 3
      tests/gui/gui_specific/test_shared.py
  85. 1 1
      tests/gui/gui_specific/test_state.py
  86. 2 2
      tests/gui/long_runnig/test_long_running.py
  87. 12 11
      tests/gui/server/http/test_status.py
  88. 6 6
      tests/gui/utils/test_map_dict.py
  89. 4 4
      tests/gui_core/test_context_is_deletable.py
  90. 4 4
      tests/gui_core/test_context_is_editable.py
  91. 4 4
      tests/gui_core/test_context_is_promotable.py
  92. 2 2
      tests/gui_core/test_context_is_readable.py
  93. 4 4
      tests/gui_core/test_context_is_submitable.py
  94. 1 1
      tests/rest/setup/shared/config.py

+ 0 - 1
.github/workflows/partial-tests.yml

@@ -19,7 +19,6 @@ jobs:
           use-isort: false
           use-pycodestyle: false
           use-pylint: false
-          use-mypy: false  # TODO: re-enable mypy
           extra-mypy-options: "--ignore-missing-imports --implicit-optional --no-namespace-packages --exclude (taipy/templates/|generate_pyi.py|tools) --follow-imports skip"
 
       - uses: chartboost/ruff-action@v1

+ 16 - 0
.pre-commit-config.yaml

@@ -1,4 +1,20 @@
 repos:
+-   repo: https://github.com/pre-commit/mirrors-mypy
+    rev: v1.8.0
+    hooks:
+    -   id: mypy
+        additional_dependencies: [
+                'types-Markdown',
+                'types-python-dateutil',
+                'types-pytz',
+                'types-tzlocal',
+        ]
+        args:
+        - --ignore-missing-imports
+        - --implicit-optional
+        - --no-namespace-packages
+        - --exclude=(taipy/templates/|generate_pyi.py|tools)
+        - --follow-imports=skip
 -   repo: https://github.com/Lucas-C/pre-commit-hooks
     rev: v1.1.10
     hooks:

+ 2 - 1
doc/gui/examples/charts/advanced-selection.py

@@ -14,6 +14,7 @@
 #     python <script>
 # -----------------------------------------------------------------------------------------
 import random
+from typing import List
 
 import numpy
 
@@ -40,7 +41,7 @@ config = {
     "displayModeBar": False
 }
 
-selected_indices = []
+selected_indices: List = []
 
 mean_value = 0.0
 

+ 2 - 1
doc/gui/examples/charts/continuous-error-multiple.py

@@ -14,6 +14,7 @@
 #     python <script>
 # -----------------------------------------------------------------------------------------
 import datetime
+from typing import Dict, List
 
 import dateutil.relativedelta
 
@@ -25,7 +26,7 @@ period = dateutil.relativedelta.relativedelta(months=1)
 
 # Data
 # All arrays have the same size (the number of months to track)
-prices = {
+prices: Dict[str, List] = {
     # Data for apples
     "apples": [2.48, 2.47, 2.5, 2.47, 2.46, 2.38, 2.31, 2.25, 2.39, 2.41, 2.59, 2.61],
     "apples_low": [1.58, 1.58, 1.59, 1.64, 1.79, 1.54, 1.53, 1.61, 1.65, 2.02, 1.92, 1.54],

+ 4 - 2
doc/gui/examples/charts/heatmap-annotated.py

@@ -13,9 +13,11 @@
 # Python environment and run:
 #     python <script>
 # -----------------------------------------------------------------------------------------
+from typing import Dict, List
+
 from taipy.gui import Gui
 
-data = {
+data: Dict[str, List] = {
     "Temperatures": [
         [17.2, 27.4, 28.6, 21.5],
         [5.6, 15.1, 20.2, 8.1],
@@ -59,7 +61,7 @@ for city in range(len(cities)):
             "showarrow": False,
         }
         # Add the annotation to the layout's annotations array
-        layout["annotations"].append(annotation)
+        layout["annotations"].append(annotation)  # type: ignore[attr-defined]
 
 page = """
 ## Heatmap - Annotated

+ 1 - 1
doc/gui/examples/charts/histogram-nbins.py

@@ -18,7 +18,7 @@ import random
 from taipy.gui import Gui
 
 # Random set of 100 samples
-samples = {"x": [random.gauss() for i in range(100)]}
+samples = {"x": [random.gauss(mu=0.0, sigma=1.0) for _ in range(100)]}
 
 # Use the same data for both traces
 data = [samples, samples]

+ 4 - 2
doc/gui/examples/charts/map-lines.py

@@ -13,11 +13,13 @@
 # Python environment and run:
 #     python <script>
 # -----------------------------------------------------------------------------------------
+from typing import Any, Dict, List
+
 from taipy.gui import Gui
 
 # Busiest US airports
 # Source: https://en.wikipedia.org/wiki/List_of_busiest_airports_by_passenger_traffic
-airports = {
+airports: Dict[str, Dict[str, float]] = {
     "AMS": {"lat": 52.31047296675518, "lon": 4.76819929439927},
     "ATL": {"lat": 33.64086185344307, "lon": -84.43600501711686},
     "AYT": {"lat": 36.90419539293911, "lon": 30.801855337974292},
@@ -72,7 +74,7 @@ airports = {
 
 # Inter US airports flights
 # Source: https://www.faa.gov/air_traffic/by_the_numbers
-flights = [
+flights: List[Dict[str, Any]] = [
     {"from": "ATL", "to": "DFW", "traffic": 580},
     {"from": "ATL", "to": "MIA", "traffic": 224},
     {"from": "BOS", "to": "LAX", "traffic": 168},

+ 3 - 1
doc/gui/examples/charts/radar-multiple.py

@@ -13,11 +13,13 @@
 # Python environment and run:
 #     python <script>
 # -----------------------------------------------------------------------------------------
+from typing import Dict, List
+
 from taipy.gui import Gui
 
 # Skill categories
 skills = ["HTML", "CSS", "Java", "Python", "PHP", "JavaScript", "Photoshop"]
-data = [
+data: List[Dict[str, List]] = [
     # Proportion of skills used for Backend development
     {"Backend": [10, 10, 80, 70, 90, 30, 0], "Skills": skills},
     # Proportion of skills used for Frontend development

+ 3 - 1
doc/gui/examples/charts/radar-simple.py

@@ -13,10 +13,12 @@
 # Python environment and run:
 #     python <script>
 # -----------------------------------------------------------------------------------------
+from typing import Dict, List
+
 from taipy.gui import Gui
 
 # Source: www.statista.com (Most used programming languages in 2022)
-data = {
+data: Dict[str, List] = {
     # List of programming languages
     "Language": ["JavaScript", "HTML/CSS", "SQL", "Python", "Typescript", "Java", "Bash/Shell"],
     # Percentage of usage, per language

+ 3 - 3
doc/gui/examples/charts/treemap-hierarchical-values.py

@@ -56,9 +56,9 @@ continents = {
     "Antarctica": [{"name": "Whole", "surface": 14200000}],
 }
 
-name = []
-surface = []
-continent = []
+name: list = []
+surface: list = []
+continent: list = []
 
 for continent_name, countries in continents.items():
     # Create continent in root rectangle

+ 3 - 3
doc/gui/examples/charts/waterfall-styling.py

@@ -24,15 +24,15 @@ data = {
     # ["Hole1", "Hole2", ..., "Hole9"]
     "Hole": [f"Hole{h}" for h in range(1, n_holes + 1)] + ["Score"],
     # Par for each hole
-    "Par": [3, 4, 4, 5, 3, 5, 4, 5, 3] + [None],
+    "Par": [3, 4, 4, 5, 3, 5, 4, 5, 3] + [None],  # type: ignore
     # Score for each hole
-    "Score": [4, 4, 5, 4, 4, 5, 4, 5, 4] + [None],
+    "Score": [4, 4, 5, 4, 4, 5, 4, 5, 4] + [None],  # type: ignore
     # Represented as relative values except for the last one
     "M": n_holes * ["relative"] + ["total"],
 }
 
 # Compute difference (Score-Par)
-data["Diff"] = [data["Score"][i] - data["Par"][i] for i in range(0, n_holes)] + [None]
+data["Diff"] = [data["Score"][i] - data["Par"][i] for i in range(0, n_holes)] + [None]  # type: ignore[index]
 
 # Show positive values in red, and negative values in green
 options = {"decreasing": {"marker": {"color": "green"}}, "increasing": {"marker": {"color": "red"}}}

+ 1 - 1
doc/gui/examples/controls/file_download-dynamic-temp-file.py

@@ -39,7 +39,7 @@ def pi(precision: int) -> list[int]:
         n, na = n + na, na + 8
         d, da = d + da, da + 32
         t = (t * n) / d
-        s += t
+        s += t  # type: ignore[assignment]
     digits = []
     while s != 0:
         integral = int(s)

+ 1 - 1
doc/gui/examples/controls/file_download-dynamic.py

@@ -36,7 +36,7 @@ def pi(precision: int) -> list[int]:
         n, na = n + na, na + 8
         d, da = d + da, da + 32
         t = (t * n) / d
-        s += t
+        s += t  # type: ignore[assignment]
     digits = []
     while s != 0:
         integral = int(s)

+ 12 - 1
doc/gui/extension/example_library/example_library.py

@@ -1,3 +1,14 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+
 from taipy.gui.extension import Element, ElementLibrary, ElementProperty, PropertyType
 
 
@@ -31,7 +42,7 @@ class ExampleLibrary(ElementLibrary):
         numerator = props.get("numerator")
         denominator = props.get("denominator")
         # No denominator or numerator is 0: display the numerator
-        if denominator is None or int(numerator) == 0:
+        if denominator is None or int(numerator) == 0:  # type: ignore[arg-type]
             return f"<span>{numerator}</span>"
         # Denominator is zero: display infinity
         if int(denominator) == 0:

+ 7 - 0
pyproject.toml

@@ -51,6 +51,13 @@ max-complexity = 18
 [tool.ruff.lint.pydocstyle]
 convention = "google"
 
+[tool.mypy]
+ignore_missing_imports = true
+implicit_optional = true
+namespace_packages = false
+exclude = "(taipy/templates/|generate_pyi.py|tools)"
+follow_imports = "skip"
+
 [tool.pyright]
 
 [tool.codespell]

+ 0 - 63
ruff.toml

@@ -1,63 +0,0 @@
-exclude = [
-    ".git",
-    "__pycache__",
-    "setup.py",
-    "build",
-    "dist",
-    "releases",
-    ".venv",
-    ".tox",
-    ".mypy_cache",
-    ".pytest_cache",
-    ".vscode",
-    ".github",
-]
-line-length = 120
-indent-width = 4
-ignore-init-module-imports = true
-
-[lint]
-select = [
-    "E",  # pycodestyle errors
-    "F",  # pyflakes errors
-    "W",  # pycodestyle warnings
-    "C",  # mccabe complexity checker
-    "B",  # bugbear best practices checker
-    "T",  # mypy type errors
-    "B", # flake8-bugbear best practices checker
-    "I001", # isort import order
-]
-ignore = [
-    "E203",  # whitespace before ':'
-    # "E266",  # too many leading '#' for block comment
-    # "E501",  # line too long (82 > 79 characters)
-    "E722",  # do not use bare except
-    # "W503",  # line break before binary operator
-    # "F403",  # 'from module import *' used; unable to detect undefined names
-    # "F401", # module imported but unused
-    # "missing-imports",  # mypy: Missing module imports
-    "C401",  # Unnecessary generator (rewrite as a `set` comprehension)
-    "C405",  # Unnecessary list literal - rewrite as a literal
-    "C408",  # Unnecessary dict call - rewrite as a literal
-    "C409",  # Unnecessary list passed to tuple() - rewrite as a tuple literal
-    "C416",  # Unnecessary `set` comprehension (rewrite using `set()`)
-]
-
-# Allow fix for all enabled rules (when `--fix`) is provided.
-fixable = ["ALL"]
-unfixable = []
-
-[lint.per-file-ignores]
-"__init__.py" = ["F401", "F403"]  # unused import
-"_init.py" = ["F401", "F403"]  # unused import
-"taipy/config/stubs/pyi_header.py" = ["F401", "F403"]  # unused import
-"taipy/templates/*" = ["F401", "F403", "T201"]  # unused import, `print` found
-"tests/*" = ["T201"]  # `print` found
-"tools/*" = ["T201"]  # `print` found
-
-[lint.mccabe]
-# Flag errors (`C901`) whenever the complexity level exceeds 5.
-max-complexity = 18
-
-[pydocstyle]
-convention = "google"

+ 3 - 4
taipy/_run.py

@@ -57,7 +57,7 @@ def _run(*services: _AppType, **kwargs) -> t.Optional[Flask]:
         return None
 
     if gui and rest:
-        gui._set_flask(rest._app)  # type: ignore
+        gui._set_flask(rest._app)  # type: ignore[union-attr]
         return gui.run(**kwargs)
     else:
         app = rest or gui
@@ -65,15 +65,14 @@ def _run(*services: _AppType, **kwargs) -> t.Optional[Flask]:
         return app.run(**kwargs)
 
 
-# Avoid black adding too many empty lines
-# fmt: off
 if sys.version_info >= (3, 10):
+
     def __get_app(apps: t.Tuple[_AppType, ...], type_: t.Type[_AppTypeT]) -> t.Optional[_AppType]:
         def filter_isinstance(tl: _AppType) -> TypeGuard[_AppTypeT]:
             return isinstance(tl, type_)
 
         return next(filter(filter_isinstance, apps), None)
 else:
+
     def __get_app(apps: t.Tuple[_AppType, ...], type_: t.Type[_AppTypeT]) -> t.Optional[_AppType]:
         return next(filter(lambda a: isinstance(a, type_), apps), None)
-# fmt: on

+ 1 - 1
taipy/config/__init__.py

@@ -70,7 +70,7 @@ def _inject_section(
         raise TypeError
 
     if add_to_unconflicted_sections:
-        Config._comparator._add_unconflicted_section(section_clazz.name)  # type: ignore
+        Config._comparator._add_unconflicted_section(section_clazz.name)  # type: ignore[attr-defined]
 
     for exposed_configuration_method, configuration_method in configuration_methods:
         setattr(Config, exposed_configuration_method, configuration_method)

+ 4 - 4
taipy/config/checker/_checker.py

@@ -9,16 +9,16 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 
-from typing import List
+from typing import List, Type
 
-from ._checkers._config_checker import _ConfigChecker
+from ..common.typing import ConfigCheckerType
 from .issue_collector import IssueCollector
 
 
 class _Checker:
     """Holds the various checkers to perform on the config."""
 
-    _checkers: List[_ConfigChecker] = []
+    _checkers: List = []
 
     @classmethod
     def _check(cls, _applied_config):
@@ -28,5 +28,5 @@ class _Checker:
         return collector
 
     @classmethod
-    def add_checker(cls, checker_class: _ConfigChecker):
+    def add_checker(cls, checker_class: Type[ConfigCheckerType]):
         cls._checkers.append(checker_class)

+ 16 - 0
taipy/config/common/typing.py

@@ -0,0 +1,16 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+
+from typing import TypeVar
+
+from ..checker._checkers._config_checker import _ConfigChecker
+
+ConfigCheckerType = TypeVar("ConfigCheckerType", bound=_ConfigChecker)

+ 2 - 2
taipy/core/_orchestrator/_dispatcher/_job_dispatcher.py

@@ -12,7 +12,7 @@
 import threading
 from abc import abstractmethod
 from queue import Empty
-from typing import Dict
+from typing import Dict, Optional
 
 from taipy.config.config import Config
 from taipy.logger._taipy_logger import _TaipyLogger
@@ -32,7 +32,7 @@ class _JobDispatcher(threading.Thread):
     __logger = _TaipyLogger._get_logger()
     _nb_available_workers: int = 1
 
-    def __init__(self, orchestrator: _AbstractOrchestrator):
+    def __init__(self, orchestrator: Optional[_AbstractOrchestrator]):
         threading.Thread.__init__(self, name="Thread-Taipy-JobDispatcher")
         self.daemon = True
         self.orchestrator = orchestrator

+ 3 - 3
taipy/core/_orchestrator/_dispatcher/_standalone_job_dispatcher.py

@@ -9,7 +9,7 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 
-from concurrent.futures import ProcessPoolExecutor
+from concurrent.futures import Executor, ProcessPoolExecutor
 from functools import partial
 from typing import Callable, Optional
 
@@ -28,7 +28,7 @@ class _StandaloneJobDispatcher(_JobDispatcher):
     def __init__(self, orchestrator: Optional[_AbstractOrchestrator], subproc_initializer: Optional[Callable] = None):
         super().__init__(orchestrator)
         max_workers = Config.job_config.max_nb_of_workers or 1
-        self._executor = ProcessPoolExecutor(max_workers=max_workers, initializer=subproc_initializer)  # type: ignore
+        self._executor: Executor = ProcessPoolExecutor(max_workers=max_workers, initializer=subproc_initializer)  # type: ignore
         self._nb_available_workers = self._executor._max_workers  # type: ignore
 
     def _dispatch(self, job: Job):
@@ -39,7 +39,7 @@ class _StandaloneJobDispatcher(_JobDispatcher):
         """
         self._nb_available_workers -= 1
 
-        config_as_string = _TomlSerializer()._serialize(Config._applied_config)
+        config_as_string = _TomlSerializer()._serialize(Config._applied_config)  # type: ignore[attr-defined]
         future = self._executor.submit(_TaskFunctionWrapper(job.id, job.task), config_as_string=config_as_string)
 
         self._set_dispatched_processes(job.id, future)  # type: ignore

+ 1 - 1
taipy/core/_repository/_base_taipy_model.py

@@ -28,7 +28,7 @@ class _BaseModel:
             yield attr, value
 
     def to_dict(self) -> Dict[str, Any]:
-        model_dict = {**dataclasses.asdict(self)}
+        model_dict = {**dataclasses.asdict(self)}  # type: ignore[call-overload]
 
         for k, v in model_dict.items():
             if isinstance(v, enum.Enum):

+ 1 - 1
taipy/core/_version/_cli/_version_cli.py

@@ -216,7 +216,7 @@ class _VersionCLI:
             cls.__logger.error(f"Version '{version_2}' does not exist.")
             sys.exit(1)
 
-        Config._comparator._compare(
+        Config._comparator._compare(  # type: ignore[attr-defined]
             version_entity_1.config,
             version_entity_2.config,
             version_1,

+ 2 - 2
taipy/core/_version/_version_converter.py

@@ -23,10 +23,10 @@ class _VersionConverter(_AbstractConverter):
     def _entity_to_model(cls, version: _Version) -> _VersionModel:
         return _VersionModel(
             id=version.id, config=Config._to_json(version.config), creation_date=version.creation_date.isoformat()
-        )
+        )  # type: ignore[attr-defined]
 
     @classmethod
     def _model_to_entity(cls, model: _VersionModel) -> _Version:
-        version = _Version(id=model.id, config=Config._from_json(model.config))
+        version = _Version(id=model.id, config=Config._from_json(model.config))  # type: ignore[attr-defined]
         version.creation_date = datetime.fromisoformat(model.creation_date)
         return version

+ 3 - 3
taipy/core/_version/_version_manager.py

@@ -52,18 +52,18 @@ class _VersionManager(_Manager[_Version]):
     @classmethod
     def _get_or_create(cls, id: str, force: bool) -> _Version:
         if version := cls._get(id):
-            comparator_result = Config._comparator._find_conflict_config(version.config, Config._applied_config, id)
+            comparator_result = Config._comparator._find_conflict_config(version.config, Config._applied_config, id)  # type: ignore[attr-defined]
             if comparator_result.get(_ComparatorResult.CONFLICTED_SECTION_KEY):
                 if force:
                     cls.__logger.warning(
                         f"Option --force is detected, overriding the configuration of version {id} ..."
                     )
-                    version.config = Config._applied_config
+                    version.config = Config._applied_config  # type: ignore[attr-defined]
                 else:
                     raise ConflictedConfigurationError()
 
         else:
-            version = _Version(id=id, config=Config._applied_config)
+            version = _Version(id=id, config=Config._applied_config)  # type: ignore[attr-defined]
 
         cls._set(version)
         return version

+ 1 - 1
taipy/core/_version/_version_model.py

@@ -32,7 +32,7 @@ class _VersionModel(_BaseModel):
         Column("is_latest", Boolean),
     )
     id: str
-    config: Dict[str, Any]
+    config: str
     creation_date: str
 
     @staticmethod

+ 1 - 0
taipy/core/config/checkers/_config_id_checker.py

@@ -36,3 +36,4 @@ class _ConfigIdChecker(_ConfigChecker):
                     config_id,
                     f"`{config_id}` is used as the config_id of multiple configurations {str(entity_types)}",
                 )
+        return self._collector

+ 2 - 2
taipy/core/config/checkers/_core_section_checker.py

@@ -9,7 +9,7 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 
-from typing import Set
+from typing import Set, cast
 
 from taipy.config._config import _Config
 from taipy.config.checker._checkers._config_checker import _ConfigChecker
@@ -19,7 +19,6 @@ from ..core_section import CoreSection
 
 
 class _CoreSectionChecker(_ConfigChecker):
-
     _ACCEPTED_REPOSITORY_TYPES: Set[str] = {"filesystem", "sql"}
 
     def __init__(self, config: _Config, collector: IssueCollector):
@@ -27,6 +26,7 @@ class _CoreSectionChecker(_ConfigChecker):
 
     def _check(self) -> IssueCollector:
         if core_section := self._config._unique_sections.get(CoreSection.name):
+            core_section = cast(CoreSection, core_section)
             self._check_repository_type(core_section)
         return self._collector
 

+ 6 - 3
taipy/core/config/checkers/_data_node_config_checker.py

@@ -10,10 +10,10 @@
 # specific language governing permissions and limitations under the License.
 
 from datetime import timedelta
-from typing import Dict, List
+from typing import Dict, List, cast
 
 from taipy.config._config import _Config
-from taipy.config.checker._checker import _ConfigChecker
+from taipy.config.checker._checkers._config_checker import _ConfigChecker
 from taipy.config.checker.issue_collector import IssueCollector
 from taipy.config.common.scope import Scope
 
@@ -27,7 +27,10 @@ class _DataNodeConfigChecker(_ConfigChecker):
         super().__init__(config, collector)
 
     def _check(self) -> IssueCollector:
-        data_node_configs: Dict[str, DataNodeConfig] = self._config._sections[DataNodeConfig.name]
+        data_node_configs: Dict[str, DataNodeConfig] = cast(
+            Dict[str, DataNodeConfig],
+            self._config._sections[DataNodeConfig.name],
+        )
         task_attributes = [attr for attr in dir(Task) if not callable(getattr(Task, attr)) and not attr.startswith("_")]
         scenario_attributes = [
             attr for attr in dir(Scenario) if not callable(getattr(Scenario, attr)) and not attr.startswith("_")

+ 5 - 2
taipy/core/config/checkers/_job_config_checker.py

@@ -9,7 +9,7 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 
-from typing import Dict
+from typing import Dict, cast
 
 from taipy.config._config import _Config
 from taipy.config.checker._checkers._config_checker import _ConfigChecker
@@ -26,7 +26,10 @@ class _JobConfigChecker(_ConfigChecker):
     def _check(self) -> IssueCollector:
         if job_config := self._config._unique_sections.get(JobConfig.name):
             data_node_configs = self._config._sections[DataNodeConfig.name]
-            self._check_multiprocess_mode(job_config, data_node_configs)
+            self._check_multiprocess_mode(
+                cast(JobConfig, job_config),
+                cast(Dict[str, DataNodeConfig], data_node_configs),
+            )
         return self._collector
 
     def _check_multiprocess_mode(self, job_config: JobConfig, data_node_configs: Dict[str, DataNodeConfig]):

+ 1 - 1
taipy/core/config/checkers/_migration_config_checker.py

@@ -27,7 +27,7 @@ class _MigrationConfigChecker(_ConfigChecker):
 
             migration_fcts = migration_config.migration_fcts
 
-            for target_version, migration_functions in migration_config.migration_fcts.items():
+            for target_version, migration_functions in migration_config.migration_fcts.items():  # type: ignore[union-attr]
                 for config_id, migration_function in migration_functions.items():
                     self._check_callable(target_version, config_id, migration_function)
 

+ 4 - 1
taipy/core/config/checkers/_scenario_config_checker.py

@@ -9,6 +9,8 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 
+from typing import Dict, cast
+
 from taipy.config import Config
 from taipy.config._config import _Config
 from taipy.config.checker._checkers._config_checker import _ConfigChecker
@@ -25,7 +27,8 @@ class _ScenarioConfigChecker(_ConfigChecker):
         super().__init__(config, collector)
 
     def _check(self) -> IssueCollector:
-        scenario_configs = self._config._sections[ScenarioConfig.name]
+        scenario_configs = cast(Dict[str, ScenarioConfig], self._config._sections[ScenarioConfig.name])
+
         for scenario_config_id, scenario_config in scenario_configs.items():
             if scenario_config_id != _Config.DEFAULT_KEY:
                 self._check_if_entity_property_key_used_is_predefined(scenario_config)

+ 2 - 2
taipy/core/config/checkers/_task_config_checker.py

@@ -9,7 +9,7 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 
-from typing import List
+from typing import Dict, List, cast
 
 from taipy.config._config import _Config
 from taipy.config.checker._checkers._config_checker import _ConfigChecker
@@ -25,7 +25,7 @@ class _TaskConfigChecker(_ConfigChecker):
         super().__init__(config, collector)
 
     def _check(self) -> IssueCollector:
-        task_configs = self._config._sections[TaskConfig.name]
+        task_configs = cast(Dict[str, TaskConfig], self._config._sections[TaskConfig.name])
         scenario_attributes = [
             attr for attr in dir(Scenario) if not callable(getattr(Scenario, attr)) and not attr.startswith("_")
         ]

+ 1 - 1
taipy/core/config/core_section.py

@@ -271,7 +271,7 @@ class CoreSection(UniqueSection):
             **as_dict,
         )
 
-    def _update(self, as_dict: Dict[str, Any]):
+    def _update(self, as_dict: Dict[str, Any], default_section=None):
         self._root_folder = as_dict.pop(self._ROOT_FOLDER_KEY, self._root_folder)
         self._storage_folder = as_dict.pop(self._STORAGE_FOLDER_KEY, self._storage_folder)
         self._repository_type = as_dict.pop(self._REPOSITORY_TYPE_KEY, self._repository_type)

+ 3 - 6
taipy/core/config/scenario_config.py

@@ -61,15 +61,14 @@ class ScenarioConfig(Section):
         sequences: Optional[Dict[str, List[TaskConfig]]] = None,
         **properties,
     ):
-
         if tasks:
-            self._tasks = list(tasks) if isinstance(tasks, TaskConfig) else copy(tasks)
+            self._tasks = [tasks] if isinstance(tasks, TaskConfig) else copy(tasks)
         else:
             self._tasks = []
 
         if additional_data_nodes:
             self._additional_data_nodes = (
-                list(additional_data_nodes)
+                [additional_data_nodes]
                 if isinstance(additional_data_nodes, DataNodeConfig)
                 else copy(additional_data_nodes)
             )
@@ -159,9 +158,7 @@ class ScenarioConfig(Section):
         }
 
     @classmethod
-    def _from_dict(
-        cls, as_dict: Dict[str, Any], id: str, config: Optional[_Config] = None
-    ) -> "ScenarioConfig":  # type: ignore
+    def _from_dict(cls, as_dict: Dict[str, Any], id: str, config: Optional[_Config] = None) -> "ScenarioConfig":  # type: ignore
         as_dict.pop(cls._ID_KEY, id)
 
         tasks = cls.__get_task_configs(as_dict.pop(cls._TASKS_KEY, list()), config)

+ 7 - 4
taipy/core/config/task_config.py

@@ -10,7 +10,7 @@
 # specific language governing permissions and limitations under the License.
 
 from copy import copy
-from typing import Any, Dict, List, Optional, Union
+from typing import Any, Dict, List, Optional, Union, cast
 
 from taipy.config._config import _Config
 from taipy.config.common._template_handler import _TemplateHandler as _tpl
@@ -127,11 +127,14 @@ class TaskConfig(Section):
     def _from_dict(cls, as_dict: Dict[str, Any], id: str, config: Optional[_Config]):
         as_dict.pop(cls._ID_KEY, id)
         funct = as_dict.pop(cls._FUNCTION, None)
-        dn_configs = config._sections.get(DataNodeConfig.name, None) or []  # type: ignore
-        inputs = []
+        dn_configs: Dict[str, DataNodeConfig] = {}
+        if config:
+            dn_configs = cast(Dict[str, DataNodeConfig], config._sections.get(DataNodeConfig.name))
+
+        inputs: List[DataNodeConfig] = []
         if inputs_as_str := as_dict.pop(cls._INPUT_KEY, None):
             inputs = [dn_configs[dn_id] for dn_id in inputs_as_str if dn_id in dn_configs]
-        outputs = []
+        outputs: List[DataNodeConfig] = []
         if outputs_as_str := as_dict.pop(cls._OUTPUT_KEY, None):
             outputs = [dn_configs[ds_id] for ds_id in outputs_as_str if ds_id in dn_configs]
         skippable = as_dict.pop(cls._IS_SKIPPABLE_KEY, False)

+ 0 - 1
taipy/core/data/data_node.py

@@ -463,7 +463,6 @@ class DataNode(_Entity, _Labeled):
     def _read(self):
         raise NotImplementedError
 
-    @abstractmethod
     def _append(self, data):
         raise NotImplementedError
 

+ 2 - 2
taipy/core/data/excel.py

@@ -264,7 +264,7 @@ class ExcelDataNode(DataNode, _AbstractFileDataNode, _AbstractTabularDataNode):
             return {sheet_name: df.to_numpy() for sheet_name, df in sheets.items()}
         return sheets.to_numpy()
 
-    def _do_read_excel(self, engine, sheet_names, kwargs) -> pd.DataFrame:
+    def _do_read_excel(self, engine, sheet_names, kwargs) -> Union[Dict[Union[int, str], pd.DataFrame], pd.DataFrame]:
         df = pd.read_excel(
             self._path,
             sheet_name=sheet_names,
@@ -402,6 +402,6 @@ class ExcelDataNode(DataNode, _AbstractFileDataNode, _AbstractTabularDataNode):
         else:
             df = pd.DataFrame(data)
             if columns:
-                df.columns = columns
+                df.columns = pd.Index(columns, dtype="object")
             self.__write_excel_with_single_sheet(df.to_excel, self.path, index=False)
         self.track_edit(timestamp=datetime.now(), job_id=job_id)

+ 2 - 2
taipy/gui/_gui_section.py

@@ -40,9 +40,9 @@ class _GuiSection(UniqueSection):
     def _from_dict(cls, as_dict: t.Dict[str, t.Any], *_):
         return _GuiSection(property_list=list(default_config), **as_dict)
 
-    def _update(self, as_dict: t.Dict[str, t.Any]):
+    def _update(self, config_as_dict: t.Dict[str, t.Any], default_section=None):
         if self._property_list:
-            as_dict = {k: v for k, v in as_dict.items() if k in self._property_list}
+            as_dict = {k: v for k, v in config_as_dict.items() if k in self._property_list}
         self._properties.update(as_dict)
 
     @staticmethod

+ 6 - 3
taipy/gui/data/decimator/scatter_decimator.py

@@ -64,8 +64,10 @@ class ScatterDecimator(Decimator):
         mask.fill(False)
         grid_x, grid_y = round(width / self._binning_ratio), round(height / self._binning_ratio)
         x_col, y_col = data[:, 0], data[:, 1]
-        min_x, max_x = np.amin(x_col), np.amax(x_col)
-        min_y, max_y = np.amin(y_col), np.amax(y_col)
+        min_x: float = np.amin(x_col)
+        max_x: float = np.amax(x_col)
+        min_y: float = np.amin(y_col)
+        max_y: float = np.amax(y_col)
         min_max_x_diff, min_max_y_diff = max_x - min_x, max_y - min_y
         x_grid_map = np.rint((x_col - min_x) * grid_x / min_max_x_diff).astype(int)
         y_grid_map = np.rint((y_col - min_y) * grid_y / min_max_y_diff).astype(int)
@@ -75,7 +77,8 @@ class ScatterDecimator(Decimator):
             grid_z = grid_x
             grid_shape = (grid_x + 1, grid_y + 1, grid_z + 1)  # type: ignore
             z_col = data[:, 2]
-            min_z, max_z = np.amin(z_col), np.amax(z_col)
+            min_z: float = np.amin(z_col)
+            max_z: float = np.amax(z_col)
             min_max_z_diff = max_z - min_z
             z_grid_map = np.rint((z_col - min_z) * grid_z / min_max_z_diff).astype(int)
         grid = np.empty(grid_shape, dtype=int)

+ 3 - 5
taipy/gui/data/pandas_data_accessor.py

@@ -48,9 +48,9 @@ class _PandasDataAccessor(_DataAccessor):
         args = []
         if column_name:
             args.append(row[column_name])
-        args.extend((row.name, row))
+        args.extend((row.name, row))  # type: ignore[arg-type]
         if column_name:
-            args.append(column_name)
+            args.append(column_name)  # type: ignore[arg-type]
         try:
             return str(gui._call_function_with_state(user_function, args))
         except Exception as e:
@@ -134,9 +134,7 @@ class _PandasDataAccessor(_DataAccessor):
             # remove the date columns from the list of columns
             cols = list(set(cols) - set(datecols))
         dataframe = dataframe.iloc[new_indexes] if new_indexes is not None else dataframe
-        dataframe = dataframe.loc[
-            :, dataframe.dtypes[dataframe.dtypes.index.astype(str).isin(cols)].index
-        ]  # type: ignore
+        dataframe = dataframe.loc[:, dataframe.dtypes[dataframe.dtypes.index.astype(str).isin(cols)].index]  # type: ignore
         return dataframe
 
     def __apply_user_function(

+ 1 - 1
taipy/gui/gui.py

@@ -1944,7 +1944,7 @@ class Gui:
             return self._server.get_flask()
         raise RuntimeError("get_flask_app() cannot be invoked before run() has been called.")
 
-    def _set_frame(self, frame: FrameType):
+    def _set_frame(self, frame: t.Optional[FrameType]):
         if not isinstance(frame, FrameType):  # pragma: no cover
             raise RuntimeError("frame must be a FrameType where Gui can collect the local variables.")
         self.__frame = frame

+ 1 - 2
taipy/gui/utils/_evaluator.py

@@ -95,8 +95,7 @@ class _Evaluator:
             st = ast.parse('f"{' + e + '}"' if _Evaluator.__EXPR_EDGE_CASE_F_STRING.match(e) else e)
             args = [arg.arg for node in ast.walk(st) if isinstance(node, ast.arguments) for arg in node.args]
             targets = [
-                # type: ignore
-                compr.target.id
+                compr.target.id  # type: ignore[attr-defined]
                 for node in ast.walk(st)
                 if isinstance(node, ast.ListComp)
                 for compr in node.generators

+ 3 - 2
taipy/gui_core/_context.py

@@ -137,9 +137,10 @@ class _GuiCoreContext(CoreEventConsumerBase):
                     if event.operation != EventOperation.DELETION and is_readable(t.cast(SequenceId, event.entity_id))
                     else None
                 )
-                if sequence and hasattr(sequence, "parent_ids") and sequence.parent_ids:
+                if sequence and hasattr(sequence, "parent_ids") and sequence.parent_ids:  # type: ignore
                     self.gui._broadcast(
-                        _GuiCoreContext._CORE_CHANGED_NAME, {"scenario": [x for x in sequence.parent_ids]}
+                        _GuiCoreContext._CORE_CHANGED_NAME,
+                        {"scenario": [x for x in sequence.parent_ids]},  # type: ignore
                     )
             except Exception as e:
                 _warn(f"Access to sequence {event.entity_id} failed", e)

+ 1 - 1
taipy/rest/api/resources/cycle.py

@@ -26,7 +26,7 @@ from ..schemas import CycleResponseSchema, CycleSchema
 REPOSITORY = "cycle"
 
 
-def _get_or_raise(cycle_id: str) -> None:
+def _get_or_raise(cycle_id: str) -> Cycle:
     manager = _CycleManagerFactory._build_manager()
     cycle = manager._get(cycle_id)
     if not cycle:

+ 2 - 1
taipy/rest/api/resources/datanode.py

@@ -17,6 +17,7 @@ from flask import request
 from flask_restful import Resource
 
 from taipy.config.config import Config
+from taipy.core import DataNode
 from taipy.core.data._data_manager_factory import _DataManagerFactory
 from taipy.core.data.operator import Operator
 from taipy.core.exceptions.exceptions import NonExistingDataNode, NonExistingDataNodeConfig
@@ -53,7 +54,7 @@ ds_schema_map = {
 REPOSITORY = "data"
 
 
-def _get_or_raise(data_node_id: str) -> None:
+def _get_or_raise(data_node_id: str) -> DataNode:
     manager = _DataManagerFactory._build_manager()
     data_node = manager._get(data_node_id)
     if not data_node:

+ 1 - 1
taipy/rest/api/resources/job.py

@@ -26,7 +26,7 @@ from ..middlewares._middleware import _middleware
 from ..schemas import JobSchema
 
 
-def _get_or_raise(job_id: str):
+def _get_or_raise(job_id: str) -> Job:
     manager = _JobManagerFactory._build_manager()
     job = manager._get(job_id)
     if job is None:

+ 2 - 1
taipy/rest/api/resources/scenario.py

@@ -13,6 +13,7 @@ from flask import request
 from flask_restful import Resource
 
 from taipy.config.config import Config
+from taipy.core import Scenario
 from taipy.core.exceptions.exceptions import NonExistingScenario, NonExistingScenarioConfig
 from taipy.core.scenario._scenario_manager_factory import _ScenarioManagerFactory
 
@@ -22,7 +23,7 @@ from ..middlewares._middleware import _middleware
 from ..schemas import ScenarioResponseSchema
 
 
-def _get_or_raise(scenario_id: str):
+def _get_or_raise(scenario_id: str) -> Scenario:
     manager = _ScenarioManagerFactory._build_manager()
     scenario = manager._get(scenario_id)
     if scenario is None:

+ 2 - 1
taipy/rest/api/resources/sequence.py

@@ -13,6 +13,7 @@
 from flask import request
 from flask_restful import Resource
 
+from taipy.core import Sequence
 from taipy.core.exceptions.exceptions import NonExistingScenario, NonExistingSequence
 from taipy.core.scenario._scenario_manager_factory import _ScenarioManagerFactory
 from taipy.core.sequence._sequence_manager_factory import _SequenceManagerFactory
@@ -23,7 +24,7 @@ from ..middlewares._middleware import _middleware
 from ..schemas import SequenceResponseSchema
 
 
-def _get_or_raise(sequence_id: str):
+def _get_or_raise(sequence_id: str) -> Sequence:
     manager = _SequenceManagerFactory._build_manager()
     sequence = manager._get(sequence_id)
     if sequence is None:

+ 2 - 1
taipy/rest/api/resources/task.py

@@ -13,6 +13,7 @@ from flask import request
 from flask_restful import Resource
 
 from taipy.config.config import Config
+from taipy.core import Task
 from taipy.core.exceptions.exceptions import NonExistingTask, NonExistingTaskConfig
 from taipy.core.task._task_manager_factory import _TaskManagerFactory
 
@@ -22,7 +23,7 @@ from ..middlewares._middleware import _middleware
 from ..schemas import TaskSchema
 
 
-def _get_or_raise(task_id: str):
+def _get_or_raise(task_id: str) -> Task:
     manager = _TaskManagerFactory._build_manager()
     task = manager._get(task_id)
     if task is None:

+ 11 - 10
tests/core/_orchestrator/_dispatcher/mock_standalone_dispatcher.py

@@ -8,8 +8,9 @@
 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
+
 from concurrent.futures import Executor, Future
-from typing import Optional
+from typing import List, Optional
 
 from taipy.core import Job
 from taipy.core._orchestrator._abstract_orchestrator import _AbstractOrchestrator
@@ -17,8 +18,8 @@ from taipy.core._orchestrator._dispatcher import _StandaloneJobDispatcher
 
 
 class MockProcessPoolExecutor(Executor):
-    submit_called = []
-    f = []
+    submit_called: List = []
+    f: List = []
 
     def submit(self, fn, *args, **kwargs):
         self.submit_called.append((fn, args, kwargs))
@@ -36,15 +37,15 @@ class MockProcessPoolExecutor(Executor):
 class MockStandaloneDispatcher(_StandaloneJobDispatcher):
     def __init__(self, orchestrator: Optional[_AbstractOrchestrator]):
         super(_StandaloneJobDispatcher, self).__init__(orchestrator)
-        self._executor = MockProcessPoolExecutor()
-        self.dispatch_calls = []
-        self.release_worker_calls = []
-        self.set_dispatch_processes_calls = []
-        self.pop_dispatch_processes_calls = []
-        self.update_job_status_from_future_calls = []
+        self._executor: Executor = MockProcessPoolExecutor()
+        self.dispatch_calls: List = []
+        self.release_worker_calls: List = []
+        self.set_dispatch_processes_calls: List = []
+        self.pop_dispatch_processes_calls: List = []
+        self.update_job_status_from_future_calls: List = []
 
     def mock_exception_for_job(self, task_id, e: Exception):
-        self.exceptions[task_id] = e
+        self.exceptions[task_id] = e  # type: ignore[attr-defined]
 
     def _dispatch(self, job: Job):
         self.dispatch_calls.append(job)

+ 1 - 1
tests/gui/actions/test_download.py

@@ -38,7 +38,7 @@ def test_download(gui: Gui, helpers):
     flask_client.get(f"/taipy-jsx/test?client_id={cid}")
     with gui.get_flask_app().test_request_context(f"/taipy-jsx/test/?client_id={cid}", data={"client_id": cid}):
         g.client_id = cid
-        download(gui._Gui__state, "some text", "filename.txt", "on_download_action")
+        download(gui._Gui__state, "some text", "filename.txt", "on_download_action")  # type: ignore[attr-defined]
 
     received_messages = ws_client.get_received()
     helpers.assert_outward_ws_simple_message(

+ 1 - 1
tests/gui/actions/test_get_state_id.py

@@ -33,4 +33,4 @@ def test_get_state_id(gui: Gui, helpers):
     flask_client.get(f"/taipy-jsx/test?client_id={cid}")
     with gui.get_flask_app().app_context():
         g.client_id = cid
-        assert cid == get_state_id(gui._Gui__state)
+        assert cid == get_state_id(gui._Gui__state)  # type: ignore[attr-defined]

+ 1 - 1
tests/gui/actions/test_hold_control.py

@@ -35,7 +35,7 @@ def test_hold_control(gui: Gui, helpers):
     flask_client.get(f"/taipy-jsx/test?client_id={cid}")
     with gui.get_flask_app().test_request_context(f"/taipy-jsx/test/?client_id={cid}", data={"client_id": cid}):
         g.client_id = cid
-        hold_control(gui._Gui__state)
+        hold_control(gui._Gui__state)  # type: ignore[attr-defined]
 
     received_messages = ws_client.get_received()
     helpers.assert_outward_ws_simple_message(

+ 1 - 1
tests/gui/actions/test_invoke_callback.py

@@ -40,4 +40,4 @@ def test_invoke_callback(gui: Gui, helpers):
     with gui.get_flask_app().app_context():
         g.client_id = cid
         invoke_callback(gui, cid, user_callback, [])
-        assert gui._Gui__state.val == 10
+        assert gui._Gui__state.val == 10  # type: ignore[attr-defined]

+ 1 - 1
tests/gui/actions/test_navigate.py

@@ -35,7 +35,7 @@ def test_navigate(gui: Gui, helpers):
     flask_client.get(f"/taipy-jsx/test?client_id={cid}")
     with gui.get_flask_app().test_request_context(f"/taipy-jsx/test/?client_id={cid}", data={"client_id": cid}):
         g.client_id = cid
-        navigate(gui._Gui__state, "test")
+        navigate(gui._Gui__state, "test")  # type: ignore[attr-defined]
 
     received_messages = ws_client.get_received()
     helpers.assert_outward_ws_simple_message(received_messages[0], "NA", {"to": "test"})

+ 1 - 1
tests/gui/actions/test_notify.py

@@ -35,7 +35,7 @@ def test_notify(gui: Gui, helpers):
     flask_client.get(f"/taipy-jsx/test?client_id={cid}")
     with gui.get_flask_app().test_request_context(f"/taipy-jsx/test/?client_id={cid}", data={"client_id": cid}):
         g.client_id = cid
-        notify(gui._Gui__state, "Info", "Message")
+        notify(gui._Gui__state, "Info", "Message")  # type: ignore[attr-defined]
 
     received_messages = ws_client.get_received()
     helpers.assert_outward_ws_simple_message(received_messages[0], "AL", {"atype": "Info", "message": "Message"})

+ 1 - 1
tests/gui/actions/test_resume_control.py

@@ -35,7 +35,7 @@ def test_resume_control(gui: Gui, helpers):
     flask_client.get(f"/taipy-jsx/test?client_id={cid}")
     with gui.get_flask_app().test_request_context(f"/taipy-jsx/test/?client_id={cid}", data={"client_id": cid}):
         g.client_id = cid
-        resume_control(gui._Gui__state)
+        resume_control(gui._Gui__state)  # type: ignore[attr-defined]
 
     received_messages = ws_client.get_received()
     helpers.assert_outward_ws_simple_message(received_messages[0], "BL", {"message": None})

+ 1 - 1
tests/gui/builder/control/test_button.py

@@ -16,6 +16,6 @@ def test_button_builder_1(gui: Gui, test_client, helpers):
     gui._bind_var_val("name", "World!")
     gui._bind_var_val("btn_id", "button1")
     with tgb.Page(frame=None) as page:
-        tgb.button(label="Hello {name}", id="{btn_id}")
+        tgb.button(label="Hello {name}", id="{btn_id}")  # type: ignore[attr-defined]
     expected_list = ["<Button", 'defaultLabel="Hello World!"', "label={tp_TpExPr_Hello_name_TPMDL_0_0"]
     helpers.test_control_builder(gui, page, expected_list)

+ 5 - 5
tests/gui/builder/control/test_chart.py

@@ -30,7 +30,7 @@ def test_chart_builder_1(gui: Gui, helpers, csvdata):
     chart_type = [None, "scatter"]  # noqa: F841
     xaxis = [None, "x2"]  # noqa: F841
     with tgb.Page(frame=None) as page:
-        tgb.chart(
+        tgb.chart(  # type: ignore[attr-defined]
             data="{csvdata}",
             x="Day",
             selected_color="green",
@@ -65,7 +65,7 @@ def test_chart_builder_1(gui: Gui, helpers, csvdata):
 def test_chart_builder_2(gui: Gui, helpers, csvdata):
     selected_indices = [14258]  # noqa: F841
     with tgb.Page(frame=None) as page:
-        tgb.chart(
+        tgb.chart(  # type: ignore[attr-defined]
             data="{csvdata}",
             x="Day",
             selected_color="green",
@@ -161,7 +161,7 @@ def test_map_builder(gui: Gui, helpers):
         "margin": {"r": 0, "t": 0, "b": 0, "l": 0},
     }
     with tgb.Page(frame=None) as page:
-        tgb.chart(
+        tgb.chart(  # type: ignore[attr-defined]
             data="{mapData}",
             type="scattermapbox",
             marker="{marker}",
@@ -198,7 +198,7 @@ def test_chart_indexed_properties_builder(gui: Gui, helpers):
     data["Montpellier 2"] = [x * (1 - (random.random() / 10)) for x in data["Montpellier"]]
 
     with tgb.Page(frame=None) as page:
-        tgb.chart(
+        tgb.chart(  # type: ignore[attr-defined]
             data="{data}",
             x="Date",
             mode="lines",
@@ -242,7 +242,7 @@ def test_chart_indexed_properties_with_arrays_builder(gui: Gui, helpers):
     colors = [None, "blue", "blue", None, "red", "red"]  # noqa: F841
 
     with tgb.Page(frame=None) as page:
-        tgb.chart(
+        tgb.chart(  # type: ignore[attr-defined]
             data="{data}",
             x="Date",
             mode="lines",

+ 2 - 2
tests/gui/builder/control/test_date.py

@@ -18,7 +18,7 @@ from taipy.gui import Gui
 def test_date_builder_1(gui: Gui, test_client, helpers):
     gui._bind_var_val("date", datetime.strptime("15 Dec 2020", "%d %b %Y"))
     with tgb.Page(frame=None) as page:
-        tgb.date(id="date", date="{date}")
+        tgb.date(id="date", date="{date}")  # type: ignore[attr-defined]
     expected_list = [
         "<DateSelector",
         'defaultDate="2020-12-',
@@ -31,7 +31,7 @@ def test_date_builder_1(gui: Gui, test_client, helpers):
 def test_date_builder_2(gui: Gui, test_client, helpers):
     gui._bind_var_val("date", datetime.strptime("15 Dec 2020", "%d %b %Y"))
     with tgb.Page(frame=None) as page:
-        tgb.date(id="date", date="{date}", with_time=True)
+        tgb.date(id="date", date="{date}", with_time=True)  # type: ignore[attr-defined]
     expected_list = [
         "<DateSelector",
         'defaultDate="2020-12-',

+ 3 - 3
tests/gui/builder/control/test_dialog.py

@@ -19,7 +19,7 @@ def test_dialog_builder_1(gui: Gui, helpers):
     dialog_open = False  # noqa: F841
     gui._set_frame(inspect.currentframe())
     with tgb.Page(frame=None) as page:
-        tgb.dialog(title="This is a Dialog", open="{dialog_open}", page="page_test", on_action="validate_action")
+        tgb.dialog(title="This is a Dialog", open="{dialog_open}", page="page_test", on_action="validate_action")  # type: ignore[attr-defined]
     expected_list = [
         "<Dialog",
         'onAction="validate_action"',
@@ -36,7 +36,7 @@ def test_dialog_builder_2(gui: Gui, helpers):
     partial = gui.add_partial(Markdown("# A partial"))  # noqa: F841
     dialog_open = False  # noqa: F841
     with tgb.Page(frame=None) as page:
-        tgb.dialog(
+        tgb.dialog(  # type: ignore[attr-defined]
             title="Another Dialog",
             open="{dialog_open}",
             partial="{partial}",
@@ -57,7 +57,7 @@ def test_dialog_labels_builder(gui: Gui, helpers):
     gui._set_frame(inspect.currentframe())
     dialog_open = False  # noqa: F841
     with tgb.Page(frame=None) as page:
-        tgb.dialog(
+        tgb.dialog(  # type: ignore[attr-defined]
             title="Another Dialog",
             open="{dialog_open}",
             page="page_test",

+ 2 - 2
tests/gui/builder/control/test_expandable.py

@@ -14,8 +14,8 @@ from taipy.gui import Gui
 
 
 def test_expandable_builder_1(gui: Gui, helpers):
-    with tgb.expandable(title="Expandable section", expanded=False) as content:
-        tgb.text(value="This is an expandable section")
+    with tgb.expandable(title="Expandable section", expanded=False) as content:  # type: ignore[attr-defined]
+        tgb.text(value="This is an expandable section")  # type: ignore[attr-defined]
     expected_list = [
         "<Expandable",
         "expanded={false}",

+ 4 - 4
tests/gui/builder/control/test_file_download.py

@@ -20,7 +20,7 @@ from taipy.gui import Gui
 def test_file_download_url_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("content", "some_url")
     with tgb.Page(frame=None) as page:
-        tgb.file_download(content="{content}")
+        tgb.file_download(content="{content}")  # type: ignore[attr-defined]
     expected_list = [
         "<FileDownload",
         "content={_TpC_tpec_TpExPr_content_TPMDL_0}",
@@ -33,7 +33,7 @@ def test_file_download_file_builder(gui: Gui, test_client, helpers):
     with open((pathlib.Path(__file__).parent.parent.parent / "resources" / "fred.png").resolve(), "rb") as content:
         gui._bind_var_val("content", content.read())
         with tgb.Page(frame=None) as page:
-            tgb.file_download(content="{content}")
+            tgb.file_download(content="{content}")  # type: ignore[attr-defined]
         expected_list = [
             "<FileDownload",
             'defaultContent="data:image/png;base64,',
@@ -48,7 +48,7 @@ def test_file_download_path_builder(gui: Gui, test_client, helpers):
         "content", str((pathlib.Path(__file__).parent.parent.parent / "resources" / "fred.png").resolve())
     )
     with tgb.Page(frame=None) as page:
-        tgb.file_download(content="{content}")
+        tgb.file_download(content="{content}")  # type: ignore[attr-defined]
     expected_list = [
         "<FileDownload",
         'defaultContent="/taipy-content/taipyStatic0/fred.png',
@@ -60,7 +60,7 @@ def test_file_download_any_file_builder(gui: Gui, test_client, helpers):
     with open(os.path.abspath(__file__), "rb") as content:
         gui._bind_var_val("content", content.read())
         with tgb.Page(frame=None) as page:
-            tgb.file_download(content="{content}")
+            tgb.file_download(content="{content}")  # type: ignore[attr-defined]
         expected_list = [
             "<FileDownload",
             'defaultContent="data:text/x',

+ 1 - 1
tests/gui/builder/control/test_file_selector.py

@@ -16,7 +16,7 @@ from taipy.gui import Gui
 def test_file_selector_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("content", None)
     with tgb.Page(frame=None) as page:
-        tgb.file_selector(content="{content}", label="label", on_action="action")
+        tgb.file_selector(content="{content}", label="label", on_action="action")  # type: ignore[attr-defined]
     expected_list = [
         "<FileSelector",
         'updateVarName="tpec_TpExPr_content_TPMDL_0"',

+ 4 - 4
tests/gui/builder/control/test_image.py

@@ -20,7 +20,7 @@ from taipy.gui import Gui
 def test_image_url_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("content", "some_url")
     with tgb.Page(frame=None) as page:
-        tgb.image(content="{content}")
+        tgb.image(content="{content}")  # type: ignore[attr-defined]
     expected_list = [
         "<Image",
         "content={_TpCi_tpec_TpExPr_content_TPMDL_0}",
@@ -33,7 +33,7 @@ def test_image_file_builder(gui: Gui, test_client, helpers):
     with open((pathlib.Path(__file__).parent.parent.parent / "resources" / "fred.png").resolve(), "rb") as content:
         gui._bind_var_val("content", content.read())
         with tgb.Page(frame=None) as page:
-            tgb.image(content="{content}")
+            tgb.image(content="{content}")  # type: ignore[attr-defined]
         expected_list = [
             "<Image",
             'defaultContent="data:image/png;base64,',
@@ -48,7 +48,7 @@ def test_image_path_builder(gui: Gui, test_client, helpers):
         "content", str((pathlib.Path(__file__).parent.parent.parent / "resources" / "fred.png").resolve())
     )
     with tgb.Page(frame=None) as page:
-        tgb.image(content="{content}")
+        tgb.image(content="{content}")  # type: ignore[attr-defined]
     expected_list = [
         "<Image",
         'defaultContent="/taipy-content/taipyStatic0/fred.png',
@@ -60,7 +60,7 @@ def test_image_bad_file_builder(gui: Gui, test_client, helpers):
     with open(os.path.abspath(__file__), "rb") as content:
         gui._bind_var_val("content", content.read())
         with tgb.Page(frame=None) as page:
-            tgb.image(content="{content}")
+            tgb.image(content="{content}")  # type: ignore[attr-defined]
         expected_list = [
             "<Image",
             'defaultContent="Invalid content: text/x',

+ 1 - 1
tests/gui/builder/control/test_indicator.py

@@ -16,7 +16,7 @@ from taipy.gui import Gui
 def test_indicator_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("val", 15)
     with tgb.Page(frame=None) as page:
-        tgb.indicator(display=12, value="{val}", min=1, max=20, format="%.2f")
+        tgb.indicator(display=12, value="{val}", min=1, max=20, format="%.2f")  # type: ignore[attr-defined]
     expected_list = [
         "<Indicator",
         'libClassName="taipy-indicator"',

+ 2 - 2
tests/gui/builder/control/test_input.py

@@ -19,7 +19,7 @@ def test_input_builder(gui: Gui, helpers):
     x = "Hello World!"  # noqa: F841
     gui._set_frame(inspect.currentframe())
     with tgb.Page(frame=None) as page:
-        tgb.input(value="{x}")
+        tgb.input(value="{x}")  # type: ignore[attr-defined]
     expected_list = [
         "<Input",
         'updateVarName="tpec_TpExPr_x_TPMDL_0"',
@@ -34,7 +34,7 @@ def test_password_builder(gui: Gui, helpers):
     x = "Hello World!"  # noqa: F841
     gui._set_frame(inspect.currentframe())
     with tgb.Page(frame=None) as page:
-        tgb.input(value="{x}", password=True)
+        tgb.input(value="{x}", password=True)  # type: ignore[attr-defined]
     expected_list = [
         "<Input",
         'updateVarName="tpec_TpExPr_x_TPMDL_0"',

+ 2 - 2
tests/gui/builder/control/test_layout.py

@@ -15,7 +15,7 @@ from taipy.gui import Gui
 
 def test_layout_builder_1(gui: Gui, helpers):
     with tgb.Page(frame=None) as page:
-        with tgb.layout(columns="1 1", gap="1rem"):
-            tgb.text(value="This is a layout section")
+        with tgb.layout(columns="1 1", gap="1rem"):  # type: ignore[attr-defined]
+            tgb.text(value="This is a layout section")  # type: ignore[attr-defined]
     expected_list = ["<Layout", 'columns="1 1', 'gap="1rem"', "This is a layout section"]
     helpers.test_control_builder(gui, page, expected_list)

+ 1 - 1
tests/gui/builder/control/test_menu.py

@@ -16,7 +16,7 @@ from taipy.gui import Gui
 def test_menu_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("lov", ["Item 1", "Item 2", "Item 3", "Item 4"])
     with tgb.Page(frame=None) as page:
-        tgb.menu(lov="{lov}", on_action="on_menu_action")
+        tgb.menu(lov="{lov}", on_action="on_menu_action")  # type: ignore[attr-defined]
     expected_list = [
         "<MenuCtl",
         'libClassName="taipy-menu"',

+ 1 - 1
tests/gui/builder/control/test_navbar.py

@@ -24,7 +24,7 @@ def test_navbar_builder(gui: Gui, test_client, helpers):
         ],
     )
     with tgb.Page(frame=None) as page:
-        tgb.navbar(lov="{navlov}")
+        tgb.navbar(lov="{navlov}")  # type: ignore[attr-defined]
     expected_list = [
         "<NavBar",
         'defaultLov="[[&quot;/page1&quot;, &quot;Page 1&quot;], [&quot;/page2&quot;, &quot;Page 2&quot;], [&quot;/page3&quot;, &quot;Page 3&quot;], [&quot;/page4&quot;, &quot;Page 4&quot;]]"',  # noqa: E501

+ 2 - 2
tests/gui/builder/control/test_number.py

@@ -15,7 +15,7 @@ from taipy.gui import Gui
 
 def test_number_builder_1(gui: Gui, helpers):
     with tgb.Page(frame=None) as page:
-        tgb.number(value="10")
+        tgb.number(value="10")  # type: ignore[attr-defined]
     expected_list = ["<Input", 'value="10"', 'type="number"']
     helpers.test_control_builder(gui, page, expected_list)
 
@@ -23,7 +23,7 @@ def test_number_builder_1(gui: Gui, helpers):
 def test_number_builder_2(gui: Gui, test_client, helpers):
     gui._bind_var_val("x", "10")
     with tgb.Page(frame=None) as page:
-        tgb.number(value="{x}")
+        tgb.number(value="{x}")  # type: ignore[attr-defined]
     expected_list = [
         "<Input",
         'updateVarName="_TpN_tpec_TpExPr_x_TPMDL_0"',

+ 4 - 4
tests/gui/builder/control/test_pane.py

@@ -16,8 +16,8 @@ from taipy.gui import Gui
 def test_pane_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("show_pane", False)
     with tgb.Page(frame=None) as page:
-        with tgb.pane(open="{show_pane}"):
-            tgb.text(value="This is a Pane")
+        with tgb.pane(open="{show_pane}"):  # type: ignore[attr-defined]
+            tgb.text(value="This is a Pane")  # type: ignore[attr-defined]
     expected_list = [
         "<Pane",
         'anchor="left"',
@@ -31,8 +31,8 @@ def test_pane_builder(gui: Gui, test_client, helpers):
 def test_pane_persistent_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("show_pane", False)
     with tgb.Page(frame=None) as page:
-        with tgb.pane(open="{show_pane}", persistent=True):
-            tgb.text(value="This is a Pane")
+        with tgb.pane(open="{show_pane}", persistent=True):  # type: ignore[attr-defined]
+            tgb.text(value="This is a Pane")  # type: ignore[attr-defined]
     expected_list = [
         "<Pane",
         'anchor="left"',

+ 2 - 2
tests/gui/builder/control/test_part.py

@@ -15,7 +15,7 @@ from taipy.gui import Gui
 
 def test_part_builder_1(gui: Gui, helpers):
     with tgb.Page(frame=None) as page:
-        with tgb.part(class_name="class1"):
-            tgb.text(value="This is a part")
+        with tgb.part(class_name="class1"):  # type: ignore[attr-defined]
+            tgb.text(value="This is a part")  # type: ignore[attr-defined]
     expected_list = ["<Part", "This is a part"]
     helpers.test_control_builder(gui, page, expected_list)

+ 3 - 3
tests/gui/builder/control/test_selector.py

@@ -17,7 +17,7 @@ def test_selector_builder_1(gui: Gui, test_client, helpers):
     gui._bind_var_val("selected_val", ["l1", "l2"])
     gui._bind_var_val("selector_properties", {"lov": [("l1", "v1"), ("l2", "v2"), ("l3", "v3")], "filter": True})
     with tgb.Page(frame=None) as page:
-        tgb.selector(value="{selected_val}", properties="{selector_properties}", multiple=True)
+        tgb.selector(value="{selected_val}", properties="{selector_properties}", multiple=True)  # type: ignore[attr-defined]
     expected_list = [
         "<Selector",
         'defaultLov="[[&quot;l1&quot;, &quot;v1&quot;], [&quot;l2&quot;, &quot;v2&quot;], [&quot;l3&quot;, &quot;v3&quot;]]"',  # noqa: E501
@@ -33,7 +33,7 @@ def test_selector_builder_1(gui: Gui, test_client, helpers):
 def test_selector_builder_2(gui: Gui, test_client, helpers):
     gui._bind_var_val("selected_val", "Item 2")
     with tgb.Page(frame=None) as page:
-        tgb.selector(value="{selected_val}", lov="Item 1;Item 2; This is a another value")
+        tgb.selector(value="{selected_val}", lov="Item 1;Item 2; This is a another value")  # type: ignore[attr-defined]
     expected_list = [
         "<Selector",
         'defaultLov="[&quot;Item 1&quot;, &quot;Item 2&quot;, &quot; This is a another value&quot;]"',
@@ -52,7 +52,7 @@ def test_selector_builder_3(gui: Gui, test_client, helpers):
     )
     gui._bind_var_val("selected_obj", {"id": "1", "name": "scenario 1"})
     with tgb.Page(frame=None) as page:
-        tgb.selector(
+        tgb.selector(  # type: ignore[attr-defined]
             value="{selected_obj}",
             lov="{scenario_list}",
             adapter="{lambda elt: (elt['id'], elt['name'])}",

+ 7 - 7
tests/gui/builder/control/test_slider.py

@@ -18,7 +18,7 @@ from taipy.gui import Gui
 def test_slider_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("x", 10)
     with tgb.Page(frame=None) as page:
-        tgb.slider(value="{x}")
+        tgb.slider(value="{x}")  # type: ignore[attr-defined]
     expected_list = [
         "<Slider",
         'updateVarName="_TpN_tpec_TpExPr_x_TPMDL_0',
@@ -31,7 +31,7 @@ def test_slider_builder(gui: Gui, test_client, helpers):
 def test_slider_with_min_max_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("x", 0)
     with tgb.Page(frame=None) as page:
-        tgb.slider(value="{x}", min=-10, max=10)
+        tgb.slider(value="{x}", min=-10, max=10)  # type: ignore[attr-defined]
     expected_list = ["<Slider", "min={-10.0}", "max={10.0}", "defaultValue={0}"]
     helpers.test_control_builder(gui, page, expected_list)
 
@@ -41,7 +41,7 @@ def test_slider_with_dict_labels_builder(gui: Gui, helpers):
     labels = {"Item 1": "Label Start", "Item 3": "Label End"}  # noqa: F841
     gui._set_frame(inspect.currentframe())
     with tgb.Page(frame=None) as page:
-        tgb.slider(value="{sel}", lov="Item 1;Item 2;Item 3", labels=labels)
+        tgb.slider(value="{sel}", lov="Item 1;Item 2;Item 3", labels=labels)  # type: ignore[attr-defined]
     expected_list = [
         "<Slider",
         'labels="{&quot;Item 1&quot;: &quot;Label Start&quot;, &quot;Item 3&quot;: &quot;Label End&quot;}"',
@@ -53,7 +53,7 @@ def test_slider_with_boolean_labels_builder(gui: Gui, helpers):
     sel = "Item 1"  # noqa: F841
     gui._set_frame(inspect.currentframe())
     with tgb.Page(frame=None) as page:
-        tgb.slider(value="{sel}", lov="Item 1;Item 2;Item 3", labels=True)
+        tgb.slider(value="{sel}", lov="Item 1;Item 2;Item 3", labels=True)  # type: ignore[attr-defined]
     expected_list = ["<Slider", "labels={true}"]
     helpers.test_control_builder(gui, page, expected_list)
 
@@ -61,7 +61,7 @@ def test_slider_with_boolean_labels_builder(gui: Gui, helpers):
 def test_slider_items_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("x", "Item 1")
     with tgb.Page(frame=None) as page:
-        tgb.slider(value="{x}", lov="Item 1;Item 2;Item 3", text_anchor="left")
+        tgb.slider(value="{x}", lov="Item 1;Item 2;Item 3", text_anchor="left")  # type: ignore[attr-defined]
     expected_list = [
         "<Slider",
         'updateVarName="_TpLv_tpec_TpExPr_x_TPMDL_0"',
@@ -76,7 +76,7 @@ def test_slider_items_builder(gui: Gui, test_client, helpers):
 def test_slider_text_anchor_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("x", "Item 1")
     with tgb.Page(frame=None) as page:
-        tgb.slider(value="{x}", text_anchor=None)
+        tgb.slider(value="{x}", text_anchor=None)  # type: ignore[attr-defined]
     expected_list = [
         "<Slider",
         'updateVarName="_TpN_tpec_TpExPr_x_TPMDL_0"',
@@ -89,7 +89,7 @@ def test_slider_text_anchor_builder(gui: Gui, test_client, helpers):
 def test_slider_text_anchor_default_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("x", "Item 1")
     with tgb.Page(frame=None) as page:
-        tgb.slider(value="{x}", items="Item 1")
+        tgb.slider(value="{x}", items="Item 1")  # type: ignore[attr-defined]
     expected_list = [
         "<Slider",
         'updateVarName="_TpN_tpec_TpExPr_x_TPMDL_0"',

+ 1 - 1
tests/gui/builder/control/test_status.py

@@ -18,7 +18,7 @@ from taipy.gui import Gui
 def test_status_builder(gui: Gui, helpers):
     status = [{"status": "info", "message": "Info Message"}]  # noqa: F841
     with tgb.Page(frame=None) as page:
-        tgb.status(value="{status}")
+        tgb.status(value="{status}")  # type: ignore[attr-defined]
     expected_list = [
         "<Status",
         'defaultValue="[&#x7B;&quot;status&quot;: &quot;info&quot;, &quot;message&quot;: &quot;Info Message&quot;&#x7D;]"',  # noqa: E501

+ 3 - 3
tests/gui/builder/control/test_table.py

@@ -17,7 +17,7 @@ from taipy.gui import Gui
 
 def test_table_builder_1(gui: Gui, helpers, csvdata):
     with tgb.Page(frame=None) as page:
-        tgb.table(
+        tgb.table(  # type: ignore[attr-defined]
             data="{csvdata}",
             page_size=10,
             page_size_options=[10, 30, 100],
@@ -41,7 +41,7 @@ def test_table_builder_1(gui: Gui, helpers, csvdata):
 
 def test_table_reset_builder(gui: Gui, helpers, csvdata):
     with tgb.Page(frame=None) as page:
-        tgb.table(
+        tgb.table(  # type: ignore[attr-defined]
             data="{csvdata}",
             rebuild=True,
             page_size=10,
@@ -82,7 +82,7 @@ def test_table_builder_2(gui: Gui, helpers, csvdata):
         "height": "60vh",
     }
     with tgb.Page(frame=None) as page:
-        tgb.table(data="{csvdata}", properties="table_properties", auto_loading=True, editable=False)
+        tgb.table(data="{csvdata}", properties="table_properties", auto_loading=True, editable=False)  # type: ignore[attr-defined]
     expected_list = [
         "<Table",
         "allowAllRows={true}",

+ 2 - 2
tests/gui/builder/control/test_text.py

@@ -16,7 +16,7 @@ from taipy.gui import Gui
 def test_text_builder_1(gui: Gui, test_client, helpers):
     gui._bind_var_val("x", 10)
     with tgb.Page(frame=None) as page:
-        tgb.text(value="{x}")
+        tgb.text(value="{x}")  # type: ignore[attr-defined]
     expected_list = ["<Field", 'dataType="int"', 'defaultValue="10"', "value={tpec_TpExPr_x_TPMDL_0}"]
     helpers.test_control_builder(gui, page, expected_list)
 
@@ -24,6 +24,6 @@ def test_text_builder_1(gui: Gui, test_client, helpers):
 def test_text_builder_2(gui: Gui, test_client, helpers):
     gui._bind_var_val("x", 10)
     with tgb.Page(frame=None) as page:
-        tgb.text("{x}")
+        tgb.text("{x}")  # type: ignore[attr-defined]
     expected_list = ["<Field", 'dataType="int"', 'defaultValue="10"', "value={tpec_TpExPr_x_TPMDL_0}"]
     helpers.test_control_builder(gui, page, expected_list)

+ 3 - 3
tests/gui/builder/control/test_toggle.py

@@ -15,14 +15,14 @@ from taipy.gui import Gui
 
 def test_toggle_builder(gui: Gui, helpers):
     with tgb.Page(frame=None) as page:
-        tgb.toggle(theme=True)
+        tgb.toggle(theme=True)  # type: ignore[attr-defined]
     expected_list = ["<Toggle", 'kind="theme"', 'unselectedValue=""']
     helpers.test_control_builder(gui, page, expected_list)
 
 
 def test_toggle_allow_unselected_builder(gui: Gui, helpers):
     with tgb.Page(frame=None) as page:
-        tgb.toggle(allow_unselect=True, lov="1;2")
+        tgb.toggle(allow_unselect=True, lov="1;2")  # type: ignore[attr-defined]
     expected_list = ["<Toggle", 'unselectedValue=""', "allowUnselect={true}"]
     helpers.test_control_builder(gui, page, expected_list)
 
@@ -31,7 +31,7 @@ def test_toggle_lov_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("x", "l1")
     gui._bind_var_val("lov", [("l1", "v1"), ("l2", "v2")])
     with tgb.Page(frame=None) as page:
-        tgb.toggle(lov="{lov}", value="{x}", label="Label")
+        tgb.toggle(lov="{lov}", value="{x}", label="Label")  # type: ignore[attr-defined]
     expected_list = [
         "<Toggle",
         'defaultLov="[[&quot;l1&quot;, &quot;v1&quot;], [&quot;l2&quot;, &quot;v2&quot;]]"',

+ 3 - 3
tests/gui/builder/control/test_tree.py

@@ -16,7 +16,7 @@ from taipy.gui import Gui
 def test_tree_builder(gui: Gui, test_client, helpers):
     gui._bind_var_val("value", "Item 1")
     with tgb.Page(frame=None) as page:
-        tgb.tree(value="{value}", lov="Item 1;Item 2;Item 3")
+        tgb.tree(value="{value}", lov="Item 1;Item 2;Item 3")  # type: ignore[attr-defined]
     expected_list = [
         "<TreeView",
         'defaultLov="[&quot;Item 1&quot;, &quot;Item 2&quot;, &quot;Item 3&quot;]"',
@@ -30,7 +30,7 @@ def test_tree_builder(gui: Gui, test_client, helpers):
 def test_tree_expanded_builder_1(gui: Gui, test_client, helpers):
     gui._bind_var_val("value", "Item 1")
     with tgb.Page(frame=None) as page:
-        tgb.tree(value="{value}", lov="Item 1;Item 2;Item 3", expanded=False)
+        tgb.tree(value="{value}", lov="Item 1;Item 2;Item 3", expanded=False)  # type: ignore[attr-defined]
     expected_list = [
         "<TreeView",
         'defaultLov="[&quot;Item 1&quot;, &quot;Item 2&quot;, &quot;Item 3&quot;]"',
@@ -46,7 +46,7 @@ def test_tree_expanded_builder_2(gui: Gui, test_client, helpers):
     gui._bind_var_val("value", "Item 1")
     gui._bind_var_val("expa", ["Item1"])
     with tgb.Page(frame=None) as page:
-        tgb.tree(value="{value}", lov="Item 1;Item 2;Item 3", expanded="{expa}")
+        tgb.tree(value="{value}", lov="Item 1;Item 2;Item 3", expanded="{expa}")  # type: ignore[attr-defined]
     expected_list = [
         "<TreeView",
         'defaultLov="[&quot;Item 1&quot;, &quot;Item 2&quot;, &quot;Item 3&quot;]"',

+ 4 - 0
tests/gui/gui_specific/test_gui.py

@@ -67,6 +67,8 @@ def test__tbl_cols(gui: Gui):
         gui.run(run_server=False)
     with gui.get_flask_app().app_context():
         res = gui._tbl_cols(True, None, json.dumps({}), json.dumps({"data": "data"}), data=data)
+        assert isinstance(res, str)
+
         d = json.loads(res)
         assert isinstance(d, dict)
         assert d["col1"]["type"] == "int"
@@ -81,6 +83,8 @@ def test__chart_conf(gui: Gui):
         gui.run(run_server=False)
     with gui.get_flask_app().app_context():
         res = gui._chart_conf(True, None, json.dumps({}), json.dumps({"data": "data"}), data=data)
+        assert isinstance(res, str)
+
         d = json.loads(res)
         assert isinstance(d, dict)
         assert d["columns"]["col1"]["type"] == "int"

+ 3 - 3
tests/gui/gui_specific/test_shared.py

@@ -14,8 +14,8 @@ from taipy.gui import Gui
 
 def test_add_shared_variables(gui: Gui):
     Gui.add_shared_variable("var1", "var2")
-    assert isinstance(gui._Gui__shared_variables, list)
-    assert len(gui._Gui__shared_variables) == 2
+    assert isinstance(gui._Gui__shared_variables, list)  # type: ignore[attr-defined]
+    assert len(gui._Gui__shared_variables) == 2  # type: ignore[attr-defined]
 
     Gui.add_shared_variables("var1", "var2")
-    assert len(gui._Gui__shared_variables) == 2
+    assert len(gui._Gui__shared_variables) == 2  # type: ignore[attr-defined]

+ 1 - 1
tests/gui/gui_specific/test_state.py

@@ -25,7 +25,7 @@ def test_state(gui: Gui):
     gui.add_page("page1", md_page1)
     with patch("sys.argv", ["prog"]):
         gui.run(run_server=False, single_client=True)
-    state = gui._Gui__state
+    state = gui._Gui__state  # type: ignore[attr-defined]
     with gui.get_flask_app().app_context():
         assert state.a == 10
         assert state["page1"].a == 20

+ 2 - 2
tests/gui/long_runnig/test_long_running.py

@@ -35,12 +35,12 @@ def test_long_callback(gui: Gui):
     gui._set_frame(inspect.currentframe())
     with patch("sys.argv", ["prog"]):
         gui.run(run_server=False, single_client=True)
-    state = gui._Gui__state
+    state = gui._Gui__state  # type: ignore[attr-defined]
 
     with gui.get_flask_app().app_context():
         assert state.status is None
         invoke_long_callback(state, heavy_function)
         invoke_long_callback(state, heavy_function_with_exception)
         invoke_long_callback(state, heavy_function, (), heavy_function_status)
-        invoke_long_callback(state, heavy_function, (2), heavy_function_status, (), 1000)
+        invoke_long_callback(state, heavy_function, (2,), heavy_function_status, (), 1000)
         invoke_long_callback(state, heavy_function_with_exception, (), heavy_function_status)

+ 12 - 11
tests/gui/server/http/test_status.py

@@ -38,14 +38,14 @@ def test_get_extended_status(gui: Gui):
     assert ret.status_code == 200, f"status_code => {ret.status_code} != 200"
     assert ret.mimetype == "application/json", f"mimetype => {ret.mimetype} != application/json"
     assert ret.json, "json is not defined"
-    gui = ret.json.get("gui")
-    assert "backend_version" in gui, "json.gui has no key backend_version"
-    assert "flask_version" in gui, "json.gui has no key flask_version"
-    assert "frontend_version" in gui, "json.gui has no key frontend_version"
-    assert "host" in gui, "json.gui has no key host"
-    assert "python_version" in gui, "json.gui has no key python_version"
-    assert "user_status" in gui, "json.gui has no key user_status"
-    assert gui.get("user_status") == "", "json.gui.user_status is not empty"
+    gui_ret = ret.json.get("gui")
+    assert "backend_version" in gui_ret, "json.gui has no key backend_version"
+    assert "flask_version" in gui_ret, "json.gui has no key flask_version"
+    assert "frontend_version" in gui_ret, "json.gui has no key frontend_version"
+    assert "host" in gui_ret, "json.gui has no key host"
+    assert "python_version" in gui_ret, "json.gui has no key python_version"
+    assert "user_status" in gui_ret, "json.gui has no key user_status"
+    assert gui_ret.get("user_status") == "", "json.gui.user_status is not empty"
 
 
 def test_get_status_with_user_status(gui: Gui):
@@ -62,6 +62,7 @@ def test_get_status_with_user_status(gui: Gui):
     ret = flask_client.get("/taipy.status.json")
     assert ret.status_code == 200, f"status_code => {ret.status_code} != 200"
     assert ret.json, "json is not defined"
-    gui = ret.json.get("gui")
-    assert "user_status" in gui, "json.gui has no key user_status"
-    assert gui.get("user_status") == user_status, f'json.gui.user_status => {gui.get("user_status")} != {user_status}'
+    gui_ret = ret.json.get("gui")
+    assert "user_status" in gui_ret, "json.gui has no key user_status"
+    assert gui_ret.get("user_status") == user_status
+    assert f'json.gui.user_status => {gui_ret.get("user_status")} != {user_status}'

+ 6 - 6
tests/gui/utils/test_map_dict.py

@@ -115,12 +115,12 @@ def test_map_dict_set(gui: Gui, test_client):
     with patch("sys.argv", ["prog"]):
         gui.run(run_server=False, single_client=True)
     with gui.get_flask_app().app_context():
-        assert isinstance(gui._Gui__state.d, _MapDict)
-        gui._Gui__state.d = {"b": 2}
-        assert isinstance(gui._Gui__state.d, _MapDict)
-        assert len(gui._Gui__state.d) == 1
-        assert gui._Gui__state.d.get("a", None) is None
-        assert gui._Gui__state.d.get("b", None) == 2
+        assert isinstance(gui._Gui__state.d, _MapDict)  # type: ignore[attr-defined]
+        gui._Gui__state.d = {"b": 2}  # type: ignore[attr-defined]
+        assert isinstance(gui._Gui__state.d, _MapDict)  # type: ignore[attr-defined]
+        assert len(gui._Gui__state.d) == 1  # type: ignore[attr-defined]
+        assert gui._Gui__state.d.get("a", None) is None  # type: ignore[attr-defined]
+        assert gui._Gui__state.d.get("b", None) == 2  # type: ignore[attr-defined]
 
 
 def test_map_dict_items():

+ 4 - 4
tests/gui_core/test_context_is_deletable.py

@@ -12,14 +12,14 @@
 from unittest.mock import Mock, patch
 
 from taipy.config.common.scope import Scope
-from taipy.core import Job, Scenario, Task
+from taipy.core import Job, JobId, Scenario, Task
 from taipy.core.data.pickle import PickleDataNode
 from taipy.gui_core._context import _GuiCoreContext
 
-a_scenario = Scenario("scenario_config_id", [], {}, sequences={"sequence": {}})
+a_scenario = Scenario("scenario_config_id", None, {}, sequences={"sequence": {}})
 a_task = Task("task_config_id", {}, print)
-a_job = Job("JOB_job_id", a_task, "submit_id", a_scenario.id)
-a_job.isfinished = lambda s: True
+a_job = Job(JobId("JOB_job_id"), a_task, "submit_id", a_scenario.id)
+a_job.isfinished = lambda s: True  # type: ignore[attr-defined]
 a_datanode = PickleDataNode("data_node_config_id", Scope.SCENARIO)
 
 

+ 4 - 4
tests/gui_core/test_context_is_editable.py

@@ -12,15 +12,15 @@
 from unittest.mock import Mock, patch
 
 from taipy.config.common.scope import Scope
-from taipy.core import Job, Scenario, Task
+from taipy.core import Job, JobId, Scenario, Task
 from taipy.core.data.pickle import PickleDataNode
 from taipy.gui import Gui
 from taipy.gui_core._context import _GuiCoreContext
 
-a_scenario = Scenario("scenario_config_id", [], {}, sequences={"sequence": {}})
+a_scenario = Scenario("scenario_config_id", None, {}, sequences={"sequence": {}})
 a_task = Task("task_config_id", {}, print)
-a_job = Job("JOB_job_id", a_task, "submit_id", a_scenario.id)
-a_job.isfinished = lambda s: True
+a_job = Job(JobId("JOB_job_id"), a_task, "submit_id", a_scenario.id)
+a_job.isfinished = lambda s: True  # type: ignore[attr-defined]
 a_datanode = PickleDataNode("data_node_config_id", Scope.SCENARIO)
 
 

+ 4 - 4
tests/gui_core/test_context_is_promotable.py

@@ -12,14 +12,14 @@
 from unittest.mock import Mock, patch
 
 from taipy.config.common.scope import Scope
-from taipy.core import Job, Scenario, Task
+from taipy.core import Job, JobId, Scenario, Task
 from taipy.core.data.pickle import PickleDataNode
 from taipy.gui_core._context import _GuiCoreContext
 
-a_scenario = Scenario("scenario_config_id", [], {}, sequences={"sequence": {}})
+a_scenario = Scenario("scenario_config_id", None, {}, sequences={"sequence": {}})
 a_task = Task("task_config_id", {}, print)
-a_job = Job("JOB_job_id", a_task, "submit_id", a_scenario.id)
-a_job.isfinished = lambda s: True
+a_job = Job(JobId("JOB_job_id"), a_task, "submit_id", a_scenario.id)
+a_job.isfinished = lambda s: True  # type: ignore[attr-defined]
 a_datanode = PickleDataNode("data_node_config_id", Scope.SCENARIO)
 
 

+ 2 - 2
tests/gui_core/test_context_is_readable.py

@@ -19,10 +19,10 @@ from taipy.core.submission.submission import Submission
 from taipy.gui import Gui
 from taipy.gui_core._context import _GuiCoreContext, _SubmissionDetails
 
-a_scenario = Scenario("scenario_config_id", [], {}, sequences={"sequence": {}})
+a_scenario = Scenario("scenario_config_id", None, {}, sequences={"sequence": {}})
 a_task = Task("task_config_id", {}, print)
 a_job = Job(t.cast(JobId, "JOB_job_id"), a_task, "submit_id", a_scenario.id)
-a_job.isfinished = lambda s: True
+a_job.isfinished = lambda s: True  # type: ignore[attr-defined]
 a_datanode = PickleDataNode("data_node_config_id", Scope.SCENARIO)
 a_submission = Submission(a_scenario.id, "Scenario", a_scenario.config_id)
 

+ 4 - 4
tests/gui_core/test_context_is_submitable.py

@@ -12,14 +12,14 @@
 from unittest.mock import Mock, patch
 
 from taipy.config.common.scope import Scope
-from taipy.core import Job, Scenario, Task
+from taipy.core import Job, JobId, Scenario, Task
 from taipy.core.data.pickle import PickleDataNode
 from taipy.gui_core._context import _GuiCoreContext
 
-a_scenario = Scenario("scenario_config_id", [], {}, sequences={"sequence": {}})
+a_scenario = Scenario("scenario_config_id", None, {}, sequences={"sequence": {}})
 a_task = Task("task_config_id", {}, print)
-a_job = Job("JOB_job_id", a_task, "submit_id", a_scenario.id)
-a_job.isfinished = lambda s: True
+a_job = Job(JobId("JOB_job_id"), a_task, "submit_id", a_scenario.id)
+a_job.isfinished = lambda s: True  # type: ignore[attr-defined]
 a_datanode = PickleDataNode("data_node_config_id", Scope.SCENARIO)
 
 

+ 1 - 1
tests/rest/setup/shared/config.py

@@ -9,7 +9,7 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 
-from taipy.core import Config, Frequency
+from taipy.config import Config, Frequency
 
 from .algorithms import evaluate, forecast