content: [build-system]
  requires = ["hatchling", "versioningit"]
  build-backend = "hatchling.build"
  
  [project]
  name = "zospy"
  authors = [
      { name = "Luc van Vught" },
      { name = "Jan-Willem Beenakker" },
      { name = "Corné Haasjes" },
  ]
  maintainers = [{ name = "MReye research group", email = "zospy@mreye.nl" }]
  
  description = "A Python package used to communicate with Zemax OpticStudio through the API"
  readme = "README.md"
  license = { file = "LICENSE.txt" }
  keywords = ["Zemax", "OpticStudio", "API", "ZOSAPI"]
  classifiers = [
      "Development Status :: 5 - Production/Stable",
      "Programming Language :: Python :: 3",
      "Typing :: Typed",
  ]
  requires-python = ">=3.10,<3.14"
  dependencies = [
      "lark ~= 1.2.0",
      "pythonnet >=3.0.0,<4",
      "pandas",
      "pydantic >= 2.4.0",
      "numpy",
      "semver >= 3.0.0,<4",
      "typing_extensions; python_version <= '3.10'",
  ]
  dynamic = ["version"]
  
  [project.urls]
  Source = "https://github.com/MREYE-LUMC/ZOSPy"
  Documentation = "https://mreye-lumc.github.io/ZOSPy"
  
  [project.optional-dependencies]
  docs = [
      "ipython",
      "myst-parser",
      "nbsphinx",
      "numpydoc",
      "sphinx",
      "sphinx-book-theme",
      "sphinx-design",
  ]
  
  ### Hatch configuration
  
  [tool.hatch.version]
  source = "versioningit"
  default-version = "0.0.0+unknown"
  
  [tool.hatch.envs.default]
  python = "3.12"
  installer = "uv"
  path = ".venv"
  dependencies = ["pytest"]
  
  
  [tool.hatch.envs.default.scripts]
  test-extension = "hatch test --extension {args}"
  
  # Build and serve documentation
  docs = ["hatch run docs:build", "hatch run docs:serve"]
  
  # Run examples using the development version of ZOSPy
  example = "{env:HATCH_UV:uv} run --isolated scripts/run_examples/run_single_example.py {args} --zospy-location ."
  all-examples = "{env:HATCH_UV:uv} run --isolated scripts/run_examples/run_all_examples.py {args:examples} --zospy-location ."
  
  # Format docstrings according to numpydoc
  format-docstrings = "{env:HATCH_UV:uv} tool uvx pydocstringformatter --write {args:examples scripts tests zospy}"
  
  # Generate reference data for unit tests
  generate-reference-data = "hatch run reference-data:generate"
  
  ## Unit testing using hatch test
  [tool.hatch.envs.hatch-test]
  randomize = false
  retries = 0
  
  [[tool.hatch.envs.hatch-test.matrix]]
  python = ["3.13", "3.12", "3.11", "3.10"]
  
  ## Documentation
  [tool.hatch.envs.docs]
  installer = "uv"
  features = ["docs"]
  
  [tool.hatch.envs.docs.scripts]
  # Build documentation; run as hatch run docs:build
  build = "sphinx-build -M {args:html} ./docs ./docs/_build"
  # Serve documentation locally; run as hatch run docs:serve
  serve = "python -m http.server -d ./docs/_build/html {args:8888}"
  
  ## Examples
  [tool.hatch.envs.examples]
  installer = "uv"
  dependencies = ["jupyter", "matplotlib", "numpy", "pandas", "pip"]
  
  ## Test reference data generation
  [tool.hatch.envs.reference-data]
  dependencies = ["pyyaml"]
  
  [tool.hatch.envs.reference-data.scripts]
  generate = "python scripts/generate_test_reference_data {args}"
  
  ## Formatting using hatch fmt
  [tool.hatch.envs.hatch-static-analysis]
  config-path = "ruff_defaults.toml"
  dependencies = ["ruff==0.11.5"]
  
  # Linting and formatting options
  [tool.ruff]
  extend = "ruff_defaults.toml"
  preview = true
  
  line-length = 120
  extend-include = ["*.ipynb"]
  exclude = [
      "zospy/analyses/old",
  ]
  
  [tool.ruff.lint]
  extend-select = [
      "D",   # pydocstyle
      "NPY", # numpy-specific
      "RUF", # ruff-specific
  ]
  extend-ignore = ["B028", "EM101", "EM102", "G004", "PLR2004", "TD004", "TRY003"]
  allowed-confusables = ["µ"]
  
  [tool.ruff.lint.extend-per-file-ignores]
  "examples/**" = [
      "D",      # pydocstyle
      "FBT002", # Allow positional boolean arguments
      "INP001", # Do not require __init__.py
      "RET504",
      "S101",   # Allow use of assert
      "TCH",    # Do not require type checking blocks
      "T201",   # Allow use of print
  ]
  "**/tests/**" = [
      "D",   # pydocstyle
      "DTZ", # Datetime timezones
  ]
  "scripts/**" = [
      "D",    # pydocstyle
      "S101", # Use of assert
  ]
  "docs/conf.py" = [
      "INP001", # Missing __init__.py
      "D100",   # Missing docstring in public module
      "D103",   # Missing docstring in public function
  ]
  "**/*.ipynb" = [
      "I002",  # Missing required import
  ]
  
  [tool.ruff.lint.flake8-pytest-style]
  parametrize-names-type = "csv"
  
  [tool.ruff.lint.isort]
  required-imports = ["from __future__ import annotations"]
  
  [tool.ruff.lint.pydocstyle]
  convention = "numpy"
  
  [tool.pydocstringformatter]
  style = "numpydoc"
  max-line-length = 120
  max-summary-lines = 1
  summary-quotes-same-line = true
  linewrap-full-docstring = true
  
  [tool.pytest.ini_options]
  markers = [
      "must_pass: test must pass, otherwise all other tests will be skipped",
      "old_analyses: test is part of the old analyses and will be skipped by default",
      "require_mode: requires the specified connection mode, otherwise the test will be skipped",
      "skip_for_opticstudio_versions: test is skipped for specific OpticStudio versions",
      "xfail_for_opticstudio_versions: test is expected to fail for specific OpticStudio versions",
  ]
  filterwarnings = [
      "ignore:Header and row length mismatch",
      "ignore:The `zospy.analyses.old` module contains the deprecated analysis API"
  ]
  
  [tool.mypy]
  files = ["zospy"]
  pretty = true
  
  [[tool.mypy.overrides]]
  module = ["zospy.api._ZOSAPI", "zospy.api._ZOSAPI_constants"]
  ignore_errors = "True"
  