Add py.typed marker for PEP 561 type checker support#95
Add py.typed marker for PEP 561 type checker support#95benaduo wants to merge 2 commits intoinertiajs:mainfrom
Conversation
Previously, even though type hints were added across the entire codebase (see 97227b2), external type checkers like mypy still couldn't see them. This is because Python requires a special marker file called `py.typed` to be present in the package root for type checkers to recognize inline type annotations — this is defined in PEP 561. Without this marker, users importing `render`, `InertiaResponse`, or any other typed export from inertia-django would see everything as `Any`, which defeats the purpose of having type hints at all. Changes: - Add empty inertia/py.typed marker file - Update pyproject.toml to include py.typed in package distribution - Add test to verify py.typed marker exists in the package Fixes Issue inertiajs#94 Author: Benjamin Aduo (@benaduo)
There was a problem hiding this comment.
Pull request overview
This PR adds PEP 561 compliance to enable external type checkers like mypy to recognize the package's inline type annotations. The codebase already has comprehensive type hints (added in commit 97227b2), but without the py.typed marker file, external tools treat all exports as Any type.
Changes:
- Added empty
py.typedmarker file in theinertia/package directory for PEP 561 compliance - Updated
pyproject.tomlto include the marker file in package distributions - Added a test to verify the marker file exists and prevent accidental removal
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| inertia/py.typed | Empty PEP 561 marker file that signals to type checkers that the package supports inline type hints |
| pyproject.toml | Added Poetry configuration to include py.typed in package distributions |
| inertia/tests/test_typing.py | New test case to verify the py.typed marker file exists in the package directory |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [tool.poetry.include] | ||
| include = ["inertia/py.typed"] |
There was a problem hiding this comment.
The [tool.poetry.include] section syntax is incorrect. The include key should be placed directly under the [tool.poetry] section, not in a separate section. The current configuration will not work as intended and the py.typed file will not be included in the package distribution.
The correct configuration should be:
[tool.poetry]
packages = [
{ include = "inertia" },
]
include = ["inertia/py.typed"]Move the include line to be directly under [tool.poetry] and remove the [tool.poetry.include] header.
There was a problem hiding this comment.
This seems to be correct, after doing more research, I’ve removed the [tool.poetry.include] section entirely. Poetry already includes files that live inside the declared package directory, and py.typed lives inside inertia/, which is already configured as a package, so it gets packaged automatically. The fix has been pushed.
There was a problem hiding this comment.
Does it include the py.typed file though? I think by default it only includes python files in the specified directory.
There was a problem hiding this comment.
Hey @sopelj, good question, I looked into this carefully.
Poetry includes all files in the package source tree by default, not just .py files. Since py.typed lives inside inertia/ which is already declared as a package, it ships in both the sdist and wheel automatically with no extra configuration needed.
This is confirmed by Jürgen Gmach (a well-known Python packaging contributor):
"Poetry actually includes everything that's part of the package source tree in your distribution, so py.typed is included out-of-the-box, no configuration needed."
Reference: https://jugmac00.github.io/blog/bite-my-shiny-type-annotated-library/
The confusion often comes from older Poetry issues (pre-1.0) where setup.py-based builds had this problem, but those are long resolved with the current poetry-core build backend.
If you have anything that contradicts this, I'm genuinely curious drop it in the next comment. I've gone through quite a bit of documentation on this and this is consistently what I find.
WORTH NOTING: This is also why I corrected my earlier commit to remove the [tool.poetry.include] section, py.typed comes packaged automatically, so the explicit include was unnecessary. That was the Copilot comment I addressed. If that's what you were referring to, then yes, it's already handled and the old PR has been updated.
There was a problem hiding this comment.
Ok, thanks for the information. I have never used poetry personally. The other tools I've used only load Python files automatically. So thanks for the clarification. :)
|
thanks @benaduo ! is |
The [tool.poetry.include] section added in the previous commit was unnecessary. Poetry automatically includes all files inside a declared package directory, and since py.typed lives inside inertia/ which is already configured under packages, it ships with the distribution by default. The incorrect [tool.poetry.include] section syntax was also flagged in code review. Removing it entirely is the cleanest solution. Changes: - Remove [tool.poetry.include] section from pyproject.toml Author: Benjamin Aduo (@benaduo)
|
Hey @BrandonShar, thanks for the review! With regards to version controlling py.typed: Yes, it needs to be in the repo. PEP 561 requires that the py.typed marker file is included in the installed package; if it’s not tracked, it won’t end up in the wheel/sdist, and type checkers like mypy will keep treating the package as untyped even if there are inline annotations. From PEP 561: “Package maintainers who wish to support type checking of their code MUST add a marker file named py.typed to their package supporting typing. To have this file installed with the package, maintainers can use existing packaging options such as package_data in distutils, shown below.” https://peps.python.org/pep-0561/ The mypy docs describe the same pattern for installed packages: add py.typed and include it as package data so mypy knows to use the package’s own types. https://mypy.readthedocs.io/en/stable/installed_packages.html This is also what people do in practice when making a package PEP‑561 compliant: “The solution was to add one py.typed file to the root of the main package. This forces mypy to analyze the types.” With regards to the file being empty: That’s intentional. For normal inline‑typed packages, py.typed is just a marker; tools don’t care about its contents. PEP 561 only specifies contents for partial stub packages, where it must contain partial\n: “If a stub package distribution is partial it MUST include partial\n in a py.typed file.” https://peps.python.org/pep-0561/ Since this project already runs mypy in strict mode and has type hints across the modules, an empty py.typed marker at the package root is the expected setup. With regards to the Copilot comment: You were right here (or Copilot was). I’ve removed the [tool.poetry.include] section entirely. Poetry already includes files that live inside the declared package directory, and py.typed lives in inertia/, which is already configured as a package, so it gets packaged automatically. The fix has been pushed. |
Summary
py.typedmarker file to the package root for PEP 561 compliancepyproject.tomlto ensurepy.typedis included in thepackage distribution
removal
Motivation
Fixes Issue #94
Type hints were already added across the entire codebase in 97227b2,
but external type checkers like mypy still treat all exports as
Any.This happens because Python's PEP 561 requires a
py.typedmarkerfile to be present in the package root before type checkers will
recognize inline type annotations.
Without this marker, users importing
render,InertiaResponse, orany other typed export from inertia-django get no type checking
support — which defeats the purpose of having the hints in the first
place.
Changes
inertia/py.typed: Empty PEP 561 marker filepyproject.toml: Added[tool.poetry.include]to ship the markerwith the package
inertia/tests/test_typing.py: Test verifying the marker file existsTesting
Author
Benjamin Aduo (@benaduo)