Skip to content

Commit b6b4159

Browse files
committed
Merge branch 'main' into impr/quality/add-pytest-mypy-testing
2 parents ebbefdb + 736f9ec commit b6b4159

File tree

757 files changed

+46271
-1700
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

757 files changed

+46271
-1700
lines changed

.flake8

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[flake8]
22

33
max-line-length = 90
4+
exclude = conformance
45
ignore =
56
# irrelevant plugins
67
B3,

.github/ISSUE_TEMPLATE/documentation-issue.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: Documentation issue
3-
about: Report a problem or suggest changes for the documentation at https://typing.readthedocs.io/
3+
about: Report a problem or suggest changes for the documentation at https://typing.python.org/
44
title: ''
55
labels: 'topic: documentation'
66
assignees: ''

.github/dependabot.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: monthly
7+
groups:
8+
actions:
9+
patterns:
10+
- "*"

.github/workflows/build-docs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ jobs:
1313
runs-on: ubuntu-latest
1414

1515
steps:
16-
- uses: actions/checkout@v2
16+
- uses: actions/checkout@v4
1717
- name: Set up Python
18-
uses: actions/setup-python@v2
18+
uses: actions/setup-python@v5
1919
with:
2020
python-version: 3.9
2121
- name: Install dependencies

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ jobs:
1414
runs-on: ubuntu-latest
1515

1616
steps:
17-
- uses: actions/checkout@v2
17+
- uses: actions/checkout@v4
1818
- name: Set up Python 3
19-
uses: actions/setup-python@v2
19+
uses: actions/setup-python@v5
2020
with:
2121
python-version: 3
2222
cache: "pip"

.pre-commit-config.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v4.6.0
4+
hooks:
5+
- id: trailing-whitespace
6+
exclude: conformance/results/.*/.*\.toml
7+
- id: end-of-file-fixer
8+
- id: check-yaml
9+
- id: check-toml
10+
- id: check-merge-conflict
11+
- id: mixed-line-ending
12+
args: [--fix=lf]
13+
exclude: docs/make\.bat
14+
- id: check-case-conflict
15+
- repo: meta
16+
hooks:
17+
- id: check-hooks-apply
18+
19+
ci:
20+
autofix_commit_msg: "[pre-commit.ci] auto fixes from pre-commit.com hooks"
21+
autofix_prs: true
22+
autoupdate_commit_msg: "[pre-commit.ci] pre-commit autoupdate"
23+
autoupdate_schedule: quarterly
24+
submodules: false

.readthedocs.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Read the Docs configuration file
2+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3+
4+
version: 2
5+
6+
build:
7+
os: ubuntu-22.04
8+
tools:
9+
python: "3"
10+
11+
sphinx:
12+
configuration: docs/conf.py
13+
14+
python:
15+
install:
16+
- requirements: docs/requirements.txt

README.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,34 @@
33
## Documentation and Support
44

