Skip to content

Commit

Permalink
[cleanup] Add more ruff rules (yt-dlp#10149)
Browse files Browse the repository at this point in the history
Authored by: seproDev

Reviewed-by: bashonly <[email protected]>
Reviewed-by: Simon Sawicki <[email protected]>
  • Loading branch information
seproDev authored Jun 11, 2024
1 parent db50f19 commit add96eb
Show file tree
Hide file tree
Showing 915 changed files with 7,028 additions and 7,247 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ After you have ensured this site is distributing its content legally, you can fo
$ hatch fmt --check
```

You can use `hatch fmt` to automatically fix problems.
You can use `hatch fmt` to automatically fix problems. Rules that the linter/formatter enforces should not be disabled with `# noqa` unless a maintainer requests it. The only exception allowed is for old/printf-style string formatting in GraphQL query templates (use `# noqa: UP031`).

1. Make sure your code works under all [Python](https://www.python.org/) versions supported by yt-dlp, namely CPython and PyPy for Python 3.8 and above. Backward compatibility is not required for even older versions of Python.
1. When the tests pass, [add](https://git-scm.com/docs/git-add) the new files, [commit](https://git-scm.com/docs/git-commit) them and [push](https://git-scm.com/docs/git-push) the result, like this:
Expand Down
2 changes: 1 addition & 1 deletion bundle/py2exe.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def main():
'Cryptodome',
# requests >=2.32.0 breaks py2exe builds due to certifi dependency
'requests',
'urllib3'
'urllib3',
],
'dll_excludes': ['w9xpopen.exe', 'crypt32.dll'],
# Modules that are only imported dynamically must be added here
Expand Down
8 changes: 4 additions & 4 deletions bundle/pyinstaller.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def exe(onedir):
'dist/',
onedir and f'{name}/',
name,
OS_NAME == 'win32' and '.exe'
OS_NAME == 'win32' and '.exe',
)))


Expand Down Expand Up @@ -113,7 +113,7 @@ def windows_set_version(exe, version):
),
kids=[
StringFileInfo([StringTable('040904B0', [
StringStruct('Comments', 'yt-dlp%s Command Line Interface' % suffix),
StringStruct('Comments', f'yt-dlp{suffix} Command Line Interface'),
StringStruct('CompanyName', 'https://github.com/yt-dlp'),
StringStruct('FileDescription', 'yt-dlp%s' % (MACHINE and f' ({MACHINE})')),
StringStruct('FileVersion', version),
Expand All @@ -123,8 +123,8 @@ def windows_set_version(exe, version):
StringStruct('ProductName', f'yt-dlp{suffix}'),
StringStruct(
'ProductVersion', f'{version}{suffix} on Python {platform.python_version()}'),
])]), VarFileInfo([VarStruct('Translation', [0, 1200])])
]
])]), VarFileInfo([VarStruct('Translation', [0, 1200])]),
],
))


Expand Down
8 changes: 4 additions & 4 deletions devscripts/bash-completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

import yt_dlp

BASH_COMPLETION_FILE = "completions/bash/yt-dlp"
BASH_COMPLETION_TEMPLATE = "devscripts/bash-completion.in"
BASH_COMPLETION_FILE = 'completions/bash/yt-dlp'
BASH_COMPLETION_TEMPLATE = 'devscripts/bash-completion.in'


def build_completion(opt_parser):
Expand All @@ -21,9 +21,9 @@ def build_completion(opt_parser):
opts_flag.append(option.get_opt_string())
with open(BASH_COMPLETION_TEMPLATE) as f:
template = f.read()
with open(BASH_COMPLETION_FILE, "w") as f:
with open(BASH_COMPLETION_FILE, 'w') as f:
# just using the special char
filled_template = template.replace("{{flags}}", " ".join(opts_flag))
filled_template = template.replace('{{flags}}', ' '.join(opts_flag))
f.write(filled_template)


