]>
Commit | Line | Data |
---|---|---|
e9df3d42 | 1 | [build-system] |
775cde82 | 2 | requires = ["hatchling"] |
3 | build-backend = "hatchling.build" | |
4 | ||
5 | [project] | |
6 | name = "yt-dlp" | |
7 | maintainers = [ | |
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 | 13 | description = "A feature-rich command-line audio/video downloader" |
775cde82 | 14 | readme = "README.md" |
15 | requires-python = ">=3.8" | |
16 | keywords = [ | |
17 | "youtube-dl", | |
18 | "video-downloader", | |
19 | "youtube-downloader", | |
20 | "sponsorblock", | |
21 | "youtube-dlc", | |
22 | "yt-dlp", | |
23 | ] | |
24 | license = {file = "LICENSE"} | |
25 | classifiers = [ | |
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 | ] | |
42 | dynamic = ["version"] | |
43 | dependencies = [ | |
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 | 55 | default = [] |
02483bea | 56 | curl-cffi = ["curl-cffi==0.5.10; implementation_name=='cpython'"] |
775cde82 | 57 | secretstorage = [ |
58 | "cffi", | |
59 | "secretstorage", | |
60 | ] | |
61 | build = [ | |
62 | "build", | |
63 | "hatchling", | |
64 | "pip", | |
5fdd1300 | 65 | "setuptools", |
775cde82 | 66 | "wheel", |
67 | ] | |
68 | dev = [ | |
e897bd82 SS |
69 | "pre-commit", |
70 | "yt-dlp[static-analysis]", | |
71 | "yt-dlp[test]", | |
72 | ] | |
73 | static-analysis = [ | |
74 | "autopep8~=2.0", | |
7814c509 | 75 | "ruff~=0.5.0", |
e897bd82 SS |
76 | ] |
77 | test = [ | |
78 | "pytest~=8.1", | |
775cde82 | 79 | ] |
58dd0f8d | 80 | pyinstaller = [ |
5fdd1300 | 81 | "pyinstaller>=6.7.0", # for compat with setuptools>=70 |
58dd0f8d | 82 | ] |
3f799953 SS |
83 | py2exe = [ |
84 | "py2exe>=0.12", | |
3f799953 | 85 | ] |
775cde82 | 86 | |
87 | [project.urls] | |
88 | Documentation = "https://github.com/yt-dlp/yt-dlp#readme" | |
89 | Repository = "https://github.com/yt-dlp/yt-dlp" | |
90 | Tracker = "https://github.com/yt-dlp/yt-dlp/issues" | |
91 | Funding = "https://github.com/yt-dlp/yt-dlp/blob/master/Collaborators.md#collaborators" | |
92 | ||
93 | [project.scripts] | |
94 | yt-dlp = "yt_dlp:main" | |
a1b77842 | 95 | |
96 | [project.entry-points.pyinstaller40] | |
97 | hook-dirs = "yt_dlp.__pyinstaller:get_hook_dirs" | |
775cde82 | 98 | |
99 | [tool.hatch.build.targets.sdist] | |
100 | include = [ | |
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 | 112 | artifacts = [ |
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] | |
121 | packages = ["yt_dlp"] | |
775cde82 | 122 | artifacts = ["/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] | |
132 | path = "yt_dlp/version.py" | |
133 | pattern = "_pkg_version = '(?P<version>[^']+)'" | |
e897bd82 SS |
134 | |
135 | [tool.hatch.envs.default] | |
136 | features = ["curl-cffi", "default"] | |
137 | dependencies = ["pre-commit"] | |
138 | path = ".venv" | |
139 | installer = "uv" | |
140 | ||
141 | [tool.hatch.envs.default.scripts] | |
142 | setup = "pre-commit install --config .pre-commit-hatch.yaml" | |
143 | yt-dlp = "python -Werror -Xdev -m yt_dlp {args}" | |
144 | ||
145 | [tool.hatch.envs.hatch-static-analysis] | |
146 | detached = true | |
147 | features = ["static-analysis"] | |
148 | dependencies = [] # override hatch ruff version | |
149 | config-path = "pyproject.toml" | |
150 | ||
151 | [tool.hatch.envs.hatch-static-analysis.scripts] | |
152 | format-check = "autopep8 --diff {args:.}" | |
153 | format-fix = "autopep8 --in-place {args:.}" | |
154 | lint-check = "ruff check {args:.}" | |
155 | lint-fix = "ruff check --fix {args:.}" | |
156 | ||
157 | [tool.hatch.envs.hatch-test] | |
158 | features = ["test"] | |
159 | dependencies = [ | |
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] | |
166 | run = "python -m devscripts.run_tests {args}" | |
167 | run-cov = "echo Code coverage not implemented && exit 1" | |
168 | ||
169 | [[tool.hatch.envs.hatch-test.matrix]] | |
170 | python = [ | |
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] | |
182 | line-length = 120 | |
183 | ||
184 | [tool.ruff.lint] | |
185 | ignore = [ | |
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 | ] |
222 | select = [ | |
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] | |
267 | known-first-party = [ | |
268 | "bundle", | |
269 | "devscripts", | |
270 | "test", | |
271 | ] | |
272 | relative-imports-order = "closest-to-furthest" | |
273 | ||
add96eb9 | 274 | [tool.ruff.lint.flake8-quotes] |
275 | docstring-quotes = "double" | |
276 | multiline-quotes = "single" | |
277 | inline-quotes = "single" | |
278 | avoid-escape = false | |
279 | ||
280 | [tool.ruff.lint.pep8-naming] | |
281 | classmethod-decorators = [ | |
282 | "yt_dlp.utils.classproperty", | |
283 | ] | |
284 | ||
285 | [tool.ruff.lint.flake8-import-conventions] | |
286 | banned-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", | |
6aaf96a3 | 302 | "urllib.parse", |
add96eb9 | 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] |
319 | max_line_length = 120 | |
320 | recursive = true | |
321 | exit-code = true | |
322 | jobs = 0 | |
323 | select = [ | |
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] | |
381 | addopts = "-ra -v --strict-markers" | |
382 | markers = [ | |
383 | "download", | |
384 | ] |