[build-system]
build-backend = "hatchling.build"
requires = [
  "docutils>=0.21",
  "hatch-vcs>=0.5",
  "hatchling>=1.29",
]

[project]
name = "tox"
description = "tox is a generic virtualenv management and test command line tool"
readme.content-type = "text/markdown"
readme.file = "README.md"
keywords = [
  "environments",
  "isolated",
  "testing",
  "virtual",
]
license = "MIT"
maintainers = [
  { name = "Bernát Gábor", email = "gaborjbernat@gmail.com" },
  { name = "Jürgen Gmach", email = "juergen.gmach@googlemail.com" },
  { name = "Rahul Devikar", email = "rahuldevikar5512@gmail.com" },
]
authors = [
  { name = "Bernát Gábor", email = "gaborjbernat@gmail.com" },
]
requires-python = ">=3.10"
classifiers = [
  "Development Status :: 5 - Production/Stable",
  "Framework :: tox",
  "Intended Audience :: Developers",
  "License :: OSI Approved :: MIT License",
  "Operating System :: MacOS :: MacOS X",
  "Operating System :: Microsoft :: Windows",
  "Operating System :: POSIX",
  "Programming Language :: Python :: 3 :: Only",
  "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",
  "Programming Language :: Python :: 3.15",
  "Topic :: Software Development :: Libraries",
  "Topic :: Software Development :: Testing",
  "Topic :: Utilities",
]
dynamic = [
  "version",
]
dependencies = [
  "cachetools>=7.0.3",
  "colorama>=0.4.6",
  "filelock>=3.25",
  "packaging>=26",
  "platformdirs>=4.9.4",
  "pluggy>=1.6",
  "pyproject-api>=1.10",
  "python-discovery>=1.4.4",
  "tomli>=2.4; python_version<'3.11'",
  "tomli-w>=1.2",
  "typing-extensions>=4.15; python_version<'3.11'",
  "virtualenv>=21.1",
]
optional-dependencies.completion = [
  "argcomplete>=3.6.3",
]
optional-dependencies.testing = [
  "devpi-process>=1.1.1",
  "pytest>=9.0.2",
  "pytest-mock>=3.15.1",
]
urls."Release Notes" = "https://tox.wiki/en/latest/changelog.html"
urls.Documentation = "https://tox.wiki"
urls.Homepage = "https://tox.wiki"
urls.Source = "https://github.com/tox-dev/tox"
urls.Tracker = "https://github.com/tox-dev/tox/issues"
scripts.tox = "tox.run:run"

[dependency-groups]
dev = [
  { include-group = "docs" },
  { include-group = "test" },
  { include-group = "type" },
]
test = [
  "build[virtualenv]>=1.4",
  "covdefaults>=2.3",
  "coverage>=7.13.4",
  "detect-test-pollution>=1.2",
  "devpi-process>=1.1.1",
  "diff-cover>=10.2",
  "distlib>=0.4",
  "docutils>=0.21",
  "flaky>=3.8.1",
  "hatch-vcs>=0.5",
  "hatchling>=1.29",
  "pdm-backend>=2.4.7",
  "psutil>=7.2.2",
  "pytest>=9.0.2",
  "pytest-cov>=7",
  "pytest-mock>=3.15.1",
  "pytest-timeout>=2.4",
  "pytest-xdist>=3.8",
  "re-assert>=1.1",
  "setuptools<82,>=81",
  "time-machine>=3.2; implementation_name!='pypy'",
  "tombi>=0.11.3",
  "wheel>=0.46.3",
]
type = [
  "ty>=0.0.19",
  "types-docutils>=0.21",
  { include-group = "docs" },
  { include-group = "release" },
  { include-group = "test" },
]
docs = [
  "furo>=2025.12.19",
  "sphinx>=9.1",
  "sphinx-argparse-cli>=1.21.1",
  "sphinx-autodoc-typehints>=3.9.7",
  "sphinx-copybutton>=0.5.2",
  "sphinx-inline-tabs>=2025.12.21.14",
  "sphinx-issues>=5.0.1",
  "sphinx-reredirects>=1.1",
  "sphinxcontrib-mermaid>=2.0.1",
  "sphinxcontrib-towncrier>=0.2.1a0",
  "towncrier>=25.8",
  "truststore>=0.10.4",
]
fix = [
  "pre-commit-uv>=4.2.1",
]
pkg-meta = [
  "check-wheel-contents>=0.6.3",
  "twine>=6.2",
  "uv>=0.10.8",
]
release = [
  "gitpython>=3.1.46",
  "packaging>=26",
  "pre-commit>=4.5.1",
  "towncrier>=25.8",
]
type-min = [
  "ty>=0.0.19",
  { include-group = "test" },
]

