| [build-system] | |
| requires = [ | |
| # NOTE: this needs to be kept in sync with mypy-requirements.txt | |
| # and build-requirements.txt, because those are both needed for | |
| # self-typechecking :/ | |
| "setuptools >= 75.1.0", | |
| # the following is from mypy-requirements.txt/setup.py | |
| "typing_extensions>=4.6.0", | |
| "mypy_extensions>=1.0.0", | |
| "pathspec>=0.9.0", | |
| "tomli>=1.1.0; python_version<'3.11'", | |
| # the following is from build-requirements.txt | |
| "types-psutil", | |
| "types-setuptools", | |
| ] | |
| build-backend = "setuptools.build_meta" | |
| [project] | |
| name = "mypy" | |
| description = "Optional static typing for Python" | |
| readme = {text = """ | |
| Mypy -- Optional Static Typing for Python | |
| ========================================= | |
| Add type annotations to your Python programs, and use mypy to type | |
| check them. Mypy is essentially a Python linter on steroids, and it | |
| can catch many programming errors by analyzing your program, without | |
| actually having to run it. Mypy has a powerful type system with | |
| features such as type inference, gradual typing, generics and union | |
| types. | |
| """, content-type = "text/x-rst"} | |
| authors = [{name = "Jukka Lehtosalo", email = "jukka.lehtosalo@iki.fi"}] | |
| license = {text = "MIT"} | |
| classifiers = [ | |
| "Development Status :: 5 - Production/Stable", | |
| "Environment :: Console", | |
| "Intended Audience :: Developers", | |
| "License :: OSI Approved :: MIT License", | |
| "Programming Language :: Python :: 3", | |
| "Programming Language :: Python :: 3.9", | |
| "Programming Language :: Python :: 3.10", | |
| "Programming Language :: Python :: 3.11", | |
| "Programming Language :: Python :: 3.12", | |
| "Programming Language :: Python :: 3.13", | |
| "Topic :: Software Development", | |
| "Typing :: Typed", | |
| ] | |
| requires-python = ">=3.9" | |
| dependencies = [ | |
| # When changing this, also update build-system.requires and mypy-requirements.txt | |
| "typing_extensions>=4.6.0", | |
| "mypy_extensions>=1.0.0", | |
| "pathspec>=0.9.0", | |
| "tomli>=1.1.0; python_version<'3.11'", | |
| ] | |
| dynamic = ["version"] | |
| [project.optional-dependencies] | |
| dmypy = ["psutil>=4.0"] | |
| mypyc = ["setuptools>=50"] | |
| python2 = [] | |
| reports = ["lxml"] | |
| install-types = ["pip"] | |
| faster-cache = ["orjson"] | |
| [project.urls] | |
| Homepage = "https://www.mypy-lang.org/" | |
| Documentation = "https://mypy.readthedocs.io/en/stable/index.html" | |
| Repository = "https://github.com/python/mypy" | |
| Changelog = "https://github.com/python/mypy/blob/master/CHANGELOG.md" | |
| Issues = "https://github.com/python/mypy/issues" | |
| [project.scripts] | |
| mypy = "mypy.__main__:console_entry" | |
| stubgen = "mypy.stubgen:main" | |
| stubtest = "mypy.stubtest:main" | |
| dmypy = "mypy.dmypy.client:console_entry" | |
| mypyc = "mypyc.__main__:main" | |
| [tool.setuptools.packages.find] | |
| include = ["mypy*", "mypyc*", "*__mypyc*"] | |
| exclude = ["mypyc.test-data*"] | |
| namespaces = false | |
| [tool.setuptools.package-data] | |
| mypy = [ | |
| "py.typed", | |
| "typeshed/**/*.py", | |
| "typeshed/**/*.pyi", | |
| "typeshed/stdlib/VERSIONS", | |
| "xml/*.xsd", | |
| "xml/*.xslt", | |
| "xml/*.css", | |
| ] | |
| [tool.setuptools.exclude-package-data] | |
| mypyc = [ | |
| "README.md", | |
| "doc/**", | |
| "external/**", | |
| "lib-rt/test_capi.cc", | |
| "lib-rt/setup.py", | |
| "test-data/**", | |
| ] | |
| [tool.black] | |
| line-length = 99 | |
| target-version = ["py39", "py310", "py311", "py312", "py313"] | |
| skip-magic-trailing-comma = true | |
| force-exclude = ''' | |
| ^/mypy/typeshed| | |
| ^/mypyc/test-data| | |
| ^/test-data | |
| ''' | |
| [tool.ruff] | |
| line-length = 99 | |
| target-version = "py39" | |
| fix = true | |
| extend-exclude = [ | |
| "@*", | |
| # Sphinx configuration is irrelevant | |
| "docs/source/conf.py", | |
| "mypyc/doc/conf.py", | |
| # tests have more relaxed styling requirements | |
| # fixtures have their own .pyi-specific configuration | |
| "test-data/*", | |
| "mypyc/test-data/*", | |
| # typeshed has its own .pyi-specific configuration | |
| "mypy/typeshed/*", | |
| ] | |
| [tool.ruff.lint] | |
| select = [ | |
| "E", # pycodestyle (error) | |
| "F", # pyflakes | |
| "W", # pycodestyle (warning) | |
| "B", # flake8-bugbear | |
| "I", # isort | |
| "N", # pep8-naming | |
| "PIE", # flake8-pie | |
| "PLE", # pylint error | |
| "RUF100", # Unused noqa comments | |
| "PGH004", # blanket noqa comments | |
| "UP", # pyupgrade | |
| "C4", # flake8-comprehensions | |
| "SIM101", # merge duplicate isinstance calls | |
| "SIM201", "SIM202", "SIM222", "SIM223", # flake8-simplify | |
| "FURB168", # Prefer is operator over isinstance for None checks | |
| "FURB169", # Do not use is comparison with type(None). Use None | |
| "FURB187", # avoid list reverse copy | |
| "FURB188", # use str.remove(pre|suf)fix | |
| "ISC001", # implicitly concatenated string | |
| "RET501", "RET502", # better return None handling | |
| ] | |
| ignore = [ | |
| "B007", # Loop control variable not used within the loop body. | |
| "B011", # Don't use assert False | |
| "B023", # Function definition does not bind loop variable | |
| "E2", # conflicts with black | |
| "E402", # module level import not at top of file | |
| "E501", # conflicts with black | |
| "E721", # Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks | |
| "E731", # Do not assign a `lambda` expression, use a `def` | |
| "E741", # Ambiguous variable name | |
| "N818", # Exception should be named with an Error suffix | |
| "N806", # UPPER_CASE used for constant local variables | |
| "UP031", # Use format specifiers instead of percent format | |
| "UP032", # 'f-string always preferable to format' is controversial | |
| "C409", # https://github.com/astral-sh/ruff/issues/12912 | |
| "C420", # reads a little worse. fromkeys predates dict comprehensions | |
| "C416", # There are a few cases where it's nice to have names for the dict items | |
| "PIE790", # there's nothing wrong with pass | |
| ] | |
| unfixable = [ | |
| "F841", # unused variable. ruff keeps the call, but mostly we want to get rid of it all | |
| "F601", # automatic fix might obscure issue | |
| "F602", # automatic fix might obscure issue | |
| "B018", # automatic fix might obscure issue | |
| "UP036", # sometimes it's better to just noqa this | |
| "SIM222", # automatic fix might obscure issue | |
| "SIM223", # automatic fix might obscure issue | |
| ] | |
| [tool.ruff.lint.per-file-ignores] | |
| # Mixed case variable and function names. | |
| "mypy/fastparse.py" = ["N802", "N816"] | |
| [tool.ruff.lint.isort] | |
| combine-as-imports = true | |
| extra-standard-library = ["typing_extensions"] | |
| [tool.check-manifest] | |
| ignore = ["**/.readthedocs.yaml"] | |
| [tool.pytest.ini_options] | |
| minversion = "7.0.0" | |
| testpaths = ["mypy/test", "mypyc/test"] | |
| python_files = 'test*.py' | |
| # Where do the test cases come from? We provide our own collection | |
| # logic by implementing `pytest_pycollect_makeitem` in mypy.test.data; | |
| # the test files import that module, and pytest sees the magic name | |
| # and invokes it at the relevant moment. See | |
| # https://doc.pytest.org/en/latest/how-to/writing_plugins.html#collection-hooks | |
| # Both our plugin and unittest provide their own collection logic, | |
| # So we can disable the default python collector by giving it empty | |
| # patterns to search for. | |
| # Note that unittest requires that no "Test*" classes exist. | |
| python_classes = [] | |
| python_functions = [] | |
| # always run in parallel (requires pytest-xdist, see test-requirements.txt) | |
| # and enable strict mode: require all markers | |
| # to be defined and raise on invalid config values | |
| addopts = "-nauto --strict-markers --strict-config" | |
| # treat xpasses as test failures so they get converted to regular tests as soon as possible | |
| xfail_strict = true | |
| [tool.coverage.run] | |
| branch = true | |
| source = ["mypy"] | |
| parallel = true | |
| [tool.coverage.report] | |
| show_missing = true | |
| skip_covered = true | |
| omit = ['mypy/test/*'] | |
| exclude_lines = [ | |
| '\#\s*pragma: no cover', | |
| '^\s*raise AssertionError\b', | |
| '^\s*raise NotImplementedError\b', | |
| '^\s*return NotImplemented\b', | |
| '^\s*raise$', | |
| '^assert False\b', | |
| '''^if __name__ == ['"]__main__['"]:$''', | |
| ] |