blob: 1870e0931407cc650225a4edea9553bb1231a9dd [file] [log] [blame] [edit]
[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",
"Programming Language :: Python :: 3.14",
"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__['"]:$''',
]