Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions azure-functions-durable/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Empty file.
3 changes: 3 additions & 0 deletions azure-functions-durable/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
57 changes: 54 additions & 3 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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))

@berndverst berndverst Jul 29, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Make the consumer check resolve packaged core types

Pyright does not follow this PEP 660 editable install for the consumer config: pyright --verbose reports Could not import 'durabletask.task', while the new DFApp() probe still passes. A strict probe that also uses the public df.RetryPolicy and DurableOrchestrationContext.call_activity() then produces five reportUnknown* errors; installing the already-typed core wheel makes them disappear. This leaves the packaging smoke test blind to regressions in the provider's core-backed public types. Install/build the core wheel for the consumer phase (forcing it fresh under nox -R) and exercise at least one core-backed export.

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)
Expand Down
8 changes: 8 additions & 0 deletions tests/azure-functions-durable/typing/import_package.py
Original file line number Diff line number Diff line change
@@ -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()
7 changes: 7 additions & 0 deletions tests/azure-functions-durable/typing/pyrightconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"include": [
"import_package.py"
],
"pythonVersion": "3.13",
"typeCheckingMode": "strict"
}
Loading