content: # Project metadata, including build by setuptools
  # See https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html
  
  # TOML syntax at https://toml.io/en/
  
  
  [build-system]
  # Minimum requirements for the build system to execute.
  requires = ['setuptools'] # PEP 508 specifications.
  # Setuptools specification
  build-backend = "setuptools.build_meta"
  
  
  [project]
  # See https://packaging.python.org/en/latest/specifications/declaring-project-metadata/
  dynamic = ['version', 'dependencies']
  name = 'airportsdata'
  description = """\
      Extensive database of location and timezone data for nearly every airport and landing strip in the world.\
      """
  readme = { file = 'README.rst', content-type = 'text/x-rst' }
  requires-python = '>=3.9'
  license = { file = 'LICENSE' }
  authors = [{ name = 'Mike Borsetti', email = 'mike+airportsdata@borsetti.com' }]
  maintainers = [
      { name = 'Mike Borsetti', email = 'mike+airportsdata@borsetti.com' },
  ]
  keywords = ['airports', 'aerodromes', 'ICAO', 'IATA']
  classifiers = [
      'Development Status :: 5 - Production/Stable',
      'Intended Audience :: Developers',
      'License :: OSI Approved :: MIT License',
      'Natural Language :: English',
      'Operating System :: OS Independent',
      'Programming Language :: Python',
      'Programming Language :: Python :: 3',
      'Programming Language :: Python :: 3 :: Only',
      'Programming Language :: Python :: 3.10',
      'Programming Language :: Python :: 3.11',
      'Programming Language :: Python :: 3.12',
      'Programming Language :: Python :: 3.13',
      'Programming Language :: Python :: Implementation :: CPython',
      'Typing :: Typed',
  ]
  
  [project.urls]
  Documentation = 'https://github.com/mborsetti/airportsdata/blob/main/README.rst'
  Repository = 'https://github.com/mborsetti/airportsdata/'
  'Database (csv)' = 'https://github.com/mborsetti/airportsdata/blob/main/airportsdata/airports.csv'
  Changelog = 'https://github.com/mborsetti/airportsdata/blob/main/CHANGELOG.rst'
  Issues = 'https://github.com/mborsetti/airportsdata/issues'
  CI = 'https://github.com/mborsetti/airportsdata/actions'
  
  
  # -------------------------- setuptools --------------------------
  # Called by build
  # See https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html
  [tool.setuptools]
  packages = ['airportsdata']
  
  [tool.setuptools.dynamic]
  version = { attr = 'airportsdata.__version__' }
  dependencies = { file = 'requirements.txt' }
  
  [tool.setuptools.package-data]
  'airportsdata' = ['py.typed']
  
  # -------------------------- coverage --------------------------
  # Runs in Github Actions (see .github/workflows/ci-cd.yaml) and in tox (see tox.ini).
  # Config file documentation at https://coverage.readthedocs.io/en/latest/config.html
  [tool.coverage.run]
  branch = true
  source = ['.']
  omit = [
      '.*/*',
      'build/*',
      'dist/*',
      'docs/*',
      'htmlcov/*',
      'pip/*',
      'tests/*',
      'airportsdata.egg-info/*',
  ]
  relative_files = true
  command_line = '-m pytest -v'
  parallel = true
  
  [tool.coverage.report]
  # Regexes for lines to exclude from consideration
  exclude_lines = [
      # Don't complain about missing debug-only code:
      'def __repr__',
      'if self\.debug:',
  
      # Have to re-enable the standard pragma
      'pragma: no cover',
  
      # Don't complain if tests don't hit defensive assertion code:
      'raise AssertionError',
      'raise NotImplementedError',
  
      # Don't complain if non-runnable code isn't run:
      'if 0:',
      'if __name__ == .__main__.:',
  
      # Don't complain if module is not importable (handled by code):
      'except ImportError:',
  
      # Don't cover IDE code:
      'if TYPE_CHECKING:',
  ]
  # ignore_errors = true
  
  
  # -------------------------- pytest --------------------------
  # Testing framework
  # Config file documentation at https://docs.pytest.org/en/stable/reference/reference.html#ini-options-ref
  [tool.pytest.ini_options]
  log_auto_indent = true
  # Enable log display during test run (aka "live logging" https://docs.pytest.org/en/stable/logging.html#live-logs)
  log_cli = true
  minversion = '8.3.3'
  testpaths = ['tests']
  
  # Adds pytest-cov functionality (see https://pytest-cov.readthedocs.io/en/latest/config.html)
  # Note: --cov moved to .github/workflows/ci-cd.yaml and tox.ini due to interference with PyCharm breakpoints (see
  # https://github.com/pytest-dev/pytest-cov/issues/131) and to enable running tox --parallel
  # Instead of below, now runs with $ coverage run --parallel-mode
  # addopts = --cov=./ --cov-report=term --cov-report=html
  
  # -------------------------- mypy --------------------------
  [tool.mypy]
  # Static Typing for Python
  # Runs as part of pre-commit
  # Config file documentation at https://mypy.readthedocs.io/en/stable/config_file.html
  
  # Disables import discovery of namespace packages (see PEP 420)
  # namespace_packages = false
  
  # Top-level packages will be based in either the current directory, or a member of the MYPYPATH environment variable or
  # mypy_path config option. This option is only useful in the absence of __init__.py. See Mapping file paths to modules
  # for details.
  explicit_package_bases = true
  mypy_path = "C:\\users\\mike\\Documents\\python\\git_repos\\webchanges"
  
  # Suppresses error messages about imports that cannot be resolved.
  ignore_missing_imports = false
  
  # Specifies the Python version used to parse and check the target program.
  # python_version = 3.12
  
  # Disallows calling functions without type annotations from functions with type annotations.
  disallow_untyped_calls = true
  
  # Disallows defining functions without type annotations or with incomplete type annotations.
  disallow_untyped_defs = true
  
  # Reports an error whenever a function with type annotations is decorated with a decorator without annotations.
  # disallow_untyped_decorators = true
  
  # Warns about casting an expression to its inferred type.
  warn_redundant_casts = true
  
  # Warns about unneeded # type: ignore comments.
  # May behave differently in GitHub Actions than it does on Windows.
  warn_unused_ignores = true
  
  # Allows disabling one or multiple error codes globally.
  disable_error_code = ["import-not-found", "import-untyped"]
  
  # Shows a warning when returning a value with type Any from a function declared with a non-Any return type.
  warn_return_any = true
  
  # Shows a warning when encountering any code inferred to be unreachable or redundant after performing type analysis.
  warn_unreachable = false
  
  # Enables additional checks that are technically correct but may be impractical in real code.
  extra_checks = true
  
  # Shows documentation link to corresponding error code.
  show_error_code_links = true
  
  # Use visually nicer output in error messages: use soft word wrap, show source code snippets, and show error location
  # markers.
  pretty = true
  
  # Use an SQLite database to store the cache.
  sqlite_cache = true
  
  # Warns about per-module sections in the config file that do not match any files processed when invoking mypy.
  warn_unused_configs = true
  
  # -------------------------- ruff --------------------------
  [tool.ruff]
  # Config file documentation at https://docs.astral.sh/ruff/configuration/
  
  # By default, Ruff will discover files matching *.py, *.pyi, *.ipynb, or pyproject.toml.
  # Include additional files
  # include = []
  
  # Set the maximum line length.
  line-length = 120
  
  # Target Python version
  # target-version = "py311"  # Commented out to infer from [project] requires-python
  
  [tool.ruff.lint]
  # By default, Ruff enables Flake8's F rules, along with a subset of the E rules
  # Enable rules not enabled by default, and ignore specific rules.
  select = [
      "S",   # flake8-bandit
      "BLE", # flake8-blind-except
      "B",   # flake8-bugbear
      "A",   # flake8-builtin
      "C4",  # flake8-comprehensions
      "DTZ", # flake8-datetimez
      # "EM",   # flake8-errmsg
      "FA",  # flake8-future-annotations
      "INT", # flake8-gettext
      "ISC", # flake8-implicit-str-concat
      "LOG", # flake8-logging
      # "G",    # flake8-logging-format
      "PIE", # flake8-pie
      "PYI", # flake8-pyi
      "PT",  # flake8-pytest-style
      "Q",   # flake8-quotes
      "RSE", # flake8-raise
      "RET", # flake8-return
      "SIM", # flake8-simplify
      "TID", # flake8-tidy-imports
      "TD",  # flake8-todos
      "TC",  # flake8-type-checking
      # "ARG",  # flake8-unused-arguments
      "PTH", # flake8-use-pathlib
      # "FLY",  # flynt 
      "I",    # isort
      "C90",  # mccabe 
      "N",    # pep8-naming
      "PERF", # Perflint
      "E",    # pycodestyle errors
      "W",    # pycodestyle warnings
      # "DOC",  # pydoclint
      # "D",    # pydocstyle
      "F", # Pyflakes
      # "PL",   # Pylint
      "FURB", # refurb 
      "RUF",  # Ruff-specific rules
      # "TRY",  # tryceratops
  ]
  
  ignore = [
      "B904",   # Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None`
      "S101",   # Use of `assert` detected
      "DTZ001", # `datetime.datetime()` called without a `tzinfo` argument
      "DTZ005", # `datetime.datetime.now()` called without a `tz` argument
      "DTZ006", # `datetime.datetime.fromtimestamp()` called without a `tz` argument
      "DTZ007", # Naive datetime constructed using `datetime.datetime.strptime()` without %z
      "DTZ011", # `datetime.date.today()` used,
      "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
      "SIM105", # Use contextlib.suppress({exception}) instead of try-except-pass
      "SIM115", # Use a context manager for opening files
      "TD002",  #	Missing author in TODO
      "TD003",  # Missing issue link for this TODO
  ]
  
  # Allow fix for all enabled rules (when `--fix`) is provided.
  fixable = ["ALL"]
  unfixable = []
  
  # Allow unused variables when underscore-prefixed.
  dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
  
  # List of allowed "confusable" Unicode characters to ignore when enforcing RUF001, RUF002, and RUF003.
  allowed-confusables = ["–", "‘", "’"]
  
  [tool.ruff.lint.flake8-quotes]
  inline-quotes = "single"
  
  [tool.ruff.lint.mccabe]
  # Flag errors (`C901`) whenever the complexity level exceeds below.
  max-complexity = 30
  
  [tool.ruff.lint.per-file-ignores]
  "test_*" = [
      "S101", # Use of `assert` detected
  ]
  
  [tool.ruff.lint.pydoclint]
  # Skip docstrings which fit on a single line.
  ignore-one-line-docstrings = true
  
  [tool.ruff.lint.pydocstyle]
  convention = "google"
  
  [tool.ruff.per-file-target-version]
  ".*.py" = "py314"
  
  [tool.ruff.format]
  # Enable the formatter, which is a drop-in replacement for Black.
  # No extra configuration is needed for basic formatting.
  
  # Exclude files for formatting only
  exclude = []
  
  # Use single quotes for strings.
  quote-style = "single"
  
  # Like Black, indent with spaces, rather than tabs.
  indent-style = "space"
  
  # Like Black, respect magic trailing commas.
  skip-magic-trailing-comma = false
  
  # Like Black, automatically detect the appropriate line ending.
  line-ending = "auto"
  
  # Enable auto-formatting of code examples in docstrings. Markdown,
  # reStructuredText code/literal blocks and doctests are all supported.
  #
  # This is currently disabled by default, but it is planned for this
  # to be opt-out in the future.
  docstring-code-format = true
  
  # Set the line length limit used when formatting code snippets in
  # docstrings.
  #
  # This only has an effect when the `docstring-code-format` setting is
  # enabled.
  docstring-code-line-length = "dynamic"
  