]> jfr.im git - yt-dlp.git/blame - pyproject.toml
[ie/mlbtv] Fix extraction (#10296)
[yt-dlp.git] / pyproject.toml
CommitLineData
e9df3d42 1[build-system]
775cde82 2requires = ["hatchling"]
3build-backend = "hatchling.build"
4
5[project]
6name = "yt-dlp"
7maintainers = [
8 {name = "pukkandan", email = "pukkandan.ytdlp@gmail.com"},
9 {name = "Grub4K", email = "contact@grub4k.xyz"},
10 {name = "bashonly", email = "bashonly@protonmail.com"},
47ab66db 11 {name = "coletdjnz", email = "coletdjnz@protonmail.com"},
775cde82 12]
388c979a 13description = "A feature-rich command-line audio/video downloader"
775cde82 14readme = "README.md"
15requires-python = ">=3.8"
16keywords = [
17 "youtube-dl",
18 "video-downloader",
19 "youtube-downloader",
20 "sponsorblock",
21 "youtube-dlc",
22 "yt-dlp",
23]
24license = {file = "LICENSE"}
25classifiers = [
26 "Topic :: Multimedia :: Video",
27 "Development Status :: 5 - Production/Stable",
28 "Environment :: Console",
29 "Programming Language :: Python",
30 "Programming Language :: Python :: 3 :: Only",
31 "Programming Language :: Python :: 3.8",
32 "Programming Language :: Python :: 3.9",
33 "Programming Language :: Python :: 3.10",
34 "Programming Language :: Python :: 3.11",
35 "Programming Language :: Python :: 3.12",
36 "Programming Language :: Python :: Implementation",
37 "Programming Language :: Python :: Implementation :: CPython",
38 "Programming Language :: Python :: Implementation :: PyPy",
39 "License :: OSI Approved :: The Unlicense (Unlicense)",
40 "Operating System :: OS Independent",
41]
42dynamic = ["version"]
43dependencies = [
44 "brotli; implementation_name=='cpython'",
45 "brotlicffi; implementation_name!='cpython'",
46 "certifi",
47 "mutagen",
48 "pycryptodomex",
db50f19d 49 "requests>=2.32.2,<3",
775cde82 50 "urllib3>=1.26.17,<3",
51 "websockets>=12.0",
52]
53
54[project.optional-dependencies]
cf91400a 55default = []
02483bea 56curl-cffi = ["curl-cffi==0.5.10; implementation_name=='cpython'"]
775cde82 57secretstorage = [
58 "cffi",
59 "secretstorage",
60]
61build = [
62 "build",
63 "hatchling",
64 "pip",
5fdd1300 65 "setuptools",
775cde82 66 "wheel",
67]
68dev = [
e897bd82
SS
69 "pre-commit",
70 "yt-dlp[static-analysis]",
71 "yt-dlp[test]",
72]
73static-analysis = [
74 "autopep8~=2.0",
7814c509 75 "ruff~=0.5.0",
e897bd82
SS
76]
77test = [
78 "pytest~=8.1",
775cde82 79]
58dd0f8d 80pyinstaller = [
5fdd1300 81 "pyinstaller>=6.7.0", # for compat with setuptools>=70
58dd0f8d 82]
3f799953
SS
83py2exe = [
84 "py2exe>=0.12",
3f799953 85]
775cde82 86
87[project.urls]
88Documentation = "https://github.com/yt-dlp/yt-dlp#readme"
89Repository = "https://github.com/yt-dlp/yt-dlp"
90Tracker = "https://github.com/yt-dlp/yt-dlp/issues"
91Funding = "https://github.com/yt-dlp/yt-dlp/blob/master/Collaborators.md#collaborators"
92
93[project.scripts]
94yt-dlp = "yt_dlp:main"
a1b77842 95
96[project.entry-points.pyinstaller40]
97hook-dirs = "yt_dlp.__pyinstaller:get_hook_dirs"
775cde82 98
99[tool.hatch.build.targets.sdist]
100include = [
101 "/yt_dlp",
102 "/devscripts",
103 "/test",
104 "/.gitignore", # included by default, needed for auto-excludes
105 "/Changelog.md",
106 "/LICENSE", # included as license
107 "/pyproject.toml", # included by default
108 "/README.md", # included as readme
109 "/setup.cfg",
110 "/supportedsites.md",
111]
775cde82 112artifacts = [
113 "/yt_dlp/extractor/lazy_extractors.py",
114 "/completions",
115 "/AUTHORS", # included by default
116 "/README.txt",
117 "/yt-dlp.1",
118]
119
120[tool.hatch.build.targets.wheel]
121packages = ["yt_dlp"]
775cde82 122artifacts = ["/yt_dlp/extractor/lazy_extractors.py"]
123
124[tool.hatch.build.targets.wheel.shared-data]
125"completions/bash/yt-dlp" = "share/bash-completion/completions/yt-dlp"
126"completions/zsh/_yt-dlp" = "share/zsh/site-functions/_yt-dlp"
127"completions/fish/yt-dlp.fish" = "share/fish/vendor_completions.d/yt-dlp.fish"
128"README.txt" = "share/doc/yt_dlp/README.txt"
129"yt-dlp.1" = "share/man/man1/yt-dlp.1"
130
131[tool.hatch.version]
132path = "yt_dlp/version.py"
133pattern = "_pkg_version = '(?P<version>[^']+)'"
e897bd82
SS
134
135[tool.hatch.envs.default]
136features = ["curl-cffi", "default"]
137dependencies = ["pre-commit"]
138path = ".venv"
139installer = "uv"
140
141[tool.hatch.envs.default.scripts]
142setup = "pre-commit install --config .pre-commit-hatch.yaml"
143yt-dlp = "python -Werror -Xdev -m yt_dlp {args}"
144
145[tool.hatch.envs.hatch-static-analysis]
146detached = true
147features = ["static-analysis"]
148dependencies = [] # override hatch ruff version
149config-path = "pyproject.toml"
150
151[tool.hatch.envs.hatch-static-analysis.scripts]
152format-check = "autopep8 --diff {args:.}"
153format-fix = "autopep8 --in-place {args:.}"
154lint-check = "ruff check {args:.}"
155lint-fix = "ruff check --fix {args:.}"
156
157[tool.hatch.envs.hatch-test]
158features = ["test"]
159dependencies = [
160 "pytest-randomly~=3.15",
161 "pytest-rerunfailures~=14.0",
162 "pytest-xdist[psutil]~=3.5",
163]
164
165[tool.hatch.envs.hatch-test.scripts]
166run = "python -m devscripts.run_tests {args}"
167run-cov = "echo Code coverage not implemented && exit 1"
168
169[[tool.hatch.envs.hatch-test.matrix]]
170python = [
171 "3.8",
172 "3.9",
173 "3.10",
174 "3.11",
175 "3.12",
176 "pypy3.8",
177 "pypy3.9",
178 "pypy3.10",
179]
180
181[tool.ruff]
182line-length = 120
183
184[tool.ruff.lint]
185ignore = [
add96eb9 186 "E402", # module-import-not-at-top-of-file
187 "E501", # line-too-long
188 "E731", # lambda-assignment
189 "E741", # ambiguous-variable-name
190 "UP036", # outdated-version-block
191 "B006", # mutable-argument-default
192 "B008", # function-call-in-default-argument
193 "B011", # assert-false
194 "B017", # assert-raises-exception
195 "B023", # function-uses-loop-variable (false positives)
196 "B028", # no-explicit-stacklevel
197 "B904", # raise-without-from-inside-except
198 "C401", # unnecessary-generator-set
199 "C402", # unnecessary-generator-dict
200 "PIE790", # unnecessary-placeholder
201 "SIM102", # collapsible-if
202 "SIM108", # if-else-block-instead-of-if-exp
203 "SIM112", # uncapitalized-environment-variables
204 "SIM113", # enumerate-for-loop
205 "SIM114", # if-with-same-arms
206 "SIM115", # open-file-with-context-handler
207 "SIM117", # multiple-with-statements
208 "SIM223", # expr-and-false
209 "SIM300", # yoda-conditions
210 "TD001", # invalid-todo-tag
211 "TD002", # missing-todo-author
212 "TD003", # missing-todo-link
213 "PLE0604", # invalid-all-object (false positives)
7814c509 214 "PLE0643", # potential-index-error (false positives)
add96eb9 215 "PLW0603", # global-statement
216 "PLW1510", # subprocess-run-without-check
217 "PLW2901", # redefined-loop-name
218 "RUF001", # ambiguous-unicode-character-string
219 "RUF012", # mutable-class-default
220 "RUF100", # unused-noqa (flake8 has slightly different behavior)
e897bd82
SS
221]
222select = [
add96eb9 223 "E", # pycodestyle Error
224 "W", # pycodestyle Warning
225 "F", # Pyflakes
226 "I", # isort
227 "Q", # flake8-quotes
228 "N803", # invalid-argument-name
229 "N804", # invalid-first-argument-name-for-class-method
230 "UP", # pyupgrade
231 "B", # flake8-bugbear
232 "A", # flake8-builtins
233 "COM", # flake8-commas
234 "C4", # flake8-comprehensions
235 "FA", # flake8-future-annotations
236 "ISC", # flake8-implicit-str-concat
237 "ICN003", # banned-import-from
238 "PIE", # flake8-pie
239 "T20", # flake8-print
240 "RSE", # flake8-raise
241 "RET504", # unnecessary-assign
242 "SIM", # flake8-simplify
243 "TID251", # banned-api
244 "TD", # flake8-todos
245 "PLC", # Pylint Convention
246 "PLE", # Pylint Error
247 "PLW", # Pylint Warning
248 "RUF", # Ruff-specific rules
e897bd82
SS
249]
250
251[tool.ruff.lint.per-file-ignores]
add96eb9 252"devscripts/lazy_load_template.py" = [
253 "F401", # unused-import
254]
255"!yt_dlp/extractor/**.py" = [
256 "I", # isort
257 "ICN003", # banned-import-from
258 "T20", # flake8-print
259 "A002", # builtin-argument-shadowing
260 "C408", # unnecessary-collection-call
261]
262"yt_dlp/jsinterp.py" = [
263 "UP031", # printf-string-formatting
264]
e897bd82
SS
265
266[tool.ruff.lint.isort]
267known-first-party = [
268 "bundle",
269 "devscripts",
270 "test",
271]
272relative-imports-order = "closest-to-furthest"
273
add96eb9 274[tool.ruff.lint.flake8-quotes]
275docstring-quotes = "double"
276multiline-quotes = "single"
277inline-quotes = "single"
278avoid-escape = false
279
280[tool.ruff.lint.pep8-naming]
281classmethod-decorators = [
282 "yt_dlp.utils.classproperty",
283]
284
285[tool.ruff.lint.flake8-import-conventions]
286banned-from = [
287 "base64",
288 "datetime",
289 "functools",
290 "glob",
291 "hashlib",
292 "itertools",
293 "json",
294 "math",
295 "os",
296 "pathlib",
297 "random",
298 "re",
299 "string",
300 "sys",
301 "time",
302 "urllib",
303 "uuid",
304 "xml",
305]
306
307[tool.ruff.lint.flake8-tidy-imports.banned-api]
308"yt_dlp.compat.compat_str".msg = "Use `str` instead."
309"yt_dlp.compat.compat_b64decode".msg = "Use `base64.b64decode` instead."
310"yt_dlp.compat.compat_urlparse".msg = "Use `urllib.parse` instead."
311"yt_dlp.compat.compat_parse_qs".msg = "Use `urllib.parse.parse_qs` instead."
312"yt_dlp.compat.compat_urllib_parse_unquote".msg = "Use `urllib.parse.unquote` instead."
313"yt_dlp.compat.compat_urllib_parse_urlencode".msg = "Use `urllib.parse.urlencode` instead."
314"yt_dlp.compat.compat_urllib_parse_urlparse".msg = "Use `urllib.parse.urlparse` instead."
315"yt_dlp.compat.compat_shlex_quote".msg = "Use `yt_dlp.utils.shell_quote` instead."
316"yt_dlp.utils.error_to_compat_str".msg = "Use `str` instead."
317
e897bd82
SS
318[tool.autopep8]
319max_line_length = 120
320recursive = true
321exit-code = true
322jobs = 0
323select = [
324 "E101",
325 "E112",
326 "E113",
327 "E115",
328 "E116",
329 "E117",
330 "E121",
331 "E122",
332 "E123",
333 "E124",
334 "E125",
335 "E126",
336 "E127",
337 "E128",
338 "E129",
339 "E131",
340 "E201",
341 "E202",
342 "E203",
343 "E211",
344 "E221",
345 "E222",
346 "E223",
347 "E224",
348 "E225",
349 "E226",
350 "E227",
351 "E228",
352 "E231",
353 "E241",
354 "E242",
355 "E251",
356 "E252",
357 "E261",
358 "E262",
359 "E265",
360 "E266",
361 "E271",
362 "E272",
363 "E273",
364 "E274",
365 "E275",
366 "E301",
367 "E302",
368 "E303",
369 "E304",
370 "E305",
371 "E306",
372 "E502",
373 "E701",
374 "E702",
375 "E704",
376 "W391",
377 "W504",
378]
379
380[tool.pytest.ini_options]
381addopts = "-ra -v --strict-markers"
382markers = [
383 "download",
384]