[build-system]
requires = ["scikit-build-core >=0.11.2"]
build-backend = "scikit_build_core.build"

[project]
name = "pybind11"
description = "Seamless operability between C++11 and Python"
authors = [{name = "Wenzel Jakob", email = "wenzel.jakob@epfl.ch"}]
license = "BSD-3-Clause"
license-files = ["LICENSE"]
readme = "README.rst"
classifiers = [
    "Development Status :: 5 - Production/Stable",
    "Intended Audience :: Developers",
    "Topic :: Software Development :: Libraries :: Python Modules",
    "Topic :: Utilities",
    "Programming Language :: C++",
    "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",
    "Programming Language :: Python :: 3.13",
    "Programming Language :: Python :: 3.14",
    "Programming Language :: Python :: Implementation :: PyPy",
    "Programming Language :: Python :: Implementation :: CPython",
    "Programming Language :: C++",
    "Topic :: Software Development :: Libraries :: Python Modules",
]
keywords = [
    "C++11",
    "Python bindings",
]
dynamic = ["version", "optional-dependencies"]
requires-python = ">=3.8"

[project.urls]
Homepage = "https://github.com/pybind/pybind11"
Documentation = "https://pybind11.readthedocs.io/"
"Issue Tracker" = "https://github.com/pybind/pybind11/issues"
Discussions = "https://github.com/pybind/pybind11/discussions"
Changelog = "https://pybind11.readthedocs.io/en/latest/changelog.html"
Chat = "https://gitter.im/pybind/Lobby"

[project.scripts]
pybind11-config = "pybind11.__main__:main"

[project.entry-points."pipx.run"]
pybind11 = "pybind11.__main__:main"

[project.entry-points.pkg_config]
pybind11 = "pybind11.share.pkgconfig"


[dependency-groups]
test = [
  "pytest",
  "build",
  "tomlkit",
]
dev = [{ include-group = "test" }]


[tool.scikit-build]
minimum-version = "build-system.requires"
sdist.exclude = [
  "/docs/**",
  "/.**",
]
wheel.install-dir = "pybind11"
wheel.platlib = false

[tool.scikit-build.cmake.define]
BUILD_TESTING = false
PYBIND11_NOPYTHON = true
prefix_for_pc_file = "${pcfiledir}/../../"

[tool.scikit-build.metadata.version]
provider = "scikit_build_core.metadata.regex"
input = "include/pybind11/detail/common.h"
regex = '''(?sx)
\#define \s+ PYBIND11_VERSION_MAJOR \s+ (?P<major>\d+) .*?
\#define \s+ PYBIND11_VERSION_MINOR \s+ (?P<minor>\d+) .*?
\#define \s+ PYBIND11_VERSION_PATCH \s+ (?P<patch>\S+)
'''
result = "{major}.{minor}.{patch}"

[tool.scikit-build.metadata.optional-dependencies]
provider = "scikit_build_core.metadata.template"
result = { global = ["pybind11-global=={project[version]}"]}

[[tool.scikit-build.generate]]
path = "pybind11/_version.py"
template = '''
from __future__ import annotations


def _to_int(s: str) -> int | str:
    try:
        return int(s)
    except ValueError:
        return s


__version__ = "$version"
version_info = tuple(_to_int(s) for s in __version__.split("."))
'''


[tool.uv]
# Can't use tool.uv.sources with requirements.txt
index-strategy = "unsafe-best-match"
# This extra confuses uv
override-dependencies = ["pybind11-global"]


[tool.mypy]
files = ["pybind11"]
python_version = "3.8"
strict = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
warn_unreachable = true

[[tool.mypy.overrides]]
module = ["ghapi.*", "tomlkit"]  # tomlkit has types, but not very helpful
ignore_missing_imports = true


[tool.pylint]
master.py-version = "3.8"
reports.output-format = "colorized"
messages_control.disable = [
  "design",
  "fixme",
  "imports",
  "line-too-long",
  "imports",
  "invalid-name",
  "protected-access",
  "missing-module-docstring",
  "unused-argument",  # covered by Ruff ARG
  "consider-using-f-string", # triggers in _version.py incorrectly
]

[tool.ruff.lint]
extend-select = [
  "B",           # flake8-bugbear
  "I",           # isort
  "N",           # pep8-naming
  "ARG",         # flake8-unused-arguments
  "C4",          # flake8-comprehensions
  "EM",          # flake8-errmsg
  "ICN",         # flake8-import-conventions
  "ISC",         # flake8-implicit-str-concat
  "PERF",        # Perflint
  "PGH",         # pygrep-hooks
  "PIE",         # flake8-pie
  "PL",          # pylint
  "PT",          # flake8-pytest-style
  "RET",         # flake8-return
  "RUF100",      # Ruff-specific
  "SIM",         # flake8-simplify
  "UP",          # pyupgrade
  "YTT",         # flake8-2020
]
ignore = [
  "PLR",     # Design related pylint
  "PT011",   # Too broad with raises in pytest
  "SIM118",  # iter(x) is not always the same as iter(x.keys())
  "PLC0415", # We import in functions for various reasons
]
isort.known-first-party = ["env", "pybind11_cross_module_tests", "pybind11_tests"]
isort.required-imports = ["from __future__ import annotations"]


[tool.ruff.lint.per-file-ignores]
"tests/**" = [
  "EM",
  "N",
  "E721",
]
"tests/test_call_policies.py" = ["PLC1901"]

[tool.repo-review]
ignore = ["PP"]

[tool.typos]
files.extend-exclude = ["/cpython"]

[tool.typos.default.extend-identifiers]
ser_no = "ser_no"
SerNo = "SerNo"
StrLits = "StrLits"

[tool.typos.default.extend-words]
nd = "nd"
valu = "valu"
fo = "fo"
quater = "quater"
optin = "optin"
othr = "othr"

#[tool.typos.type.cpp.extend-words]
setp = "setp"
ot = "ot"

[tool.typos.type.json.extend-words]
ba = "ba"