Expand Down
10 changes: 5 additions & 5 deletions devscripts/make_changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,10 @@ def format_single_change(self, info: CommitInfo):

return message if not sep else f'{message}{sep}{rest}'

def _format_message_link(self, message, hash):
assert message or hash, 'Improperly defined commit message or override'
message = message if message else hash[:HASH_LENGTH]
return f'[{message}]({self.repo_url}/commit/{hash})' if hash else message
def _format_message_link(self, message, commit_hash):
assert message or commit_hash, 'Improperly defined commit message or override'
message = message if message else commit_hash[:HASH_LENGTH]
return f'[{message}]({self.repo_url}/commit/{commit_hash})' if commit_hash else message

def _format_issues(self, issues):
return ', '.join(f'[#{issue}]({self.repo_url}/issues/{issue})' for issue in issues)
Expand Down Expand Up @@ -356,7 +356,7 @@ def apply_overrides(self, overrides):
logger.info(f'CHANGE {self._commits[commit.hash]} -> {commit}')
self._commits[commit.hash] = commit

self._commits = {key: value for key, value in reversed(self._commits.items())}
self._commits = dict(reversed(self._commits.items()))

def groups(self):
group_dict = defaultdict(list)
Expand Down
12 changes: 6 additions & 6 deletions devscripts/make_readme.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def apply_patch(text, patch):
),
( # Headings
r'(?m)^ (\w.+\n)( (?=\w))?',
r'## \1'
r'## \1',
),
( # Fixup `--date` formatting
rf'(?m)( --date DATE.+({delim}[^\[]+)*)\[.+({delim}.+)*$',
Expand All @@ -61,26 +61,26 @@ def apply_patch(text, patch):
),
( # Do not split URLs
rf'({delim[:-1]})? (?P<label>\[\S+\] )?(?P<url>https?({delim})?:({delim})?/({delim})?/(({delim})?\S+)+)\s',
lambda mobj: ''.join((delim, mobj.group('label') or '', re.sub(r'\s+', '', mobj.group('url')), '\n'))
lambda mobj: ''.join((delim, mobj.group('label') or '', re.sub(r'\s+', '', mobj.group('url')), '\n')),
),
( # Do not split "words"
rf'(?m)({delim}\S+)+$',
lambda mobj: ''.join((delim, mobj.group(0).replace(delim, '')))
lambda mobj: ''.join((delim, mobj.group(0).replace(delim, ''))),
),
( # Allow overshooting last line
rf'(?m)^(?P<prev>.+)${delim}(?P<current>.+)$(?!{delim})',
lambda mobj: (mobj.group().replace(delim, ' ')
if len(mobj.group()) - len(delim) + 1 <= max_width + ALLOWED_OVERSHOOT
else mobj.group())
else mobj.group()),
),
( # Avoid newline when a space is available b/w switch and description
DISABLE_PATCH, # This creates issues with prepare_manpage
r'(?m)^(\s{4}-.{%d})(%s)' % (switch_col_width - 6, delim),
r'\1 '
r'\1 ',
),
( # Replace brackets with a Markdown link
r'SponsorBlock API \((http.+)\)',
r'[SponsorBlock API](\1)'
r'[SponsorBlock API](\1)',
),
)

Expand Down
2 changes: 1 addition & 1 deletion devscripts/set-variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def property_setter(name, value):
opts = parse_options()
transform = compose_functions(
property_setter('VARIANT', opts.variant),
property_setter('UPDATE_HINT', opts.update_message)
property_setter('UPDATE_HINT', opts.update_message),
)

write_file(VERSION_FILE, transform(read_file(VERSION_FILE)))
2 changes: 1 addition & 1 deletion devscripts/update-version.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def get_new_version(version, revision):
else:
old_version = read_version().split('.')
if version.split('.') == old_version[:3]:
revision = str(int((old_version + [0])[3]) + 1)
revision = str(int(([*old_version, 0])[3]) + 1)

