[build-system]
requires = ["flit-core >= 3.11"]
build-backend = "flit_core.buildapi"

[project]
name = "build"
description = "A simple, correct Python build frontend"
readme = "README.md"
requires-python = ">= 3.10"
license = "MIT"
authors = [
  { name = "Filipe Laíns", email = "lains@riseup.net" },
  { name = "Bernát Gábor", email = "gaborjbernat@gmail.com" },
  { name = "layday", email = "layday@protonmail.com" },
  { name = "Henry Schreiner", email = "henryschreineriii@gmail.com" },
]
classifiers = [
  "Programming Language :: Python :: 3",
  "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",
  "Programming Language :: Python :: Implementation :: CPython",
  "Programming Language :: Python :: Implementation :: PyPy",
]
urls.changelog = "https://build.pypa.io/en/stable/changelog.html"
urls.homepage = "https://build.pypa.io"
urls.issues = "https://github.com/pypa/build/issues"
urls.source = "https://github.com/pypa/build"
# Version read from __version__ field in __init__.py by Flit
dynamic = ["version"]
dependencies = [
  "packaging >= 24.0",
  "pyproject_hooks",
  # not actually a runtime dependency, only supplied as there is not "recommended dependency" support
  'colorama; os_name == "nt"',
  'importlib-metadata >= 4.6; python_full_version < "3.10.2"',  # Not required but fixes a stdlib bug
  'tomli >= 1.1.0; python_version < "3.11"',
]

[project.optional-dependencies]
uv = [
  "uv >= 0.1.18",
]
keyring = [
  "keyring",
]
virtualenv = [
  "virtualenv >= 20.36.1",
]

[project.scripts]
pyproject-build = "build.__main__:entrypoint"

[project.entry-points."pipx.run"]
build = "build.__main__:entrypoint"

[dependency-groups]
extra = [
  "uv >= 0.1.18",
  "virtualenv >= 20.36.1",
]
lint = [
  "prek",
]
coverage = [
  "covdefaults >= 2.3",
  "coverage[toml] >= 6.0",
  "diff_cover >= 6.4.2",
]
bump = [
  "bump-my-version >= 0.10",
]
docs = [
  "furo >= 2025.12.19",
  "pre-commit >= 3.0",
  "proselint >= 0.16",
  "sphinx >= 8.1",
  "sphinx-argparse-cli >= 1.17",
  "sphinx-autodoc-typehints >= 2.3",
  "sphinx-copybutton >= 0.5.2",
  "sphinx-inline-tabs >= 2025.12.21",
  "sphinx-issues >= 5.0",
  "sphinxcontrib-mermaid >= 2.0",
  "towncrier >= 24.8",
]
test-core = [
  "pytest >= 6.2.5, != 9.1.0",
  "pytest-cov >= 3.0.0",
  "pytest-mock >= 3.7.0",
  "pytest-rerunfailures >= 10.2",
  "pytest-xdist >= 2.4.0",
]
test = [
  "filelock >= 3.20.1",
  "covdefaults >= 2.3",
  "wheel >= 0.38.1",
  'setuptools >= 56.0.0; python_version == "3.10"',
  'setuptools >= 56.0.0; python_version == "3.11"',
  'setuptools >= 67.8.0; python_version >= "3.12"',
  "setuptools_scm >= 6.4.2",
  "pip >= 22.3",
  { include-group = "test-core" },
  { include-group = "extra" },
]
typing = [
  "importlib-metadata >= 5.1",
  "tomli",
  "typing-extensions >= 4.0.0",
  "types-colorama",
  "gitpython >= 3.1.44",
  { include-group = "test-core" },
  { include-group = "extra" },
]
mypy = [
  "mypy ~= 2.3.0",
  { include-group = "typing" },
]
release = [
  "docstrfmt == 2.2.0", # keep in sync with the docstrfmt rev in .pre-commit-config.yaml
  "gitpython >= 3.1.44",
  "packaging >= 25",
  "pre-commit >= 3.0",
  "towncrier >= 24.8",
]
dev = [
  "flit-core",
  { include-group = "test" },
  { include-group = "mypy" },
]

[tool.flit.sdist]
include = ["tests/", ".gitignore", "CHANGELOG.rst", "docs/", ".dockerignore", "tox.toml"]
exclude = [
  "**/__pycache__",
  "docs/_build",
  "**/*.egg-info",
  "tests/packages/*/build",
  "docs/changelog/template.jinja2",
  "tasks/*",
]

[tool.uv]
exclude-newer = "7 days"


[tool.coverage]
run.plugins = ["covdefaults"]
run.core = "ctrace"  # sysmon is 3.14+'s default but can't record dynamic contexts; PyPy falls back to pytrace
run.source = ["build", "tests"]
run.omit = ["tests/conftest.py", "tests/test_integration.py", "tests/integration_sources.py",]
report.omit = ["src/build/_types.py"]
run.disable_warnings = [
  "module-not-measured",  # Triggers in multithreaded context on build
]
covdefaults.subtract_omit = "*/__main__.py"
report.exclude_also = [
  "if typing.TYPE_CHECKING:",
]
paths.build = [
  "src",
  "*/site-packages",
  '*\site-packages',
]
html.show_contexts = true

