[project] name = "pytest" description = "pytest: simple powerful testing with Python" readme = "README.rst" keywords = [ "test", "unittest", ] license = {text = "MIT"} authors = [ {name = "Holger Krekel"}, {name = "Bruno Oliveira"}, {name = "Ronny Pfannschmidt"}, {name = "Floris Bruynooghe"}, {name = "Brianna Laugher"}, {name = "Florian Bruhin"}, {name = "Others (See AUTHORS)"}, ] requires-python = ">=3.8" classifiers = [ "Development Status :: 6 - Mature", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", "Operating System :: Unix", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Testing", "Topic :: Utilities", ] dynamic = [ "version", ] dependencies = [ 'colorama; sys_platform == "win32"', 'exceptiongroup>=1.0.0rc8; python_version < "3.11"', "iniconfig", "packaging", "pluggy<2.0,>=1.5", 'tomli>=1; python_version < "3.11"', ] [project.optional-dependencies] dev = [ "argcomplete", "attrs>=19.2", "hypothesis>=3.56", "mock", "pygments>=2.7.2", "requests", "setuptools", "xmlschema", ] [project.urls] Changelog = "https://docs.pytest.org/en/stable/changelog.html" Homepage = "https://docs.pytest.org/en/latest/" Source = "https://github.com/pytest-dev/pytest" Tracker = "https://github.com/pytest-dev/pytest/issues" Twitter = "https://twitter.com/pytestdotorg" [project.scripts] "py.test" = "pytest:console_main" pytest = "pytest:console_main" [build-system] build-backend = "setuptools.build_meta" requires = [ "setuptools>=61", "setuptools-scm[toml]>=6.2.3", ] [tool.setuptools.package-data] "_pytest" = ["py.typed"] "pytest" = ["py.typed"] [tool.setuptools_scm] write_to = "src/_pytest/_version.py" [tool.black] target-version = ['py38'] [tool.ruff] src = ["src"] line-length = 88 [tool.ruff.format] docstring-code-format = true [tool.ruff.lint] select = [ "B", # bugbear "D", # pydocstyle "E", # pycodestyle "F", # pyflakes "I", # isort "PYI", # flake8-pyi "UP", # pyupgrade "RUF", # ruff "W", # pycodestyle "PIE", # flake8-pie "PGH004", # pygrep-hooks - Use specific rule codes when using noqa "PLE", # pylint error "PLW", # pylint warning "PLR1714", # Consider merging multiple comparisons ] ignore = [ # bugbear ignore "B004", # Using `hasattr(x, "__call__")` to test if x is callable is unreliable. "B007", # Loop control variable `i` not used within loop body "B009", # Do not call `getattr` with a constant attribute value "B010", # [*] Do not call `setattr` with a constant attribute value. "B011", # Do not `assert False` (`python -O` removes these calls) "B028", # No explicit `stacklevel` keyword argument found # pycodestyle ignore # pytest can do weird low-level things, and we usually know # what we're doing when we use type(..) is ... "E721", # Do not compare types, use `isinstance()` # pydocstyle ignore "D100", # Missing docstring in public module "D101", # Missing docstring in public class "D102", # Missing docstring in public method "D103", # Missing docstring in public function "D104", # Missing docstring in public package "D105", # Missing docstring in magic method "D106", # Missing docstring in public nested class "D107", # Missing docstring in `__init__` "D209", # [*] Multi-line docstring closing quotes should be on a separate line "D205", # 1 blank line required between summary line and description "D400", # First line should end with a period "D401", # First line of docstring should be in imperative mood "D402", # First line should not be the function's signature "D404", # First word of the docstring should not be "This" "D415", # First line should end with a period, question mark, or exclamation point # ruff ignore "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` # pylint ignore "PLW0603", # Using the global statement "PLW0120", # remove the else and dedent its contents "PLW2901", # for loop variable overwritten by assignment target "PLR5501", # Use `elif` instead of `else` then `if` ] [tool.ruff.lint.pycodestyle] # In order to be able to format for 88 char in ruff format max-line-length = 120 [tool.ruff.lint.pydocstyle] convention = "pep257" [tool.ruff.lint.isort] force-single-line = true combine-as-imports = true force-sort-within-sections = true order-by-type = false known-local-folder = ["pytest", "_pytest"] lines-after-imports = 2 [tool.ruff.lint.per-file-ignores] "src/_pytest/_py/**/*.py" = ["B", "PYI"] "src/_pytest/_version.py" = ["I001"] "testing/python/approx.py" = ["B015"] [tool.pylint.main] # Maximum number of characters on a single line. max-line-length = 120 disable= [ "abstract-method", "arguments-differ", "arguments-renamed", "assigning-non-slot", "attribute-defined-outside-init", "bad-classmethod-argument", "bad-mcs-method-argument", "broad-exception-caught", "broad-exception-raised", "cell-var-from-loop", "comparison-of-constants", "comparison-with-callable", "comparison-with-itself", "condition-evals-to-constant", "consider-using-dict-items", "consider-using-enumerate", "consider-using-from-import", "consider-using-f-string", "consider-using-in", "consider-using-sys-exit", "consider-using-ternary", "consider-using-with", "cyclic-import", "disallowed-name", "duplicate-code", "eval-used", "exec-used", "expression-not-assigned", "fixme", "global-statement", "implicit-str-concat", "import-error", "import-outside-toplevel", "inconsistent-return-statements", "invalid-bool-returned", "invalid-name", "invalid-repr-returned", "invalid-str-returned", "keyword-arg-before-vararg", "line-too-long", "method-hidden", "misplaced-bare-raise", "missing-docstring", "missing-timeout", "multiple-statements", "no-else-break", "no-else-continue", "no-else-raise", "no-else-return", "no-member", "no-name-in-module", "no-self-argument", "not-an-iterable", "not-callable", "pointless-exception-statement", "pointless-statement", "pointless-string-statement", "protected-access", "raise-missing-from", "redefined-argument-from-local", "redefined-builtin", "redefined-outer-name", "reimported", "simplifiable-condition", "simplifiable-if-expression", "singleton-comparison", "superfluous-parens", "super-init-not-called", "too-few-public-methods", "too-many-ancestors", "too-many-arguments", "too-many-branches", "too-many-function-args", "too-many-instance-attributes", "too-many-lines", "too-many-locals", "too-many-nested-blocks", "too-many-public-methods", "too-many-return-statements", "too-many-statements", "try-except-raise", "typevar-name-incorrect-variance", "unbalanced-tuple-unpacking", "undefined-loop-variable", "undefined-variable", "unexpected-keyword-arg", "unidiomatic-typecheck", "unnecessary-comprehension", "unnecessary-dunder-call", "unnecessary-lambda", "unnecessary-lambda-assignment", "unpacking-non-sequence", "unspecified-encoding", "unsubscriptable-object", "unused-argument", "unused-import", "unused-variable", "used-before-assignment", "use-dict-literal", "use-implicit-booleaness-not-comparison", "use-implicit-booleaness-not-len", "useless-else-on-loop", "useless-import-alias", "useless-return", "use-maxsplit-arg", "using-constant-test", "wrong-import-order", ] [tool.check-wheel-contents] # check-wheel-contents is executed by the build-and-inspect-python-package action. # W009: Wheel contains multiple toplevel library entries ignore = "W009" [tool.pyproject-fmt] indent = 4 [tool.pytest.ini_options] minversion = "2.0" addopts = "-rfEX -p pytester --strict-markers" python_files = ["test_*.py", "*_test.py", "testing/python/*.py"] python_classes = ["Test", "Acceptance"] python_functions = ["test"] # NOTE: "doc" is not included here, but gets tested explicitly via "doctesting". testpaths = ["testing"] norecursedirs = [ "testing/example_scripts", ".*", "build", "dist", ] xfail_strict = true filterwarnings = [ "error", "default:Using or importing the ABCs:DeprecationWarning:unittest2.*", # produced by older pyparsing<=2.2.0. "default:Using or importing the ABCs:DeprecationWarning:pyparsing.*", "default:the imp module is deprecated in favour of importlib:DeprecationWarning:nose.*", # distutils is deprecated in 3.10, scheduled for removal in 3.12 "ignore:The distutils package is deprecated:DeprecationWarning", # produced by pytest-xdist "ignore:.*type argument to addoption.*:DeprecationWarning", # produced on execnet (pytest-xdist) "ignore:.*inspect.getargspec.*deprecated, use inspect.signature.*:DeprecationWarning", # pytest's own futurewarnings "ignore::pytest.PytestExperimentalApiWarning", # Do not cause SyntaxError for invalid escape sequences in py37. # Those are caught/handled by pyupgrade, and not easy to filter with the # module being the filename (with .py removed). "default:invalid escape sequence:DeprecationWarning", # ignore not yet fixed warnings for hook markers "default:.*not marked using pytest.hook.*", "ignore:.*not marked using pytest.hook.*::xdist.*", # ignore use of unregistered marks, because we use many to test the implementation "ignore::_pytest.warning_types.PytestUnknownMarkWarning", # https://github.com/benjaminp/six/issues/341 "ignore:_SixMetaPathImporter\\.exec_module\\(\\) not found; falling back to load_module\\(\\):ImportWarning", # https://github.com/benjaminp/six/pull/352 "ignore:_SixMetaPathImporter\\.find_spec\\(\\) not found; falling back to find_module\\(\\):ImportWarning", # https://github.com/pypa/setuptools/pull/2517 "ignore:VendorImporter\\.find_spec\\(\\) not found; falling back to find_module\\(\\):ImportWarning", # https://github.com/pytest-dev/execnet/pull/127 "ignore:isSet\\(\\) is deprecated, use is_set\\(\\) instead:DeprecationWarning", ] pytester_example_dir = "testing/example_scripts" markers = [ # dummy markers for testing "foo", "bar", "baz", # conftest.py reorders tests moving slow ones to the end of the list "slow", # experimental mark for all tests using pexpect "uses_pexpect", ] [tool.towncrier] package = "pytest" package_dir = "src" filename = "doc/en/changelog.rst" directory = "changelog/" title_format = "pytest {version} ({project_date})" template = "changelog/_template.rst" [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true [[tool.towncrier.type]] directory = "feature" name = "Features" showcontent = true [[tool.towncrier.type]] directory = "improvement" name = "Improvements" showcontent = true [[tool.towncrier.type]] directory = "bugfix" name = "Bug Fixes" showcontent = true [[tool.towncrier.type]] directory = "vendor" name = "Vendored Libraries" showcontent = true [[tool.towncrier.type]] directory = "doc" name = "Improved Documentation" showcontent = true [[tool.towncrier.type]] directory = "trivial" name = "Trivial/Internal Changes" showcontent = true [tool.mypy] files = ["src", "testing", "scripts"] mypy_path = ["src"] check_untyped_defs = true disallow_any_generics = true disallow_untyped_defs = true ignore_missing_imports = true show_error_codes = true strict_equality = true warn_redundant_casts = true warn_return_any = true warn_unreachable = true warn_unused_configs = true no_implicit_reexport = true warn_unused_ignores = true