return f'{version}.{revision}' if revision else version

Expand Down
16 changes: 8 additions & 8 deletions devscripts/zsh-completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@

import yt_dlp

ZSH_COMPLETION_FILE = "completions/zsh/_yt-dlp"
ZSH_COMPLETION_TEMPLATE = "devscripts/zsh-completion.in"
ZSH_COMPLETION_FILE = 'completions/zsh/_yt-dlp'
ZSH_COMPLETION_TEMPLATE = 'devscripts/zsh-completion.in'


def build_completion(opt_parser):
opts = [opt for group in opt_parser.option_groups
for opt in group.option_list]
opts_file = [opt for opt in opts if opt.metavar == "FILE"]
opts_dir = [opt for opt in opts if opt.metavar == "DIR"]
opts_file = [opt for opt in opts if opt.metavar == 'FILE']
opts_dir = [opt for opt in opts if opt.metavar == 'DIR']

fileopts = []
for opt in opts_file:
Expand All @@ -38,11 +38,11 @@ def build_completion(opt_parser):
with open(ZSH_COMPLETION_TEMPLATE) as f:
template = f.read()

template = template.replace("{{fileopts}}", "|".join(fileopts))
template = template.replace("{{diropts}}", "|".join(diropts))
template = template.replace("{{flags}}", " ".join(flags))
template = template.replace('{{fileopts}}', '|'.join(fileopts))
template = template.replace('{{diropts}}', '|'.join(diropts))
template = template.replace('{{flags}}', ' '.join(flags))

with open(ZSH_COMPLETION_FILE, "w") as f:
with open(ZSH_COMPLETION_FILE, 'w') as f:
f.write(template)


Expand Down
127 changes: 117 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -183,21 +183,84 @@ line-length = 120

[tool.ruff.lint]
ignore = [
"E402", # module level import not at top of file
"E501", # line too long
"E731", # do not assign a lambda expression, use a def
"E741", # ambiguous variable name
"E402", # module-import-not-at-top-of-file
"E501", # line-too-long
"E731", # lambda-assignment
"E741", # ambiguous-variable-name
"UP036", # outdated-version-block
"B006", # mutable-argument-default
"B008", # function-call-in-default-argument
"B011", # assert-false
"B017", # assert-raises-exception
"B023", # function-uses-loop-variable (false positives)
"B028", # no-explicit-stacklevel
"B904", # raise-without-from-inside-except
"C401", # unnecessary-generator-set
"C402", # unnecessary-generator-dict
"PIE790", # unnecessary-placeholder
"SIM102", # collapsible-if
"SIM108", # if-else-block-instead-of-if-exp
"SIM112", # uncapitalized-environment-variables
"SIM113", # enumerate-for-loop
"SIM114", # if-with-same-arms
"SIM115", # open-file-with-context-handler
"SIM117", # multiple-with-statements
"SIM223", # expr-and-false
"SIM300", # yoda-conditions
"TD001", # invalid-todo-tag
"TD002", # missing-todo-author
"TD003", # missing-todo-link
"PLE0604", # invalid-all-object (false positives)
"PLW0603", # global-statement
"PLW1510", # subprocess-run-without-check
"PLW2901", # redefined-loop-name
"RUF001", # ambiguous-unicode-character-string
"RUF012", # mutable-class-default
"RUF100", # unused-noqa (flake8 has slightly different behavior)
]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # import order
"E", # pycodestyle Error
"W", # pycodestyle Warning
"F", # Pyflakes
"I", # isort
"Q", # flake8-quotes
"N803", # invalid-argument-name
"N804", # invalid-first-argument-name-for-class-method
"UP", # pyupgrade
"B", # flake8-bugbear
"A", # flake8-builtins
"COM", # flake8-commas
"C4", # flake8-comprehensions
"FA", # flake8-future-annotations
"ISC", # flake8-implicit-str-concat
"ICN003", # banned-import-from
"PIE", # flake8-pie
"T20", # flake8-print
"RSE", # flake8-raise
"RET504", # unnecessary-assign
"SIM", # flake8-simplify
"TID251", # banned-api
"TD", # flake8-todos
"PLC", # Pylint Convention
"PLE", # Pylint Error
"PLW", # Pylint Warning
"RUF", # Ruff-specific rules
]

