Skip to content

[FEAT] add PEP 561 py.typed marker so type checkers honour inline annotations - #1149

Closed
jbbqqf wants to merge 2 commits into
Nixtla:mainfrom
jbbqqf:feat/1121-py-typed-marker
Closed

[FEAT] add PEP 561 py.typed marker so type checkers honour inline annotations#1149
jbbqqf wants to merge 2 commits into
Nixtla:mainfrom
jbbqqf:feat/1121-py-typed-marker

Conversation

@jbbqqf

@jbbqqf jbbqqf commented May 9, 2026

Copy link
Copy Markdown

Summary

Add an empty python/statsforecast/py.typed marker so PEP 561-aware type checkers (pyright/pylance/mypy) honour the inline annotations already present in the codebase.

Fixes #1121feat: Consider adding py.typed file marker for type-checking support

Context

PEP 561 (spec) defines two mechanisms for shipping type information:

  • a stub-only package, or
  • inline annotations advertised by an empty py.typed marker file at the package root.

statsforecast already has inline annotations across python/statsforecast/*.py, but the marker is missing. Without it, pyright/pylance treat the package as untyped — the user reported pylance emitting Stub file not found for "statsforecast" whenever the package is imported.

The marker has to ride along into the built wheel. Two pieces are already in place:

  • MANIFEST.in includes recursive-include python/statsforecast *, which picks up py.typed for the sdist.
  • pyproject.toml's [tool.setuptools.package-data] "*" = ["**/*"] forwards every file under the package directory into the wheel.

So adding the marker file is sufficient — no other build configuration change is needed. The new regression test imports statsforecast and asserts the marker is co-located with statsforecast.__file__ (i.e. the file made it through the install path).

Changes

  • python/statsforecast/py.typed — new empty file (PEP 561 marker).
  • tests/test_utils.py — new test_py_typed_marker_is_packaged regression. It mirrors the path a real consumer would inspect: import the package, then assert py.typed sits next to statsforecast.__file__.

Reproduce BEFORE/AFTER yourself (copy-paste)

git clone https://github.com/Nixtla/statsforecast.git /tmp/sf-1121 && cd /tmp/sf-1121
git submodule update --init --recursive
python -m venv .venv && source .venv/bin/activate
pip install --no-build-isolation -e . pytest

REPRO='
import os, statsforecast
pkg_dir = os.path.dirname(statsforecast.__file__)
marker = os.path.join(pkg_dir, "py.typed")
assert os.path.isfile(marker), f"py.typed missing at {marker}"
print("OK", marker)
'

# --- BEFORE (origin/main) ---
git checkout origin/main
python -c "$REPRO"
# Expected: AssertionError: py.typed missing at .../site-packages/statsforecast/py.typed

# --- AFTER (this PR) ---
git fetch https://github.com/jbbqqf/statsforecast.git feat/1121-py-typed-marker
git checkout FETCH_HEAD
python -c "$REPRO"
# Expected: prints "OK .../python/statsforecast/py.typed"

For an end-to-end pyright check (the user's actual scenario):

pip install pyright
echo "import statsforecast" > /tmp/probe.py
pyright /tmp/probe.py

On origin/main, pyright reports error: Stub file not found for "statsforecast". On this branch it reports zero diagnostics for the import line.

What I ran locally

  • pytest tests/test_utils.py -v --no-cov2/2 passed (was 1; the new test_py_typed_marker_is_packaged fails on origin/main and passes here).

Edge cases tested

# Scenario Input Expected Verified by
1 Editable install (the dev path) pip install -e . py.typed sits next to statsforecast.__file__ test_py_typed_marker_is_packaged
2 sdist recursive-include python/statsforecast * already covers it py.typed ships in source tarball manual python -m build --sdist inspection (no test added — covered by MANIFEST.in convention)
3 wheel [tool.setuptools.package-data] "*" = ["**/*"] already forwards it py.typed ships in the wheel covered by the editable-install test (same package-data resolution)

Risk / blast radius

Pure addition. Type checkers that previously ignored statsforecast will now read its annotations; that may surface new diagnostics in downstream projects, but the annotations are already present in the source and have already been informally guiding hover-docs and IDE completions. No runtime behaviour change.

Release note

feat: ship a PEP 561 `py.typed` marker so pyright/pylance/mypy honour `statsforecast`'s inline type annotations.

PR drafted with assistance from Claude Code. The change matches the standard PEP 561 recipe and the existing MANIFEST.in / package-data configuration carries the marker into both sdist and wheel without further changes.

…nnotations

PEP 561 requires a `py.typed` marker file at the package root for
type checkers (pyright/mypy/pylance) to pick up the inline type
annotations a package ships. Without it, pylance emits
"Stub file not found for 'statsforecast'" and skips type checking.

The package already has type annotations across `python/statsforecast`,
so the marker is the only missing piece. `MANIFEST.in` already covers
the file via `recursive-include python/statsforecast *`, and
`pyproject.toml`'s `[tool.setuptools.package-data] "*" = ["**/*"]`
forwards it into the wheel — both verified by importing the editable
install and locating the file next to `statsforecast.__file__`.

Fixes Nixtla#1121.
@CLAassistant

CLAassistant commented May 9, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ nasaul
❌ jbbqqf
You have signed the CLA already but the status is still pending? Let us recheck it.

@nasaul

nasaul commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Hey @jbbqqf thanks for your contribution! Can you please sign the license?

@codspeed-hq

codspeed-hq Bot commented Jul 2, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 38 untouched benchmarks


Comparing jbbqqf:feat/1121-py-typed-marker (421901d) with main (fe9c3f8)

Open in CodSpeed

@MMenchero

Copy link
Copy Markdown
Contributor

Thanks for your contribution, @jbbqqf. We're preparing a new StatsForecast release and need to move quickly on this fix. Since the license agreement hasn't been signed yet, we'll merge #1176 instead, which addresses the same issue. It was opened after yours, but it keeps the change minimal (there's really no need for a test). We encourage you to sign the license agreement in your other PR #1148, as that's something we would like to merge.

@MMenchero MMenchero closed this Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Consider adding py.typed file marker for type-checking support

4 participants