Ctrl K
ComunidadGuías…

pyproject.toml

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

Archivo original ↗Preguntar a KiBot
[project]
name = "beets"
version = "2.14.1"
description = "music tagger and library organizer"
authors = [{ name = "Adrian Sampson", email = "adrian@radbox.org" }]
maintainers = [{ name = "Serene-Arc" }]
license = { text = "MIT" }
readme = "README.rst"
requires-python = ">=3.11,<3.16"
classifiers = [
    "Topic :: Multimedia :: Sound/Audio",
    "Topic :: Multimedia :: Sound/Audio :: Players :: MP3",
    "License :: OSI Approved :: MIT License",
    "Environment :: Console",
    "Environment :: Web Environment",
    "Programming Language :: Python",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Programming Language :: Python :: 3.14",
    "Programming Language :: Python :: 3.15",
    "Programming Language :: Python :: Implementation :: CPython",
]

dependencies = [
    "colorama ; sys_platform == 'win32'",
    "confuse>=2.3.0",
    "jellyfish",
    "lap>=0.5.12",
    "mediafile>=0.17.0",
    "numpy>=2.0.2 ; python_version < '3.13'",
    "numpy>=2.3.5 ; python_version >= '3.13'",
    "packaging>=24.0",
    "platformdirs>=3.5.0",
    "pyyaml",
    "requests>=2.32.5",
    "requests-ratelimiter>=0.7.0",
    "typing_extensions",
    "unidecode>=1.3.6",
]

[dependency-groups]
docs = [
    "docutils>=0.20.1",
    "pydata-sphinx-theme",
    "sphinx<9",
    "sphinx-lint>=1.0.0",
    "sphinx-design>=0.6.1",
    "sphinx-copybutton>=0.5.2",
    "sphinx-toolbox>=4.1.0",
    "titlecase>=2.4.1,<3",
]
test = [
    "beautifulsoup4",
    "codecov>=2.1.13",
    "flask",
    "langdetect",
    "pylast",
    "pytest",
    "pytest-cov",
    "pytest-factoryboy>=2.8.1",
    "pytest-flask",
    "python-mpd2",
    "pytest-randomly>=5.0.0",
    "pytest-xdist>=3.8.0",
    "python3-discogs-client>=2.10",
    "py7zr",
    "pyxdg",
    "rarfile",
    "requests-mock>=1.12.1",
    "requests-oauthlib",
    "responses>=0.3.0",
    "titlecase>=2.4.1,<3",
]
lint = [
    "docstrfmt>=2.0.2",
    "ruff>=0.13.0",
    "sphinx-lint>=1.0.0",
]
typing = [
    "mypy",
    "types-beautifulsoup4",
    "types-docutils>=0.22.2.20251006",
    "types-Flask-Cors",
    "types-Pillow",
    "types-PyYAML",
    "types-requests",
    "types-urllib3",
]
release = [
    "click>=8.1.7",
]
dev = [
    { include-group = "docs" },
    { include-group = "lint" },
    { include-group = "test" },
    { include-group = "typing" },
]