[tool.hatch]
version.source = "vcs"
build.dev-mode-dirs = [
  "src",
]
build.hooks.custom = {}
build.hooks.vcs.version-file = "src/tox/version.py"
build.targets.wheel.shared-data = { "build/man" = "share/man/man1" }
build.targets.sdist.include = [
  "/docs/man",
  "/src",
  "/tests",
  "/tox.toml",
]

[tool.ruff]
line-length = 120
format.preview = true
format.docstring-code-line-length = 100
format.docstring-code-format = true
lint.select = [
  "ALL",
]
lint.ignore = [
  "ANN401",  # Dynamically typed expressions (typing.Any) are disallowed in `arg`"
  "COM812",  # conflicts with formatter
  "CPY",     # No copyright header
  "D",       # ignore documentation for now
  "D203",    # `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible
  "D212",    # `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible
  "DOC201",  # no restructuredtext support yet
  "DOC402",  # no restructuredtext support yet
  "DOC501",  # broken with sphinx docs
  "INP001",  # no implicit namespaces here
  "ISC001",  # conflicts with formatter
  "LOG015",  # we require use of the root logger for reporting
  "PLR0914", ## Too many local variables
  "PLR0917", ## Too many positional arguments
  "RUF067",  # `__init__` module should only contain docstrings and re-exports
  "S104",    # Possible binding to all interfaces
  "S404",    # Using subprocess is alright.
  "S603",    # Using subprocess is alright.
]
lint.per-file-ignores."tests/**/*.py" = [
  "D",       # don't care about documentation in tests
  "FBT",     # don't care about booleans as positional arguments in tests
  "INP001",  # no implicit namespace
  "PLR0913", # too many arguments to function definition
  "PLR2004", # Magic value used in comparison, consider replacing with a constant variable
  "S101",    # asserts allowed in tests
  "S603",    # `subprocess` call: check for execution of untrusted input
]
lint.isort = { known-first-party = [
  "tox",
  "tests",
], required-imports = [
  "from __future__ import annotations",
] }
lint.preview = true

[tool.codespell]
builtin = "clear,usage,en-GB_to_en-US"
ignore-words = "ignore-words.txt"
skip = "*.svg"
write-changes = true
count = true

[tool.pyproject-fmt]
max_supported_python = "3.15"

[tool.ty]
src.exclude = []
environment.extra-paths = [ "typestubs" ]
environment.python-version = "3.14"

[tool.pytest]
ini_options.testpaths = [
  "tests",
]
ini_options.addopts = "--no-success-flaky-report"
ini_options.markers = [
  "integration: marks tests as integration tests requiring external services (deselect with '-m \"not integration\"')",
  "slow: marks tests as slow (>1s) (deselect with '-m \"not slow\"')",
]
ini_options.filterwarnings = [
  "error",
  "ignore:os.path.commonprefix\\(\\) is deprecated:DeprecationWarning",          # https://github.com/pygments/pygments/issues/3039 https://github.com/pypa/pyproject-hooks/issues/223
  "ignore:subprocess .* is still running:ResourceWarning",
  "ignore:unclosed database in <sqlite3.Connection object at:ResourceWarning",
  "ignore:unclosed file <_io.TextIOWrapper:ResourceWarning",
]
ini_options.verbosity_assertions = 2
ini_options.tmp_path_retention_policy = "failed"
ini_options.timeout = 30

[tool.coverage]
run.parallel = true
run.plugins = [
  "covdefaults",
]
paths.source = [
  "src",
  ".tox*/*/lib/python*/site-packages",
  ".tox*/pypy*/site-packages",
  ".tox*\\*\\Lib\\site-packages",
  "*/src",
  "*\\src",
]
report.fail_under = 88
report.omit = [
  "src/tox/config/cli/for_docs.py",
  "tests/execute/local_subprocess/bad_process.py",
  "tests/type_check/*",
]
html.show_contexts = true
html.skip_covered = false

[tool.towncrier]
name = "tox"
directory = "docs/changelog"
filename = "docs/changelog.rst"
template = "docs/changelog/template.jinja2"
title_format = false
issue_format = ":issue:`{issue}`"
type = [
  { directory = "breaking", name = "Backward incompatible changes", showcontent = true },
  { directory = "deprecation", name = "Deprecations (removal in next major release)", showcontent = true },
  { directory = "feature", name = "Features", showcontent = true },
  { directory = "bugfix", name = "Bug fixes", showcontent = true },
  { directory = "doc", name = "Improved documentation", showcontent = true },
  { directory = "packaging", name = "Packaging updates and notes for downstreams", showcontent = true },
  { directory = "contrib", name = "Contributor-facing changes", showcontent = true },
  { directory = "misc", name = "Miscellaneous internal changes", showcontent = true },
]
