The Role of py.typed Marker Files in Python

The py.typed marker file is a packaging standard introduced in PEP 561 that explicitly signals to static type checkers that a library supports inline type hints. Without this marker, static analysis tools such as Mypy, Pyright, and IDE type inspection engines treat installed third-party packages as untyped by default, ignoring any existing type annotations. This article explains why the py.typed file exists, how type checkers interact with it, and how to properly include it in modern Python package distributions.

The Problem py.typed Solves

Before PEP 561 was adopted, type checkers could not reliably determine whether a package's inline type hints were complete, maintained, and intended for public use, or merely experimental and partial. Analyzing incomplete type hints often produced false-positive errors for end users.

To prevent this, static type checkers adopted a conservative default behavior: any imported third-party library without an explicit signal is treated as untyped, falling back to Any types or raising "missing type stubs" warnings. The py.typed marker file provides an explicit, opt-in contract between package authors and consumer tooling.

How the Marker Works

A py.typed file is typically an empty file placed directly inside a Python package's directory alongside its __init__.py file.

When an end-user runs a type checker on code that imports your package, the tool performs the following checks:

  1. Locates the Package: The type checker finds the installed package in the Python environment.
  2. Checks for py.typed: It looks for a file named py.typed at the root of the package.
  3. Parses Annotations: If the file is present, the type checker parses the inline type hints within the package’s .py files (or any bundled .pyi stub files) and verifies the user's code against them.
  4. Fallback Behavior: If the file is missing, the type checker ignores the package's internal annotations and looks for external stubs (such as typeshed) or treats the package imports as dynamic.

How to Include py.typed in a Distribution

Creating the file is not enough; the build backend must also be instructed to include the file in the built wheel and source distribution (sdist).

1. Create the File

Inside your package directory, create an empty file named py.typed:

my_package/
├── my_package/
│   ├── __init__.py
│   ├── core.py
│   └── py.typed
├── pyproject.toml
└── README.md

2. Configure Your Build System

Ensure your packaging configuration treats py.typed as package data:

Rules for Subpackages and Namespace Packages

Verification

To verify that your package is correctly configured:

  1. Build your distribution wheel using a tool like build (python -m build).
  2. Inspect the contents of the generated .whl file (which is a standard zip archive) and confirm that my_package/py.typed is present.
  3. Install the wheel into a clean virtual environment and run mypy or pyright against consumer code that imports the package to ensure types are resolved without warnings.