Ctrl K
ComunidadGuías…

pyproject.toml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "trackstarr"
dynamic = ["version"]
description = "Keep media library audio and subtitle tracks tidy"
readme = "README.md"
license = { file = "LICENSE" }
# What the Alpine image ships and the only version CI tests.
requires-python = ">=3.14"
authors = [{ name = "MarcedForLife" }]
keywords = ["ffmpeg", "media", "radarr", "sonarr", "plex", "transcoding"]
classifiers = [
  "Programming Language :: Python :: 3",
  "License :: OSI Approved :: MIT License",
  "Topic :: Multimedia :: Video",
]
# One runtime dependency; the bar for a second is high. cryptography seals the
# credentials in settings.json, which needs an AEAD cipher the stdlib lacks.
# The floor is the first release with musllinux abi3 wheels for Alpine.
dependencies = ["cryptography>=45"]

[project.scripts]
trackstarr = "trackstarr.cli:main"

[project.urls]
Homepage = "https://github.com/MarcedForLife/trackstarr"
Issues = "https://github.com/MarcedForLife/trackstarr/issues"

# A group, so the tooling stays out of the published metadata and `uv sync`
# installs it. Loose bounds: uv.lock pins the versions CI installs.
[dependency-groups]
dev = ["mypy>=2", "pytest>=8", "pytest-cov>=5", "ruff>=0.14"]

[tool.hatch.version]
path = "src/trackstarr/__init__.py"

[tool.hatch.build.targets.wheel]
packages = ["src/trackstarr"]

[tool.pytest.ini_options]
testpaths = ["tests"]
filterwarnings = ["error"]
# strict-markers makes a mark typo an error; strict-config likewise for this
# table.
addopts = ["--strict-markers", "--strict-config"]

# --cov is not in addopts: it slows every run and the in-image suite has no
# pytest-cov. `pytest --cov` picks the settings up from here.
[tool.coverage.run]
source_pkgs = ["trackstarr"]
branch = true
# The `python -m trackstarr` shim: two imports and a call to cli.main.
omit = ["*/trackstarr/__main__.py"]

[tool.coverage.report]
show_missing = true
exclude_also = ["if __name__ == .__main__.:"]
# 100, so a line arriving without a test fails the build the day it lands.
# Untestable code takes an explicit `# pragma: no cover` with a reason; so far
# every one is a thread body or startup wiring. `grep -rn "pragma: no cover"
# src` is the list.
fail_under = 100

# src only; type-checking the tests buys little. Not --strict, which wants a
# type for every ffprobe dict, whose shape is the thing being interrogated.
# These are the strict flags that pass clean today.
[tool.mypy]
files = ["src"]
warn_unused_ignores = true
warn_redundant_casts = true
warn_unreachable = true
no_implicit_reexport = true
strict_equality = true

[tool.ruff]
line-length = 96
src = ["src", "tests"]

[tool.ruff.lint]
select = [
  "E", "W",   # pycodestyle
  "F",        # pyflakes
  "I",        # isort
  "B",        # bugbear
  "UP",       # pyupgrade
  "N",        # pep8-naming
  "SIM",      # flake8-simplify
  "S",        # bandit
  "A",        # builtin shadowing
  "C4",       # comprehensions
  "DTZ",      # naive datetimes
  "FURB",     # refurb, modern idiom
  "G",        # logging call format
  "ISC",      # implicit string concatenation, i.e. the comma you forgot
  "LOG",      # logging misuse
  "PERF",     # obviously slow constructs
  "PIE",      # assorted lint
  "RET",      # return flow
  "SLOT",
  "TID",      # tidy imports
  "PLC", "PLE",  # pylint's conventions and errors
  "RUF",
]
# Unselected: TRY, PLW, PT, C90 and the PL refactor rules fire only on
# deliberate code here and would buy a row of noqa comments. ANN and D
# duplicate mypy and the docstrings. PTH would be a pathlib migration.
ignore = [
  # Subprocess calls are the point of this tool; the argument lists are built
  # from validated config, never through a shell.
  "S603", "S607",
  # 0.0.0.0 is the right default for a container's listener.
  "S104",
  # urllib only ever gets the configured Radarr/Sonarr base URL.
  "S310",
]

[tool.ruff.lint.per-file-ignores]
# S101: asserts are what tests are. S108: the planner tests' /tmp paths are
# never opened. S105-S107: the "passwords" are fixture secrets. DTZ001: the
# cron tests are about naive wall-clock matching.
"tests/*" = ["S101", "S105", "S106", "S107", "S108", "DTZ001"]

[tool.ruff.lint.isort]
# conftest is a local test helper, not a third-party package.
known-first-party = ["trackstarr", "conftest"]