[build-system]
build-backend = "hatchling.build"
requires = [
    "hatchling",
]

[project]
name = "jinja2-async-environment"
version = "0.18.6"
description = "Provides asynchronous alternatives to Jinja2's standard template environment and loaders"
readme = "README.md"
authors = [
    { name = "lesleslie", email = "les@wedgwoodwebworks.com" },
]
requires-python = ">=3.13"
classifiers = [
    "Development Status :: 4 - Beta",
    "Framework :: AsyncIO",
    "Framework :: FastAPI",
    "License :: OSI Approved :: BSD License",
    "Operating System :: OS Independent",
    "Programming Language :: Python",
    "Programming Language :: Python :: 3 :: Only",
    "Programming Language :: Python :: 3.13",
    "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
    "Typing :: Typed",
]
dependencies = [
    "anyio>=4.11.0",
    "jinja2>=3.1.6",
    "redis>=7.1.0",
]

[project.license]
text = "BSD-3-Clause"

[dependency-groups]
dev = [
    "codespell>=2.4.1",
    "complexipy>=5.0.0",
    "crackerjack>=0.44.36",
    "session-mgmt-mcp>=0.9.6",
    "twine>=6.2.0",
    "uv-bump>=0.3.1",
]

[tool.ruff]
target-version = "py313"
line-length = 88
fix = true
unsafe-fixes = true
show-fixes = true
output-format = "full"
exclude = [
    "tests/",
    "test_*.py",
    "*_test.py",
]

[tool.ruff.format]
docstring-code-format = true

[tool.ruff.lint]
extend-select = [
    "C901",
    "D",
    "F",
    "I",
    "UP",
]
ignore = [
    "D100",
    "D101",
    "D102",
    "D103",
    "D104",
    "D105",
    "D106",
    "D107",
    "E402",
    "F821",
    "UP040",
]
fixable = [
    "ALL",
]
unfixable = []

[tool.ruff.lint.isort]
no-lines-before = [
    "first-party",
]

[tool.ruff.lint.mccabe]
max-complexity = 15

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.codespell]
skip = "*/data/*,tests/*,test_*.py,*_test.py"
quiet-level = 3
ignore-words-list = "crate,uptodate,nd"

[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
python_files = [
    "test_*.py",
    "*_test.py",
]
testpaths = [
    "tests",
    "jinja2_async_environment",
]
python_classes = [
    "Test*",
]
python_functions = [
    "test_*",
]
markers = [
    "unit: marks test as a unit test",
    "benchmark: mark test as a benchmark (disables parallel execution)",
    "integration: marks test as an integration test",
]
timeout = 300
timeout_method = "thread"
addopts = "--cov=jinja2_async_environment --cov-report=term --cov-fail-under=83"
filterwarnings = [
    "ignore::pytest_benchmark.logger.PytestBenchmarkWarning",
]

[tool.pytest-benchmark]
disable_gc = true
warmup = false
warmup_iterations = 0
min_rounds = 1
max_time = 5.0

[tool.coverage.run]
branch = false
source = [
    "jinja2_async_environment",
]
data_file = ".coverage"
parallel = false
omit = [
    "*/tests/*",
    "*/site-packages/*",
    "*/__pycache__/*",
    "*/__init__.py",
    "*/_version.py",
    "*/conftest.py",
    "*/test_*.py",
    "*/_test.py",
]

[tool.coverage.report]
exclude_also = [
    "pragma: no cover",
    "def __repr__",
    "raise NotImplementedError",
    "if __name__ == .__main__.:",
    "pass",
    "raise ImportError",
    "except ImportError",
    "def __str__",
    "@abstractmethod",
]
ignore_errors = false

[tool.pyright]
verboseOutput = true
include = [
    "tests",
    "jinja2_async_environment",
]
exclude = [
    "dist",
    "build",
    "scratch",
    ".venv",
]
extraPaths = [
    ".venv/lib/python3.13/site-packages/",
]
typeCheckingMode = "strict"
reportMissingTypeStubs = false
reportOptionalMemberAccess = false
reportOptionalCall = false
reportUnknownMemberType = false
reportUnknownVariableType = false
reportUnknownArgumentType = false
reportInvalidTypeForm = false
reportUnknownLambdaType = false
reportUnknownParameterType = "warning"
reportPrivateUsage = false
pythonVersion = "3.13"
reportUnnecessaryTypeIgnoreComment = "warning"
reportUnnecessaryComparison = "warning"
reportConstantRedefinition = "warning"

[tool.creosote]
paths = [
    "jinja2_async_environment",
]
deps-file = "pyproject.toml"
exclude-deps = [
    "pytest",
    "pytest-mock",
    "keyring",
    "pytest-benchmark",
    "pydantic-settings",
    "google-crc32c",
    "pyleak",
    "tomli-w",
    "pytest-asyncio",
    "pytest-cov",
    "pytest-xdist",
    "autotyping",
    "uv",
    "hatchling",
    "pytest-timeout",
    "pyfiglet",
    "inflection",
    "pyyaml",
    "pre-commit",
]

[tool.refurb]
enable_all = true
quiet = true
python_version = "3.13"
ignore = [
    "FURB184",
    "FURB120",
]

[tool.bandit]
target = [
    "tests",
    "jinja2_async_environment",
]
skips = [
    "B403",
    "B101",
    "B301",
    "B404",
    "B602",
    "B704",
    "B607",
    "B311",
    "B603",
]
exclude_dirs = [
    "tests/data",
]

[tool.vulture]
min_confidence = 86
paths = [
    "jinja2_async_environment",
]
exclude = [
    "tests/",
    "test_*.py",
    "*_test.py",
]
ignore_names = [
    "cls",
]

[tool.uv]
keyring-provider = "subprocess"
index-url = "https://pypi.org/simple/"
publish-url = "https://upload.pypi.org/legacy/"
check-url = "https://pypi.org/simple/"
prerelease = "allow"

[tool.uv.sources]

[[tool.uv.index]]
name = "pypi"
url = "https://upload.pypi.org/legacy/"
check-url = "https://pypi.org/simple/"

[tool.complexipy]
default_pattern = "**/*.py"
exclude_patterns = [
    "**/tests/**",
    "**/test_*.py",
]
max_complexity = 15