[tool.ruff.lint.per-file-ignores]
"devscripts/lazy_load_template.py" = ["F401"]
"!yt_dlp/extractor/**.py" = ["I"]
"devscripts/lazy_load_template.py" = [
"F401", # unused-import
]
"!yt_dlp/extractor/**.py" = [
"I", # isort
"ICN003", # banned-import-from
"T20", # flake8-print
"A002", # builtin-argument-shadowing
"C408", # unnecessary-collection-call
]
"yt_dlp/jsinterp.py" = [
"UP031", # printf-string-formatting
]

[tool.ruff.lint.isort]
known-first-party = [
Expand All @@ -207,6 +270,50 @@ known-first-party = [
]
relative-imports-order = "closest-to-furthest"

[tool.ruff.lint.flake8-quotes]
docstring-quotes = "double"
multiline-quotes = "single"
inline-quotes = "single"
avoid-escape = false

[tool.ruff.lint.pep8-naming]
classmethod-decorators = [
"yt_dlp.utils.classproperty",
]

[tool.ruff.lint.flake8-import-conventions]
banned-from = [
"base64",
"datetime",
"functools",
"glob",
"hashlib",
"itertools",
"json",
"math",
"os",
"pathlib",
"random",
"re",
"string",
"sys",
"time",
"urllib",
"uuid",
"xml",
]

[tool.ruff.lint.flake8-tidy-imports.banned-api]
"yt_dlp.compat.compat_str".msg = "Use `str` instead."
"yt_dlp.compat.compat_b64decode".msg = "Use `base64.b64decode` instead."
"yt_dlp.compat.compat_urlparse".msg = "Use `urllib.parse` instead."
"yt_dlp.compat.compat_parse_qs".msg = "Use `urllib.parse.parse_qs` instead."
"yt_dlp.compat.compat_urllib_parse_unquote".msg = "Use `urllib.parse.unquote` instead."
"yt_dlp.compat.compat_urllib_parse_urlencode".msg = "Use `urllib.parse.urlencode` instead."
"yt_dlp.compat.compat_urllib_parse_urlparse".msg = "Use `urllib.parse.urlparse` instead."
"yt_dlp.compat.compat_shlex_quote".msg = "Use `yt_dlp.utils.shell_quote` instead."
"yt_dlp.utils.error_to_compat_str".msg = "Use `str` instead."

[tool.autopep8]
max_line_length = 120
recursive = true
Expand Down
10 changes: 5 additions & 5 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ def handler(request):
class HandlerWrapper(handler):
RH_KEY = handler.RH_KEY

def __init__(self, *args, **kwargs):
super().__init__(logger=FakeLogger, *args, **kwargs)
def __init__(self, **kwargs):
super().__init__(logger=FakeLogger, **kwargs)

return HandlerWrapper

Expand Down Expand Up @@ -54,11 +54,11 @@ def skip_handlers_if(request, handler):

def pytest_configure(config):
config.addinivalue_line(
"markers", "skip_handler(handler): skip test for the given handler",
'markers', 'skip_handler(handler): skip test for the given handler',
)
config.addinivalue_line(
"markers", "skip_handler_if(handler): skip test for the given handler if condition is true"
'markers', 'skip_handler_if(handler): skip test for the given handler if condition is true',
)
config.addinivalue_line(
"markers", "skip_handlers_if(handler): skip test for handlers when the condition is true"
'markers', 'skip_handlers_if(handler): skip test for handlers when the condition is true',
)
Loading

0 comments on commit add96eb

Please sign in to comment.