[tox]
min_version = 4.0
# Default: run tests on supported Python versions + lint.
# Optional: run `tox -e type` and/or `tox -e coverage` explicitly (not default-gated).
env_list =
    py39
    py310
    py311
    py312
    lint

[testenv]
description = Run tests with pytest
deps =
    pytest>=7.0.0
    pytest-cov>=4.0.0
    pytest-xdist>=3.0.0
commands =
    pytest {posargs:tests}

[testenv:py{39,310,311,312}]
description = Run tests with Python {envname}
package = editable
extras =
    dev
commands =
    pytest --cov=pyimgano --cov-report=term-missing --cov-report=html {posargs:tests}

[testenv:lint]
description = Run linters
skip_install = true
deps =
    black>=23.0.0
    isort>=5.12.0
    flake8>=6.0.0
    ruff>=0.1.0
commands =
    black --check pyimgano tests
    isort --check-only pyimgano tests
    flake8 pyimgano tests
    ruff check pyimgano tests

[testenv:format]
description = Format code with black and isort
skip_install = true
deps =
    black>=23.0.0
    isort>=5.12.0
commands =
    black pyimgano tests
    isort pyimgano tests

[testenv:type]
description = Run type checking with mypy
deps =
    mypy>=1.0.0
    numpy>=1.19
    types-Pillow
    types-setuptools
commands =
    # Keep type-checking focused on the stable, production-facing API surface.
    mypy --follow-imports=silent pyimgano/inputs/image_format.py pyimgano/inference/api.py pyimgano/models/registry.py pyimgano/models/introspection.py pyimgano/models/capabilities.py pyimgano/utils/optional_deps.py pyimgano/defects/merge.py pyimgano/defects/io.py pyimgano/defects/overlays.py

[testenv:coverage]
description = Run tests with coverage
package = editable
extras = dev
commands =
    pytest --cov=pyimgano --cov-report=term-missing --cov-report=html --cov-report=xml
    coverage report --fail-under=70

[testenv:docs]
description = Build documentation
changedir = docs
extras = docs
commands =
    sphinx-build -W -b html -d {envtmpdir}/doctrees source {envtmpdir}/html

[testenv:build]
description = Build package
skip_install = true
deps =
    build
    twine
commands =
    python -m build
    twine check dist/*

[testenv:clean]
description = Clean up build artifacts
skip_install = true
allowlist_externals =
    rm
    find
commands =
    rm -rf build dist *.egg-info
    rm -rf .pytest_cache .coverage htmlcov .mypy_cache .ruff_cache
    find . -type d -name __pycache__ -exec rm -rf {} +
    find . -type f -name "*.pyc" -delete

[pytest]
testpaths = tests
python_files = test_*.py *_test.py
python_classes = Test*
python_functions = test_*
addopts =
    --verbose
    --strict-markers
    --tb=short

[coverage:run]
source = pyimgano
omit =
    */tests/*
    */test_*.py

[coverage:report]
exclude_lines =
    pragma: no cover
    def __repr__
    raise AssertionError
    raise NotImplementedError
    if __name__ == .__main__.:
    if TYPE_CHECKING:
    @abstractmethod

[flake8]
max-line-length = 100
extend-ignore = E203, E266, E402, E501, W503
exclude =
    .git,
    __pycache__,
    .venv,
    .tox,
    build,
    dist,
    *.egg-info
per-file-ignores =
    __init__.py:F401,F403
    tests/*:F401,F811
