content: [build-system]
  requires = ["setuptools>=68.2.2"]
  build-backend = "setuptools.build_meta"
  
  [project]
  name = "xocto"
  version = "8.5.1"
  requires-python = ">=3.9"
  description = "Kraken Technologies Python service utilities"
  readme = "README.md"
  authors = [
    {name = "Kraken Technologies", email = "talent@octopus.energy"},
  ]
  maintainers = [
    {name = "Kraken Technologies", email = "talent@octopus.energy"},
  ]
  classifiers = [
    "Development Status :: 5 - Production/Stable",
    "Intended Audience :: Developers",
    "Topic :: Software Development :: Build Tools",
    "License :: OSI Approved :: MIT License",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
  ]
  license = {text = "MIT"}
  dependencies = [
    "duckdb>=0.9.0",
    "django>=4.0",
    "openpyxl>=3.1.0",
    "pact-python>=1.6.0",
    "pandas>=1.5.3",
    "pyarrow>=11.0.0",
    "python-dateutil>=2.8.2",
    "python-magic>=0.4.27",
    "pytz",
    "structlog>=20.2.0",
    "typing-extensions>=4.12.2",
    "xlrd>=2.0.1",
  ]
  
  [project.optional-dependencies]
  dev = [
    "boto3==1.26.53",
    "botocore==1.29.53",
    "hypothesis==6.62.1",
    "moto[s3,sqs]==4.1",
    "mypy-boto3-s3==1.34.120",
    "mypy==1.10.0",
    "numpy==2.0.0",
    "pre-commit>=3.7.1",
    "psycopg2>=2.8.4",
    "pyarrow-stubs==10.0.1.6",
    "pytest-benchmark==5.0.1",
    "pytest-django==4.8.0",
    "pytest-mock==3.12.0",
    "pytest==8.0.2",
    "ruff==0.4.9",
    "time-machine==2.14.1",
    "twine==4.0.2",
    "types-openpyxl==3.0.4.5",
    "types-python-dateutil==2.8.19.20240106",
    "types-pytz==2024.1.0.20240203",
    "types-requests==2.28.11.8",
    "wheel==0.38.4",
  ]
  docs = [
    "Sphinx==7.2.6",
    "myst-parser==2.0.0",
    "sphinxcontrib-serializinghtml==1.1.10",
    "sphinx-rtd-theme==2.0.0",
  ]
  
  [project.urls]
  changelog = "https://github.com/octoenergy/xocto/blob/main/CHANGELOG.md"
  documentation = "https://xocto.readthedocs.io"
  issues = "https://github.com/octoenergy/xocto/issues"
  
  [tool.setuptools.packages.find]
  include = ["xocto*"]
  namespaces = false
  
  [tool.setuptools.package-data]
  "xocto" = ["py.typed"]
  
  
  # Mypy
  # ----
  
  [tool.mypy]
  # Specify which files to check.
  files = [
    "xocto",
    "tests",
    "*.py",
  ]
  
  # Output.
  show_error_codes = true
  
  # Strict mode; enables the following flags:
  #   --check-untyped-defs
  #   --disallow-any-generics,
  #   --disallow-incomplete-defs
  #   --disallow-subclassing-any
  #   --disallow-untyped-calls
  #   --disallow-untyped-decorators,
  #   --disallow-untyped-defs,
  #   --no-implicit-reexport
  #   --strict-concatenate
  #   --strict-equality
  #   --warn-redundant-casts
  #   --warn-return-any
  #   --warn-unused-configs
  #   --warn-unused-ignores
  strict = true
  
  # These flags enabled by `strict` are ones we're overriding.
  disallow_subclassing_any = false
  warn_return_any = false
  
  # Enable the following optional checks.
  enable_error_code = [
    "ignore-without-code",
    "redundant-expr",
    "truthy-bool",
    "unused-awaitable",
  ]
  
  # Warnings.
  warn_unreachable = true
  
  # Don't force test functions to include types.
  [[tool.mypy.overrides]]
  module = [
    "tests.*",
  ]
  disallow_untyped_defs = false
  check_untyped_defs = false
  
  # Ignore errors from packages that don't have type annotations.
  [[tool.mypy.overrides]]
  module = [
    "boto3.*",
    "botocore.*",
    "django.*",
    # TODO: Remove after https://github.com/duckdb/duckdb-python/issues/57 is resolved
    "duckdb.*",
    "moto.*",
    "pact.*",
    "pandas.*",
    "setuptools.*",
    "xlrd.*",
    "zoneinfo.*",
  ]
  ignore_missing_imports = true
  
  
  # Ruff
  # ----
  
  [tool.ruff.lint]
  select = [
      "E",  # pycodestyle
      "F",  # pyflakes
      "I",  # isort
  ]
  ignore = [
      "E501",  # line too long
  ]
  
  [tool.ruff.lint.per-file-ignores]
  # Allow unused imports in __init__ files as these are convenience imports
  "**/__init__.py" = [ "F401" ]
  
  [tool.ruff.lint.isort]
  lines-after-imports = 2
  section-order = [
      "future",
      "standard-library",
      "third-party",
      "first-party",
      "project",
      "local-folder",
  ]
  
  [tool.ruff.lint.isort.sections]
  "project" = [
      "xocto",
      "tests",
  ]
  
  
  # Pytest
  # ------
  
  [tool.pytest.ini_options]
  # Convert some warning types into errors but ignore some others that we
  # can't/won't fix right now.
  #
  # Note:
  # - Each line is a colon-separated string.
  # - The first part is what to do with the warning - error or ignore.
  # - The second part is a regex that must match the start of the warning message.
  # - The third part is the warning class name.
  # - The fourth part is a regex that must match the module triggering the error.
  # - The order matters. These rules get applied with the bottom rule first.
  #   Hence the rules ignoring deprecation warnings must by below the rule that converts
  #   DeprecationWarnings into errors.
  filterwarnings = [
      "error::RuntimeWarning",
      "error::DeprecationWarning",
      "ignore:defusedxml.lxml:DeprecationWarning:zeep",
      "ignore:Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3:DeprecationWarning:(graphene|singledispatch)",
      # https://github.com/ktosiek/pytest-freezegun/issues/35
      "ignore:distutils Version classes are deprecated:DeprecationWarning:pytest_freezegun",
  ]
  
  DJANGO_SETTINGS_MODULE = "tests.settings"
  
  # Test modules must have be named this way.
  python_files = ["test_*.py", "benchmark_*.py"]
  python_functions = ["test_*", "benchmark_*"]
  python_classes = ["Test*", "Benchmark*"]
  
  # Default options when pytest is run:
  #
  #   --verbose      -> Show names of tests being run.
  #   --tb=short     -> Use short tracebacks.
  #                     https://docs.pytest.org/en/stable/usage.html#modifying-python-traceback-printing
  #   --nomigrations -> Disable Django's migrations and create the database by inspecting models instead.
  #                     https://pytest-django.readthedocs.io/en/latest/database.html#nomigrations-disable-django-migrations
  #   --reuse-db     -> Don't remove test database after each test run so it can be re-used next time.
  #                     https://pytest-django.readthedocs.io/en/latest/database.html#reuse-db-reuse-the-testing-database-between-test-runs
  #   --color=auto   -> Detect whether to print colored output.
  #   --capture=fd   -> Capture all output written to the STDOUT and STDERR file descriptors.
  #                     https://docs.pytest.org/en/stable/capture.html
  #
  addopts = "--tb=short --verbose --nomigrations --reuse-db --color=auto --capture=fd"
  