55
The documentation for Python's static typing can be found at
6-
[typing.readthedocs.io](https://typing.readthedocs.io/). You can get
6+
[typing.python.org](https://typing.python.org/). You can get
77
help in our [support forum](https://github.com/python/typing/discussions).
88

9-
Improvements to the type system should be discussed on the
10-
[typing-sig](https://mail.python.org/mailman3/lists/typing-sig.python.org/)
11-
mailing list, although the [issues](https://github.com/python/typing/issues) in this
12-
repository contain some historic discussions.
9+
Improvements to the type system should be discussed on
10+
[Python's Discourse](https://discuss.python.org/c/typing/32), and are
11+
tracked in the [issues](https://github.com/python/typing/issues) in this
12+
repository.
1313

1414
For conversations that are more suitable to a chat platform, you can use one of the following:
15+
1516
- [gitter](https://gitter.im/python/typing)
1617
- [discord](https://discord.com/channels/267624335836053506/891788761371906108) `#type-hinting` channel
1718

1819
## Repository Content
1920

2021
This GitHub repository is used for several things:
2122

22-
- The documentation at [typing.readthedocs.io](https://typing.readthedocs.io/)
23-
is maintained in the [docs directory](./docs).
23+
- The documentation at [typing.python.org](https://typing.python.org/)
24+
is maintained in the [docs directory](./docs). This includes the
25+
[specification](https://typing.python.org/en/latest/spec/index.html) for the
26+
type system. See especially [the update procedure](https://typing.python.org/en/latest/spec/meta.html)
27+
for the spec.
2428

2529
- A [discussion forum](https://github.com/python/typing/discussions) for typing-related user
2630
help is hosted here.
2731

32+
- [Conformance test](https://github.com/python/typing/blob/main/conformance/README.md) for Python static type checkers. The [latest conformance test results](https://htmlpreview.github.io/?https://github.com/python/typing/blob/main/conformance/results/results.html) are here.
33+
2834
Historically, this repository also hosted:
2935

3036
- The `typing_extensions` package, which now lives in the

conformance/.gitignore

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
share/python-wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST
28+
29+
# Environments
30+
.env
31+
.venv
32+
33+
# Tools
34+
.mypy_cache
35+
.pyre_configuration
36+
.pyre
37+
.coverage
38+
htmlcov
39+
40+
# General
41+
.DS_Store
42+
43+
# Editor temp files
44+
.*.swp
45+
46+
# Workspace configurations
47+
.vscode

conformance/README.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Type System Conformance
2+
3+
## Motivation
4+
5+
[PEP 729](https://peps.python.org/pep-0729/) provides a structured and documented way to specify and evolve the Python type system. In support of this effort, an official [Python typing spec](https://typing.python.org/en/latest/spec/) has been drafted. This spec consolidates details from various historical typing-related PEPs. The spec will be modified over time to clarify unspecified and under-specified parts of the type system. It will also be extended to cover new features of the type system.
6+
7+
Accompanying the typing specification is this conformance test suite which validates the behavior of static type checkers against the specification.
8+
9+
## Structure & Name
10+
11+
This project contains test cases for behaviors defined in the Python typing spec. Tests are structured and grouped in accordance with the specification's chapter headings.
12+
13+
* [concepts](https://typing.python.org/en/latest/spec/concepts.html)
14+
* [annotations](https://typing.python.org/en/latest/spec/annotations.html)
15+
* [specialtypes](https://typing.python.org/en/latest/spec/special-types.html)
16+
* [generics](https://typing.python.org/en/latest/spec/generics.html)
17+
* [qualifiers](https://typing.python.org/en/latest/spec/qualifiers.html)
18+
* [classes](https://typing.python.org/en/latest/spec/class-compat.html)
19+
* [aliases](https://typing.python.org/en/latest/spec/aliases.html)
20+
* [literals](https://typing.python.org/en/latest/spec/literal.html)
21+
* [protocols](https://typing.python.org/en/latest/spec/protocol.html)
22+
* [callables](https://typing.python.org/en/latest/spec/callables.html)
23+
* [constructors](https://typing.python.org/en/latest/spec/constructors.html)
24+
* [overloads](https://typing.python.org/en/latest/spec/overload.html)
25+
* [dataclasses](https://typing.python.org/en/latest/spec/dataclasses.html)
26+
* [typeddicts](https://typing.python.org/en/latest/spec/typeddict.html)
27+
* [tuples](https://typing.python.org/en/latest/spec/tuples.html)
28+
* [namedtuples](https://typing.python.org/en/latest/spec/namedtuples.html)
29+
* [narrowing](https://typing.python.org/en/latest/spec/narrowing.html)
30+
* [directives](https://typing.python.org/en/latest/spec/directives.html)
31+
* [distribution](https://typing.python.org/en/latest/spec/distributing.html)
32+
* [historical](https://typing.python.org/en/latest/spec/historical.html)
33+
34+
A test file is a ".py" file. The file name should start with one of the above names followed by a description of the test (with words separated by underscores). For example, `generics_paramspec_basic_usage.py` would contain the basic usage tests for `ParamSpec`. Each test file can contain multiple individual unit tests, but these tests should be related to each other. If the number of unit tests in a single test file exceeds ten, it may be desirable to split it into separate test files. This will help maintain a consistent level of granularity across tests.
35+
36+
## Notes About Tests
37+
38+
Tests are designed to run on all current and future static type checkers. They must therefore be type-checker agnostic and should not rely on functionality or behaviors that are specific to one type checker or another.
39+
40+
Test cases are meant to be human readable. They should include comments that help explain their purpose (what is being tested, whether an error should be generated, etc.). They should also contain links to the typing spec, discussions, and issue trackers.
41+
42+
The test suite focuses on static type checking not general Python semantics. Tests should therefore focus on static analysis behaviors, not runtime behaviors.
43+
44+
Test cases use the following conventions:
45+
46+
* Lines that are expected to produce a type checker error should have a comment starting with # E",
47+
either by itself or followed by an explanation after a colon (e.g., "# E: int is not a subtype
48+
of str"). Such explanatory comments are purely for human understanding, but type checkers are not
49+
expected to use their exact wording.
50+
* Lines that may produce an error (e.g., because the spec allows multiple behaviors) should be
51+
marked with "# E?" instead of "# E".
52+
* If a test case tests conformance with a specific passage in the spec, that passage should be
53+
quoted in a comment prefixed with "# > ".
54+
55+
## Running the Conformance Test Tool
56+
57+
To run the conformance test suite:
58+
* Clone the https://github.com/python/typing repo.
59+
* Create and activate a Python 3.12 virtual environment.
60+
* Switch to the `conformance` subdirectory and install all dependencies (`pip install -r requirements.txt`).
61+
* Switch to the `src` subdirectory and run `python main.py`.
62+
63+
Note that some type checkers may not run on some platforms. For example, pytype cannot be installed on Windows. If a type checker fails to install, tests will be skipped for that type checker.
64+
65+
## Reporting Conformance Results
66+
67+
Different type checkers report errors in different ways (with different wording in error messages and different line numbers or character ranges for errors). This variation makes it difficult to fully automate test validation given that tests will want to check for both false positive and false negative type errors. Some level of manual inspection will therefore be needed to determine whether a type checker is fully conformant with all tests in any given test file. This "scoring" process is required only when the output of a test changes — e.g. when a new version of that type checker is released and the tests are rerun. We assume that the output of a type checker will be the same from one run to the next unless/until a new version is released that fixes or introduces a bug. In this case, the output will need to be manually inspected and the conformance results re-scored for those tests whose output has changed.
68+
69+
Conformance results are reported and summarized for each supported type checker. Currently, results are reported for mypy, pyre, pyright, and pytype. It is the goal and desire to add additional type checkers over time.
70+
71+
## Adding a New Test Case
72+
73+
To add a new test, create a new ".py" file in the `tests` directory. Its name must begin with one of the above test group names followed by an underscore. Write the contents of the test including a module docstring describing the purpose of the test. Next, run the conformance test tool. This will generate a new `.toml` file in the `results` subdirectory corresponding each type checker. Manually review the output from each type checker and determine whether it conforms to the specification. If so, add `conformant = "Pass"` to the `.toml` file. If it does not fully comply, add `conformant = "Partial"` and a `notes` section detailing where it is not compliant. If the type checker doesn't support the feature in the test add `conformant = "Unsupported"`. Once the conformance status has been updated, rerun the conformance test tool to regenerate the summary report.
74+
75+
## Updating a Test Case
76+
77+
If a test is updated (augmented or fixed), the process is similar to when adding a new test. Run the conformance test tool to generate new results and manually examine the output of each supported type checker. Then update the conformance status accordingly. Once the conformance status has been updated, rerun the conformance test tool to regenerate the summary report.
78+
79+
## Updating a Type Checker
80+
81+
If a new version of a type checker is released, re-run the test tool with the new version. If the type checker output has changed for any test cases, the tool will supply the old and new outputs. Examine these to determine whether the conformance status has changed. Once the conformance status has been updated, re-run the test tool again to regenerate the summary report.
82+
83+
## Automated Conformance Checking
84+
85+
In addition to manual scoring, we provide an experimental tool that automatically checks type checkers for conformance. This tool relies on the "# E" comments present in the stubs and on parsing type checker output. This logic is run automatically as part of the conformance test tool. It produces the following fields in the `.toml` output files:
86+
87+
* `errors_diff`: a string describing all issues found with the type checker's behavior: either expected errors that were not emitted, or extra errors that the conformance test suite does not allow.
88+
* `conformance_automated`: either "Pass" or "Fail" based on whether there are any discrepancies with the expected behavior.
89+
90+
This tool does not yet work reliably on all test cases. The script `conformance/src/unexpected_fails.py` can be run to find all test cases where the automated tool's conformance judgment differs from the manual judgment entered in the `.toml` files.
91+
92+
Some common problems with automated checks:
93+
94+
* Sometimes the spec is imprecise or allows multiple options. In this case, use "# E?" to mark an error as optional.
95+
* Type checkers may produce additional errors for issues unrelated to the topic being tested. In this case, add an extra field `ignore_errors` in the type checker's `.toml` file that contains the text of the irrelevant errors. Any error message that contains a substring in the `ignore_errors` list is ignored. For example, if `ignore_errors = ["Too many arguments"]`, then a mypy error `dataclasses_usage.py:127: error: Too many arguments for "DC7" [call-arg]` will be ignored.
96+
* Type checkers may differ in the line on which they report an error. In this case, on each of the lines where an error could
97+
reasonably be shown, write `# E[<tag>]`, where `<tag>` is an arbitrary string that is unique in the file. The test will be marked as passing if the type checker produces an error on exactly one of the lines where this tag appears.
98+
99+
## Contributing
100+
101+
Contributions are welcome!

0 commit comments

Comments
 (0)