[project.optional-dependencies]
# inline comments note required external / non-python dependencies
absubmit = ["requests"] # extractor binary from https://acousticbrainz.org/download
aura = ["flask", "flask-cors", "Pillow"]
autobpm = ["librosa>=0.11", "resampy>=0.4.3", "numba>=0.65.1"]
# badfiles # mp3val and flac
beatport = ["requests-oauthlib>=0.6.1"]
bpd = [
    "gstreamer-bundle>=1.28.0 ; sys_platform == 'win32' and python_version < '3.15'",
    "PyGObject ; sys_platform != 'win32'",
] # gobject-introspection, gstreamer1.0-plugins-base, python3-gst-1.0
chroma = ["pyacoustid>=1.3.1,<2"] # chromaprint or fpcalc
# convert # ffmpeg
discogs = ["python3-discogs-client>=2.10"]
embedart = ["Pillow"] # ImageMagick
embyupdate = ["requests"]
fetchart = ["beautifulsoup4", "langdetect", "Pillow", "requests"]
import = ["py7zr", "rarfile"]
# ipfs # go-ipfs
# keyfinder # KeyFinder
kodiupdate = ["requests"]
lastgenre = ["pylast"]
lastimport = ["pylast"]
lyrics = ["beautifulsoup4", "langdetect", "requests"]
metasync = ["dbus-python ; sys_platform != 'win32'"]
mpdstats = ["python-mpd2>=0.4.2"]
plexupdate = ["requests"]
reflink = ["reflink"]
replaygain = [
    "gstreamer-bundle>=1.28.0 ; sys_platform == 'win32' and python_version < '3.15'",
    "PyGObject ; sys_platform != 'win32'",
] # python-gi and GStreamer 1.0+ or mp3gain/aacgain or Python Audio Tools or ffmpeg
scrub = ["mutagen>=1.33"]
sonosupdate = ["soco"]
tidal = ["requests-oauthlib>=0.6.1"]
titlecase = ["titlecase"]
thumbnails = ["Pillow"]
web = ["flask", "flask-cors"]

[project.scripts]
beet = "beets.ui:main"

[project.urls]
Homepage = "https://beets.io/"
Repository = "https://github.com/beetbox/beets"
Documentation = "https://beets.readthedocs.io/en/stable/"
Changelog = "https://github.com/beetbox/beets/blob/master/docs/changelog.rst"
"Bug Tracker" = "https://github.com/beetbox/beets/issues"

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

[tool.hatch.build]
artifacts = [
    "man/**",
]

[tool.hatch.build.targets.wheel]
packages = ["beets", "beetsplug"]

[tool.hatch.build.targets.sdist]
include = [
    "beets/",
    "beetsplug/",
    "docs/",
    "extra/",
    "man/",
    "test/",
]
exclude = [
    "docs/_build/",
    "docs/modd.conf",
    "docs/**/*.css",
]

[tool.uv]
# 1.28.8 only ships free-threaded (cp313t/cp314t) wheels for Windows
constraint-dependencies = [
    "gstreamer-plugins!=1.28.8",
    "gstreamer-plugins-gpl!=1.28.8",
    "gstreamer-plugins-gpl-restricted!=1.28.8",
    "gstreamer-plugins-libs!=1.28.8",
    "gstreamer-plugins-restricted!=1.28.8",
]

[tool.poe.tasks.build]
help = "Build the package"
shell = """
make -C docs man
rm -rf man
mv docs/_build/man .
uv build
"""

[tool.poe.tasks.bump]
help = "Bump project version and update relevant files"
cmd = "python ./extra/release.py bump $version"
args = { version = { help = "The new version to set", positional = true, required = true } }

[tool.poe.tasks.changelog]
help = "Print the latest version's changelog in Markdown"
cmd = "python ./extra/release.py changelog"

[tool.poe.tasks.check-docs-links]
help = "Check the documentation for broken URLs"
cmd = "make -C docs linkcheck"

[tool.poe.tasks.check-format]
help = "Check the code for style issues"
cmd = "ruff format --check --diff"

[tool.poe.tasks.check-types]
help = "Check the code for typing issues. Accepts mypy options."
cmd = "mypy"

[tool.poe.tasks.docs]
help = "Build documentation"
args = [{ name = "COMMANDS", positional = true, multiple = true, default = "html" }]
cmd = "make -C docs $COMMANDS"

[tool.poe.tasks.format]
help = "Format the codebase"
cmd = "ruff format --config=pyproject.toml"

[tool.poe.tasks.format-docs]
help = "Format the documentation"
cmd = "docstrfmt --preserve-adornments docs *.rst"

[tool.poe.tasks.install]
help = "Install project dependencies"
cmd = "uv sync --locked"

[tool.poe.tasks.lint]
help = "Check the code for linting issues. Accepts ruff options."
cmd = "ruff check --config=pyproject.toml"