[tool.pytest.ini_options]
minversion = "6.0"
addopts = ["-ra", "--strict-config", "--strict-markers"]
log_level = "INFO"
testpaths = ["tests"]
xfail_strict = true
junit_family = "xunit2"
norecursedirs = "tests/integration/*"
markers = [
  "contextvars",
  "isolated",
  "network",
]
filterwarnings = [
  "error",
  "ignore:path is deprecated.:DeprecationWarning",
  "ignore:The --rsyncdir command line argument and rsyncdirs config variable are deprecated.:DeprecationWarning",
  "ignore:check_home argument is deprecated and ignored:DeprecationWarning:",  # PyPy 3.11
  "default:Python 3.14 will, by default, filter extracted tar archives:DeprecationWarning",
  "default:unclosed:ResourceWarning", # Python 3.11 Windows
  "ignore:os.path.commonprefix:DeprecationWarning" # https://github.com/pypa/pyproject-hooks/pull/222
]

[tool.mypy]
files = ["src", "tests", "tasks", "docs"]
exclude = ["tests/packages"]
python_version = "3.10"
native_parser = true
strict = true
disallow_any_explicit = true
disallow_any_decorated = true
disallow_any_unimported = true
disallow_untyped_globals = true
disallow_redefinition = true
warn_unused_configs = true
warn_unreachable = true
enable_error_code = [
  "deprecated",
  "exhaustive-match",
  "ignore-without-code",
  "mutable-override",
  "possibly-undefined",
  "redundant-expr",
  "redundant-self",
  "truthy-bool",
  "truthy-iterable",
  "unimported-reveal",
  "unused-awaitable",
]

[[tool.mypy.overrides]]
module = [
  "virtualenv", # Optional dependency
]
ignore_missing_imports = true

[tool.ruff]
exclude = [
  "tests/packages/*/pyproject.toml",
  "tests/packages/test-bad-syntax",
]
line-length = 127
show-fixes = true

[tool.ruff.format]
quote-style = "single"

[tool.ruff.lint]
select = ["ALL"]
ignore = [
  "A002",    # Arguments can shadow builtins
  "ANN401",  # Disallow Any
  "BLE001",  # Blind exceptions are fine if re-raised or passed on
  "COM812",  # Trailing commas teach the formatter
  "CPY001",  # No copyright notice at top of file
  "D",       # Too many doc requests
  "ERA",     # Commented out code
  "FBT",     # Boolean trap hard to fix on existing API
  "N818",    # Using Exception suffix
  "PLC0415", # Import should be at top of file
  "PLR09",   # Too many ...
  "PLR2004", # Magic values
  "PTH",     # Too many change for now
  "Q",       # Using formatter for quotes
  "S101",    # Assert is used by the type checker and pytest
  "SLF001",  # Private members are okay to access
]



[tool.ruff.lint.flake8-tidy-imports.banned-api]
"typing.TYPE_CHECKING".msg = "Use TYPE_CHECKING=False instead"
"os.path.commonprefix".msg = "Use os.path.commonpath or manually implement string manip"

[tool.ruff.lint.per-file-ignores]
"tasks/**.py" = ["T20", "INP", "S607"]
"tests/**.py" = ["TID251", "TC", "T20", "INP", "S"]
"tests/packages/**.py" = ["ANN", "INP", "ARG001"]
"docs/**.py" = ["INP", "A001"]

[tool.ruff.lint.mccabe]
max-complexity = 10

[tool.ruff.lint.isort]
lines-between-types = 1
lines-after-imports = 2

[tool.check-wheel-contents]
ignore = [
  "W005",  # We _are_ build
]

[tool.repo-review.ignore]
PC140 =  "type checker in tox"


[tool.towncrier]
name = "build"
filename = "CHANGELOG.rst"
directory = "docs/changelog"
title_format = false
issue_format = ":issue:`{issue}`"
template = "docs/changelog/template.jinja2"
underlines = ["#", "*", "=", "-"]

[[tool.towncrier.section]]
path = ""

[[tool.towncrier.type]]
directory = "feature"
name = "Features"
showcontent = true

[[tool.towncrier.type]]
directory = "bugfix"
name = "Bugfixes"
showcontent = true

[[tool.towncrier.type]]
directory = "doc"
name = "Documentation"
showcontent = true

[[tool.towncrier.type]]
directory = "removal"
name = "Removals"
showcontent = true

[[tool.towncrier.type]]
directory = "deprecation"
name = "Deprecations"
showcontent = true

[[tool.towncrier.type]]
directory = "misc"
name = "Miscellaneous"
showcontent = false

[tool.bumpversion]
current_version = "1.0.0"

[[tool.bumpversion.files]]
filename = "pyproject.toml"
search = 'version = "{current_version}"'

[[tool.bumpversion.files]]
filename = "src/build/__init__.py"
search = "__version__ = '{current_version}'"
