diff --git a/azure-functions-durable/CHANGELOG.md b/azure-functions-durable/CHANGELOG.md index e9c022e..fea8d4d 100644 --- a/azure-functions-durable/CHANGELOG.md +++ b/azure-functions-durable/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ADDED +- Added PEP 561 type information so strict type checkers recognize +`azure.durable_functions` as a typed package. - Added `azure.durable_functions.testing.execute_entity()` for unit testing function-style and class-based entities without a Functions host or Durable Task backend. The helper returns the operation result, resulting state, and typed diff --git a/azure-functions-durable/azure/durable_functions/py.typed b/azure-functions-durable/azure/durable_functions/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/azure-functions-durable/pyproject.toml b/azure-functions-durable/pyproject.toml index fb675b4..62698a0 100644 --- a/azure-functions-durable/pyproject.toml +++ b/azure-functions-durable/pyproject.toml @@ -39,5 +39,8 @@ changelog = "https://github.com/microsoft/durabletask-python/blob/main/azure-fun [tool.setuptools.packages.find] include = ["azure.durable_functions", "azure.durable_functions.*"] +[tool.setuptools.package-data] +"azure.durable_functions" = ["py.typed"] + [tool.pytest.ini_options] minversion = "6.0" diff --git a/noxfile.py b/noxfile.py index 075c71c..29ce7de 100644 --- a/noxfile.py +++ b/noxfile.py @@ -27,8 +27,10 @@ import shutil import socket import subprocess +import tarfile import time import uuid +import zipfile from pathlib import Path from typing import Sequence @@ -311,16 +313,65 @@ def typecheck_core(session: nox.Session) -> None: @nox.session(python=["3.13"]) def typecheck_functions(session: nox.Session) -> None: - """Run strict pyright checks for azure-functions-durable.""" + """Run strict pyright checks for azure-functions-durable and its wheel.""" session.install("-r", "requirements.txt") - _install_packages(session, editable=True) - session.install("pyright") + session.install("-e", str(REPO_ROOT)) + session.install("build", "pyright") + artifact_dir = Path(session.create_tmp()) / "dist" + if artifact_dir.exists(): + shutil.rmtree(artifact_dir) + session.run( + "python", + "-m", + "build", + "--outdir", + str(artifact_dir), + str(AZURE_FUNCTIONS_DURABLE), + ) + + wheels = list(artifact_dir.glob("azure_functions_durable-*.whl")) + sdists = list(artifact_dir.glob("azure_functions_durable-*.tar.gz")) + if len(wheels) != 1 or len(sdists) != 1: + session.error("Expected exactly one wheel and one source distribution") + wheel = wheels[0] + sdist = sdists[0] + marker = "azure/durable_functions/py.typed" + with zipfile.ZipFile(wheel) as archive: + if marker not in archive.namelist(): + session.error(f"{marker} is missing from {wheel.name}") + with tarfile.open(sdist, "r:gz") as archive: + if not any(name.endswith(f"/{marker}") for name in archive.getnames()): + session.error(f"{marker} is missing from {sdist.name}") + + session.install(str(wheel)) + session.run( + "python", + "-m", + "pip", + "install", + "--force-reinstall", + "--no-deps", + str(wheel), + ) session.run( "pyright", "-p", "azure-functions-durable/pyrightconfig.json", *session.posargs, ) + python_path = session.run( + "python", + "-c", + "import sys; print(sys.executable)", + silent=True, + ).strip() + session.run( + "pyright", + "--pythonpath", + python_path, + "-p", + "tests/azure-functions-durable/typing/pyrightconfig.json", + ) @nox.session(python=PYTHON_VERSIONS) diff --git a/tests/azure-functions-durable/typing/import_package.py b/tests/azure-functions-durable/typing/import_package.py new file mode 100644 index 0000000..3beb135 --- /dev/null +++ b/tests/azure-functions-durable/typing/import_package.py @@ -0,0 +1,8 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import azure.durable_functions as df + + +def create_app() -> df.DFApp: + return df.DFApp() diff --git a/tests/azure-functions-durable/typing/pyrightconfig.json b/tests/azure-functions-durable/typing/pyrightconfig.json new file mode 100644 index 0000000..68700dd --- /dev/null +++ b/tests/azure-functions-durable/typing/pyrightconfig.json @@ -0,0 +1,7 @@ +{ + "include": [ + "import_package.py" + ], + "pythonVersion": "3.13", + "typeCheckingMode": "strict" +}