content: [build-system]
  requires = ["setuptools", "wheel"]
  build-backend = "setuptools.build_meta"
  
  [project]
  name = "custodian"
  version = "2025.10.11"
  description = "A simple JIT job management framework in Python."
  authors = [
      { name = "Janosh Riebesell", email = "janosh.riebesell@gmail.com" },
      { name = "Matthew Horton" },
      { name = "Samuel M. Blau" },
      { name = "Shyue Ping Ong", email = "ongsp@ucsd.edu" },
      { name = "Stephen Dacek" },
      { name = "William Davidson Richards" },
      { name = "Xiaohui Qu" },
      { name = "Andrew Rosen", email = "asrosen@princeton.edu" },
  ]
  maintainers = [{ name = "Shyue Ping Ong" }]
  readme = "README.md"
  keywords = ["jit", "job", "just-in-time", "management", "vasp", "nwchem", "qchem"]
  classifiers = [
      "Development Status :: 5 - Production/Stable",
      "Intended Audience :: Science/Research",
      "License :: OSI Approved :: MIT License",
      "Operating System :: OS Independent",
      "Programming Language :: Python :: 3 :: Only",
      "Programming Language :: Python :: 3",
      "Programming Language :: Python :: 3.10",
      "Programming Language :: Python :: 3.11",
      "Topic :: Scientific/Engineering :: Chemistry",
      "Topic :: Scientific/Engineering :: Physics",
      "Topic :: Software Development :: Libraries :: Python Modules",
  ]
  license = { text = "MIT" }
  requires-python = ">=3.10"
  
  dependencies = ["monty>=2.0.6", "psutil", "ruamel.yaml>=0.15.6"]
  
  [project.optional-dependencies]
  matsci = ["pymatgen"]  # Error handlers and jobs for materials simulations, e.g., VASP, Nwchem, qchem, etc.
  gaussian = ["pymatgen", "matplotlib"]
  error-statistics = ["sentry-sdk>=0.8.0"]
  
  [project.scripts]
  cstdn = "custodian.cli.cstdn:main"
  run_vasp = "custodian.cli.run_vasp:main"
  run_nwchem = "custodian.cli.run_nwchem:main"
  converge_kpoints = "custodian.cli.converge_kpoints:main"
  converge_geometry = "custodian.cli.converge_geometry:main"
  
  [project.urls]
  Docs = "https://materialsproject.github.io/custodian"
  Repo = "https://github.com/materialsproject/custodian"
  Package = "https://pypi.org/project/custodian"
  
  [tool.setuptools.packages.find]
  where = ["src"]
  include = ["custodian*"]
  
  [tool.ruff]
  line-length = 120
  
  [tool.ruff.lint]
  select = [
      "B", # flake8-bugbear
      "C4", # flake8-comprehensions
      "D", # pydocstyle
      "E", # pycodestyle error
      "EXE", # flake8-executable
      "F", # pyflakes
      "FA", # flake8-future-annotations
      "FLY", # flynt
      "I", # isort
      "ICN", # flake8-import-conventions
      "ISC", # flake8-implicit-str-concat
      "PD", # pandas-vet
      "PERF", # perflint
      "PIE", # flake8-pie
      "PL", # pylint
      "PT", # flake8-pytest-style
      "PYI", # flakes8-pyi
      "Q", # flake8-quotes
      "RET", # flake8-return
      "RSE", # flake8-raise
      "RUF", # Ruff-specific rules
      "SIM", # flake8-simplify
      "SLOT", # flake8-slots
      "TCH", # flake8-type-checking
      "TID", # tidy imports
      "TID", # flake8-tidy-imports
      "UP", # pyupgrade
      "W", # pycodestyle warning
      "YTT", # flake8-2020
  ]
  ignore = [
      "B023", # Function definition does not bind loop variable
      "B028", # No explicit stacklevel keyword argument found
      "B904", # Within an except clause, raise exceptions with ...
      "C408", # unnecessary-collection-call
      "COM812",
      "D105", # Missing docstring in magic method
      "D205", # 1 blank line required between summary line and description
      "D212", # Multi-line docstring summary should start at the first line
      "ISC001",
      "PD011", # pandas-use-of-dot-values
      "PD901", # pandas-df-variable-name
      "PERF203", # try-except-in-loop
      "PLR", # pylint refactor
      "PLW2901", # Outer for loop variable overwritten by inner assignment target
      "PT013", # pytest-incorrect-pytest-import
      "PTH",
      "RUF012", # Disable checks for mutable class args
      "SIM105", # Use contextlib.suppress(OSError) instead of try-except-pass
  ]
  pydocstyle.convention = "google"
  isort.split-on-trailing-comma = false
  
  [tool.ruff.lint.per-file-ignores]
  "__init__.py" = ["F401"]
  "tests/*" = ["D", "S101"]
  "tasks.py" = ["D", "E"]
  
  [tool.pytest.ini_options]
  addopts = "--color=yes -p no:warnings --import-mode=importlib"
  
  [tool.mypy]
  ignore_missing_imports = true
  namespace_packages = true
  explicit_package_bases = true
  no_implicit_optional = false
  
  [tool.codespell]
  ignore-words-list = "ot,atomate"
  check-filenames = true
  
  [tool.coverage.run]
  relative_files = true
  
  [tool.coverage.report]
  exclude_lines = [
      "@deprecated",
      "def __repr__",
      "if 0:",
      "if TYPE_CHECKING:",
      "if __name__ == .__main__.:",
      "if self.debug:",
      "if settings.DEBUG",
      "input",
      "pragma: no cover",
      "raise AssertionError",
      "raise NotImplementedError",
  ]
  
  [tool.pyright]
  typeCheckingMode = "off"
  reportPossiblyUnboundVariable = true
  reportUnboundVariable = true
  reportMissingImports = false
  reportMissingModuleSource = false
  reportInvalidTypeForm = false
  exclude = ["**/tests"]
  
  [dependency-groups]
  dev = [
      "pre-commit>=4.2.0",
      "pymatgen>=2025.5.16",
      "pytest>=8.3.5",
      "pytest-cov>=6.0.0",
      "mypy>=1.15.0",
      "ruff>=0.11.2",
      "invoke>=2.2.0",
      "sphinx>=8.1.3",
      "myst-parser>=4.0.1",
      "sphinx-markdown-builder>=0.6.8",
  ]
  lint = [
      "pre-commit>=4.2.0",
      "mypy>=1.15.0",
      "ruff>=0.11.2",
  ]
  
  [tool.setuptools.package-data]
  custodian = ["py.typed"]
  