Prechádzať zdrojové kódy

fix typing for taipy.run (#85)

* fix typing for taipy.run make typevar private, fix return type, fix doc formatting
* Slightly more readable doc
* Drop typing_extension for all Python<3.10
* tox as a dev package

---------
Authored-by: Dr-Irv
Co-authored-by: Fabien Lelaquais <86590727+FabienLelaquais@users.noreply.github.com>
Irv Lustig 2 rokov pred
rodič
commit
2c82477fe2
7 zmenil súbory, kde vykonal 62 pridanie a 11 odobranie
  1. 23 0
      .flake8
  2. 2 2
      .pre-commit-config.yaml
  3. 3 2
      Pipfile
  4. 2 0
      mypy.ini
  5. 4 0
      pyproject.toml
  6. 27 7
      src/taipy/_run.py
  7. 1 0
      tox.ini

+ 23 - 0
.flake8

@@ -0,0 +1,23 @@
+[flake8]
+# required by black, https://github.com/psf/black/blob/master/.flake8
+max-line-length = 120
+max-complexity = 18
+ignore = E203, E266, E501, E722, W503, F403, F401
+select = B,C,E,F,W,T4,B9
+docstring-convention = google
+per-file-ignores =
+    __init__.py:F401
+exclude =
+    .git,
+    __pycache__,
+    setup.py,
+    build,
+    dist,
+    releases,
+    .venv,
+    .tox,
+    .mypy_cache,
+    .pytest_cache,
+    .vscode,
+    .github,
+    tests

+ 2 - 2
.pre-commit-config.yaml

@@ -1,6 +1,6 @@
 repos:
 -   repo: https://github.com/pre-commit/mirrors-mypy
-    rev: 'v0.910'  # Use the sha / tag you want to point at
+    rev: 'v0.991'  # Use the sha / tag you want to point at
     hooks:
     -   id: mypy
         additional_dependencies: [
@@ -35,7 +35,7 @@ repos:
     - id: black
       args: [--line-length=120]
       language_version: python3
--   repo: https://gitlab.com/pycqa/flake8
+-   repo: https://github.com/pycqa/flake8
     rev: 3.9.2
     hooks:
     -   id: flake8

+ 3 - 2
Pipfile

@@ -4,11 +4,12 @@ verify_ssl = true
 name = "pypi"
 
 [packages]
-taipy-gui = {git = "https://git@github.com/Avaiga/taipy-gui.git@develop"}
-taipy-rest = {git = "https://git@github.com/Avaiga/taipy-rest.git@develop"}
+taipy-gui = {git="https://git@github.com/Avaiga/taipy-gui.git@develop"}
+taipy-rest = {git="https://git@github.com/Avaiga/taipy-rest.git@develop"}
 
 [dev-packages]
 pytest = "*"
+tox = "*"
 
 [requires]
 python_version = "3.8"

+ 2 - 0
mypy.ini

@@ -0,0 +1,2 @@
+[mypy]
+ignore_missing_imports = True

+ 4 - 0
pyproject.toml

@@ -0,0 +1,4 @@
+[tool.black]
+line-length = 120
+
+[tool.pyright]

+ 27 - 7
src/taipy/_run.py

@@ -9,25 +9,37 @@
 # 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.
 
+import sys
 import typing as t
 
+from flask import Flask
+
 from taipy.gui import Gui
 from taipy.rest import Rest
 from taipy.core import Core
 
+if sys.version_info >= (3, 10):
+    from typing import TypeGuard
+
+_AppType = t.Union[Gui, Rest, Core]
+_AppTypeT = t.TypeVar("_AppTypeT", Gui, Rest, Core)
+
 
-def _run(*apps: t.List[t.Union[Gui, Rest, Core]], **kwargs) -> t.Optional[t.Union[Gui, Rest, Core]]:
+def _run(*apps: t.List[_AppType], **kwargs) -> t.Optional[Flask]:
     """Run one or multiple Taipy services.
 
     A Taipy service is an instance of a class that runs code as a Web application.
 
     Parameters:
-        *args (List[Union[`Gui^`, `Rest^`, `Core^`]]): Services to run. If several services are provided, all the services run simultaneously. If this is empty or set to None, this method does nothing.
+        *args (Union[`Gui^`, `Rest^`, `Core^`]): Services to run, as separate arguments.<br/>
+            If several services are provided, all the services run simultaneously.<br/>
+            If this is empty or set to None, this method does nothing.
         **kwargs: Other parameters to provide to the services.
     """
-    gui = __typing_get(apps, Gui)
-    rest = __typing_get(apps, Rest)
-    core = __typing_get(apps, Core)
+
+    gui = __get_app(apps, Gui)
+    rest = __get_app(apps, Rest)
+    core = __get_app(apps, Core)
 
     if gui and core:
         from taipy.core._version._version_cli import _VersioningCLI
@@ -49,8 +61,16 @@ def _run(*apps: t.List[t.Union[Gui, Rest, Core]], **kwargs) -> t.Optional[t.Unio
         return gui.run(**kwargs)
     else:
         app = rest or gui
+        assert app is not None  # Avoid pyright typing error
         return app.run(**kwargs)
 
 
-def __typing_get(l, type_):
-    return next(filter(lambda o: isinstance(o, type_), l), None)
+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)

+ 1 - 0
tox.ini

@@ -14,4 +14,5 @@ deps = pipenv
 [testenv:tests]
 commands =
     pipenv install --dev --skip-lock
+    pipenv run pip freeze
     pytest tests