[tool.poe.tasks.lint-docs]
help = "Lint the documentation"
interpreter = "bash"
shell = """
set -o pipefail
files=$(git ls-files '*.rst')

grep -Eno ' `[^`][^`]+`[^_]' $files |
    sed 's/ .*/ Use double backticks for inline literal (double-backticks-required)/' && failed=1
sphinx-lint --enable all --disable default-role $files || failed=1

exit ${failed:-0}
"""

[tool.poe.tasks.update-dependencies]
help = "Update dependencies to their latest versions."
cmd = "uv sync --upgrade"

[tool.poe.tasks.test]
help = "Run tests with pytest"
cmd = "uv run pytest $OPTS"
env.OPTS.default = "-p no:cov"

[tool.poe.tasks.test-with-coverage]
help = "Run tests and record coverage"
ref = "test"
# record coverage in beets and beetsplug packages
# save xml for coverage upload to coveralls
# save html report for local dev use
# measure coverage across logical branches
# show which tests cover specific lines in the code (see the HTML report)
env.OPTS = """
--cov=.
--cov-report=xml:.reports/coverage.xml
--cov-report=html:.reports/html
--cov-branch
--cov-context=test
"""

[tool.poe.tasks.check-temp-files]
help = "Run each test module one by one and check for leftover temp files"
shell = """
setopt nullglob
for file in test/**/*.py; do
  print Temp files created by $file && poe test $file &>/dev/null
  tempfiles=(/tmp/**/tmp* /tmp/beets/**/*)
  if (( $#tempfiles )); then
    print -l $'\t'$^tempfiles
    rm -r --interactive=never $tempfiles &>/dev/null
  fi
done
"""
interpreter = "zsh"

[tool.docstrfmt]
line-length = 80
extend-exclude = [
    "docs/_templates/**/*",
    "docs/api/**/*",
    "README_kr.rst",
]

[tool.ruff]
target-version = "py311"
line-length = 80

[tool.ruff.format]
skip-magic-trailing-comma = true

[tool.ruff.lint]
future-annotations = true
select = [
    "A", # flake8-builtins
    "ANN", # flake8-annotations
    # "ARG", # flake8-unused-arguments
    # "C4", # flake8-comprehensions
    "E", # pycodestyle
    "ERA", # eradicate
    "F", # pyflakes
    # "B", # flake8-bugbear
    "G", # flake8-logging-format
    "I", # isort
    "ISC", # flake8-implicit-str-concat
    "N", # pep8-naming
    "PIE", # flake8-pie
    "PT", # flake8-pytest-style
    "RET", # flake8-return
    "RUF", # ruff
    "SIM", # flake8-simplify
    "UP", # pyupgrade
    "TC", # flake8-type-checking
    "W", # pycodestyle
]
ignore = [
    "ANN002", # no need to document *args due to noise
    "ANN003", # no need to document **kwargs due to noise
    "ANN401", # we use Any type in the codebase
    "TC006", # no need to quote 'cast's since we use 'from __future__ import annotations'
]

[tool.ruff.lint.per-file-ignores]
"beets/**" = ["PT"]
"docs/conf.py" = ["ANN"]
"test/plugins/test_ftintitle.py" = ["E501"]
"test/test_util.py" = ["E501"]
"test/util/test_diff.py" = ["E501"]
"test/util/test_id_extractors.py" = ["E501"]
"test/**" = [
    "RUF001", # we use Unicode characters in tests
    "ANN", # we don't annotate test functions
]

[tool.ruff.lint.isort]
split-on-trailing-comma = false

[tool.ruff.lint.pycodestyle]
max-line-length = 88

[tool.ruff.lint.flake8-annotations]
allow-star-arg-any = true
suppress-dummy-args = true

[tool.ruff.lint.flake8-pytest-style]
fixture-parentheses = false
mark-parentheses = false
parametrize-names-type = "csv"

[tool.ruff.lint.flake8-unused-arguments]
ignore-variadic-names = true

[tool.ruff.lint.pep8-naming]
classmethod-decorators = ["cached_classproperty"]
extend-ignore-names = ["assert*", "cached_classproperty"]