content: # Copyright (c) "Neo4j"
  # Neo4j Sweden AB [https://neo4j.com]
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     https://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  [project]
  name = "neo4j"
  description = "Neo4j Bolt driver for Python"
  license = "Apache-2.0 AND Python-2.0"
  license-files = [
      "LICENSE*.txt",
      "NOTICE*.txt",
  ]
  readme = "README.rst"
  authors = [
      {name = "Neo4j, Inc.", email = "drivers@neo4j.com"},
  ]
  dependencies = ["pytz"]
  requires-python = ">=3.10"
  keywords = ["neo4j", "graph", "database"]
  classifiers = [
      "Development Status :: 5 - Production/Stable",
      "Framework :: AsyncIO",
      "Intended Audience :: Developers",
      "Operating System :: OS Independent",
      "Programming Language :: Python :: 3.10",
      "Programming Language :: Python :: 3.11",
      "Programming Language :: Python :: 3.12",
      "Programming Language :: Python :: 3.13",
      "Topic :: Database",
      "Topic :: Software Development",
      "Typing :: Typed",
  ]
  dynamic = ["version"]
  
  [project.urls]
  Homepage = "https://neo4j.com/"
  Repository = "https://github.com/neo4j/neo4j-python-driver"
  "Docs (Manual)" = "https://neo4j.com/docs/python-manual/current/"
  "Docs (API Reference)" = "https://neo4j.com/docs/api/python-driver/current/"
  "Issue Tracker" = "https://github.com/neo4j/neo4j-python-driver/issues"
  Changelog = "https://github.com/neo4j/neo4j-python-driver/wiki"
  Forum = "https://community.neo4j.com/c/drivers-stacks/python/"
  Discord = "https://discord.com/invite/neo4j"
  
  [project.optional-dependencies]
  numpy = ["numpy >= 1.21.2, < 3.0.0"]
  pandas = [
      "pandas >= 1.1.0, < 3.0.0",
      "numpy >= 1.21.2, < 3.0.0",
  ]
  pyarrow = ["pyarrow >= 6.0.0, < 22.0.0"]
  
  
  [build-system]
  requires = [
      "setuptools == 80.9.0",
  ]
  build-backend = "setuptools.build_meta"
  
  [dependency-groups]
  # To install all development dependencies as well as the driver with all optional dependencies,
  # run `pip install --group dev -e .` inside repository root folder.
  dev = [
      # dev tools
      {include-group = "dep-project-dependencies"},
      {include-group = "tox"},
      {include-group = "precommit"},
      {include-group = "unasync"},
      {include-group = "test"},
      {include-group = "typing"},
      {include-group = "docs"},
      {include-group = "testkit"},
      {include-group = "benchkit"},
      {include-group = "packaging"},
      {include-group = "release"},
  ]
  # tool for runnig test matrix
  tox = ["tox >= 4.30.2"]
  # run pre-commit hooks (includes linting, formatting, type checking, ...)
  precommit = [
      "pre-commit >= 4.3.0",
      # runs unasync and type checker outside pre-commit's isolation
      {include-group = "unasync"},
      {include-group = "typing"},
  ]
  # auto-generate sync driver from async code
  unasync = [
      "unasync == 0.5.0",
      "isort >= 6.0.1",
  ]
  # dependencies for running tests
  test = [
      "coverage[toml] >= 7.10.7",
      {include-group = "dep-freezegun"},
      "mock >= 5.2.0",
      "pytest >= 8.4.2",
      "pytest-asyncio >= 1.2.0",
      "pytest-benchmark >= 5.1.0",
      "pytest-cov >= 7.0.0",
      "pytest-mock >= 3.15.1",
  ]
  # type checker and type stubs for static type checking
  typing = [
      "mypy >= 1.18.2",
      "types-pytz >= 2025.2.0.20250809",
      {include-group = "dep-typing-extensions"},
      {include-group = "dep-project-dependencies"},
      # tests are also type-checked
      {include-group = "test"},
      # testkit backend is also type-checked
      {include-group = "testkit"},
      # benchkit backend is also type-checked
      {include-group = "benchkit"},
  ]
  # generate documentation
  docs = [
      "Sphinx >= 8.2.3",
      {include-group = "dep-typing-extensions"},
      {include-group = "dep-project-dependencies"},
  ]
  # running the testkit backend
  testkit = [
      {include-group = "dep-freezegun"},
  ]
  # running the benchkit backend for benchmarking
  benchkit = ["sanic >= 25.3.0"]
  # building and packaging the driver
  packaging = [
      "build >= 1.3.0",
  ]
  # releasing the packaged driver to PyPI
  release = [
      "twine >= 6.2.0",
  ]
  
  # single dependencies and other include-groups (not really meant to be installed as a group, but to avoid duplication)
  dep-typing-extensions = ["typing-extensions >= 4.15.0"]
  dep-freezegun = ["freezegun >= 1.5.5"]
  dep-project-dependencies = [
      "pytz",
      "numpy >= 1.7.0, < 3.0.0",
      "pandas >= 1.1.0, < 3.0.0",
      "pyarrow >= 6.0.0, < 22.0.0",
  ]
  
  [tool.setuptools.dynamic]
  version = {attr = "neo4j._meta.version"}
  
  
  [tool.coverage]
  show_missing = true
  
  [tool.coverage.run]
  branch = true
  omit = [
      ".*/*",
      "tests/*",
      "src/neo4j/meta.py",
      "*virtualenv*",
      "*venv*",
  ]
  
  [tool.coverage.report]
  exclude_lines = [
      "pragma: no cover",
      "def __repr__",
      "if self.debug:",
      "raise NotImplementedError",
      "if __name__ == .__main__.:",
      "except ImportError",
  ]
  
  
  [tool.isort]
  combine_as_imports = true
  ensure_newline_before_comments = true
  force_grid_wrap = 2
  # breaks order of relative imports
  # https://github.com/PyCQA/isort/issues/1944
  #force_sort_within_sections = true
  include_trailing_comma = true
  # currently broken
  # https://github.com/PyCQA/isort/issues/1855
  #lines_before_imports = 2
  lines_after_imports = 2
  lines_between_sections = 1
  multi_line_output = 3
  order_by_type = false
  remove_redundant_aliases = true
  use_parentheses = true
  
  
  [tool.pytest.ini_options]
  mock_use_standalone_module = true
  asyncio_mode = "strict"
  asyncio_default_fixture_loop_scope="function"
  
  
  [tool.mypy]
  
  [[tool.mypy.overrides]]
  module = [
      "pandas.*",
      "pyarrow.*",
      "neo4j._rust",
      "neo4j._rust.*",
  ]
  ignore_missing_imports = true
  
  [tool.ruff]
  line-length = 79
  extend-exclude = [
      "src/neo4j/_sync",
      "tests/unit/sync",
      "tests/integration/sync",
      "testkitbackend/_sync",
  ]
  
  [tool.ruff.lint]
  preview = true  # to get CPY lints
  typing-modules = ["neo4j._typing"]
  extend-ignore = [
      "RUF002",  # allow ’ (RIGHT SINGLE QUOTATION MARK) to be used as an apostrophe (e.g. "it’s")
  
      # pydocstyle
      "D1",   # disable check for undocumented items (way too noisy)
      "D203", # `one-blank-line-before-class`
      "D212", # `multi-line-summary-first-line`
  
      # comprehensions
      "C417", # map is ok, no need to rewrite to list comprehension
  
      # too noisy and opinionated pytest lints
      "PT007",
      "PT011",
      "PT012",
      "PT018",
  
      # too noisy and opinionated pylint lints
      "PLC0415",
      "PLC1901",
      "PLC2401",
      "PLC2701",
      "PLR09",
      "PLR1702",
      "PLR1704",
      "PLR2004",
      "PLR6301",
      "PLW2901",
      "PLW1641",
  
      # too noisy and opinionated tryceratops lints
      "TRY003",
      "TRY300",
      "TRY301",
      "TRY400",
  
      # too noisy and opinionated return statement lints
      "RET505",
      "RET506",
      "RET507",
      "RET508",
  
      # prefer to not use forward references in typing.cast calls
      # (worse IDE support => worse DX)
      "TC006",
  
      "PERF203",  # try-except within loop is fine. Especially in a retry scenario
  
      # too noisy and opinionated FURB lints
      "FURB113",
      "FURB118",
      "FURB140",
      "FURB154",
      # needs fixing in ruff to work with typing.Protocol
      # https://github.com/astral-sh/ruff/issues/13307
      "FURB180",
  
      # rule is deprected and suggests not recommended practice
      "UP038",
  ]
  select = [
      # ruff
      "RUF",
      # pycodestyle
      "E",
      "W",
      # Pyflakes
      "F",
      # pyupgrade
      "UP",
      # flake8-bugbear
      "B",
      # flake8-simplify
      "SIM",
      # pep8-naming
      "N",
      # pydocstyle
      "D",
      # pydocstyle: explicit rules not selected by the chosen convention
      "D404",
      # Does not yet fully support sphinx style docstrings
      # https://github.com/astral-sh/ruff/pull/13286
      # # pydoclint
      # "DOC",
      # pylint
      "PL",
      # tryceratops
      "TRY",
      # flynt
      "FLY",
      # Perflint
      "PERF",
      # refurb
      "FURB",
      # async checks
      "ASYNC",
      # check comprehensions
      "C4",
      # check for left-over debugger calls
      "T100",
      # check for left-over print calls
      "T20",
      # qoute styles
      "Q",
      # check for unnecessary parantheses in raise statements
      "RSE",
      # check return statements
      "RET",
      # check type-checking usage
      "TC",
      # copyright notice
      "CPY",
      # check shebangs
      "EXE",
      # logging calls + formats
      "LOG",
      "G",
      # flake8-pie
      "PIE",
      # pytest lints
      "PT",
  ]
  
  [tool.ruff.lint.per-file-ignores]
  "{testkit,testkitbackend,benchkit}/**" = [
      "T20",  # print statements are ok in the testing infrastructure
  ]
  "tests/integration/examples/**" = [
      "T20",  # print statements are part of the examples
      "LOG015",  # examples are simplified => they may use non-polished logging calls
  ]
  "tests/unit/**" = [
      "PLW1641",  # no need for production grade test code
      "FURB152",  # don't tell us to use math.pi, when all we need is just some random float
  ]
  "{tests/unit,testkitbackend}/**" = [
      # allow async functions without await to enable type checking, pretending to be async, matching type signatures
      "RUF029",
  ]
  "tests/**" = [
      "B011",  # allow `assert False` in tests, they won't be run with -O anyway
  ]
  "bin/**" = [
      "T20",  # print statements are ok in our helper scripts
  ]
  
  [tool.ruff.lint.pycodestyle]
  max-doc-length = 83 # 79 (max line length) + 4 indentation of code blocks
  
  [tool.ruff.lint.pep8-naming]
  extend-ignore-names = ["mcs"]
  
  [tool.ruff.lint.flake8-copyright]
  notice-rgx = "# Copyright \\(c\\) \"Neo4j\""
  
  [tool.ruff.lint.pydocstyle]
  convention = "pep257"
  
  [tool.ruff.lint.flake8-pytest-style]
  warns-extend-require-match-for = ["neo4j.warning.PreviewWarning"]
  