pytest-typing: Test Your Types
Ensure your types do what you think they do.
pytest-typing lets you test the type signatures of your code to ensure they really are what you expect. You write Markdown files with Python code blocks and expected type assertions; pytest-typing runs type checkers on these blocks and compares the actual and expected outputs.
First, install the plugin, making it discoverable by pytest:
$ pip install pytest-typing
$ # or
$ uv add pytest-typing --group dev
Then, configure pytest-typing with the type checker (or checkers) you want to use in pyproject.toml:
[tool.pytest]
typing_checkers = ["mypy"]
The currently supported type checkers are Mypy, ty, Pyrefly, and Pyright.
Finally, start writing Markdown files in your test directory (tests/ by default).
The files need to be named test_typing_*.md in order to be collected.
Inside the Markdown file, use Markdown headings (#, ##, etc.) to separate tests.
Inside each heading, write fenced Python code blocks (python or py) with code that will be type-checked.
This is what an example file might look like, defining two tests:
# This is a test file
This is free-form text that can explain the test but is ignored by the plugin.
## This is a happy-path test
This code snippet should type-check without problems.
```python
a: int = 1
```
## This is a sad-path test
This test demonstrates how errors can be checked using error codes.
Note that error codes are specific to individual type checkers.
```python
a: str = 1 # error: [invalid-assignment]
```
In addition to matching on error codes, we can additionally match the exact error messages too.
a: str = 1 # error: [invalid-assignment] Object of type `Literal[1]` is not assignable to `str`
Although this may be fragile since checkers can improve their error messages from time to time.
Comments may be placed above lines that are expected to produce errors.
# error: [invalid-assignment]
a: str = 1
reveal_type statements can be matched against.
reveal_type(1) # revealed: Literal[1]
Or, again, on the line above.
# revealed: Literal[1]
reveal_type(1)
A section may contain multiple code blocks; this is useful for inserting longer pieces of prose in between blocks. All blocks within a section get concatenated.
# This test contains multiple blocks
```python
a: int = 1
```
Here's some prose explaining what's going on, and then a second block:
```python
b: str = 1 # error: [invalid-assignment]
```
Testing on multiple checkers
When the typing_checkers field is configured with multiple checkers, tests will be run on all of them.
Difference checkers usually have different error codes, so different error comments should be used.
a: str = 1 # ty-error: [invalid-assignment] # mypy-error: [assignment]
Or, when more checkers are in use, stacked:
# ty-error: [invalid-assignment]
# mypy-error: [assignment]
# pyrefly-error: [bad-assignment]
# pyright-error: [reportAssignmentType]
a: str = 1
A code block can be configured to run only on a specific checker:
```python only=mypy
a: int = 1
```
Or configured to skip only a specific checker:
```python skip=mypy
a: int = 1
```
pytest-typing is inspired by Astral's mdtest framework.
Project Information
License
pytest-typing is written by Tin Tvrtković and distributed under the terms of the MIT license.
Release files for pytest-typing 26.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_typing-26.3.0.tar.gz | 65.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_typing-26.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.6 kB
Release files / pytest_typing-26.3.0.tar.gz
| Download URL | pytest_typing-26.3.0.tar.gz |
|---|---|
| Size | 65.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c0e155612088bd30351bd6a38fea2bf039a280b5303423e8c3eebe568c180b20
|
|
BLAKE2b-256 checksum How to use checksums |
3a3f982c57ce061a6fd667e85b1256eb3ad5d67dc56ba53d430b3bd9aca26716
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 24, 2026.
Transparency logRelease files / pytest_typing-26.3.0-py3-none-any.whl
| Download URL | pytest_typing-26.3.0-py3-none-any.whl |
|---|---|
| Size | 17.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b44a990622e8f77684b0f35c13e1d8711fd20a43c53a53b378619d69bea47007
|
|
BLAKE2b-256 checksum How to use checksums |
22c18c4b27724dc0cc0c566e7b1a27a1afd4497d6c5b9cc93a3f9330c742ac12
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 24, 2026.
Transparency log