Skip to content

Commit cf1d532

Browse files
authored
Merge pull request #68 from ProperDocs/lints
Enable and fix many Ruff lints
2 parents 1fe770f + 8cc173b commit cf1d532

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+224
-251
lines changed

properdocs/__main__.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#!/usr/bin/env python
2-
31
from __future__ import annotations
42

53
import logging
@@ -9,6 +7,7 @@
97
import textwrap
108
import traceback
119
import warnings
10+
from typing import ClassVar
1211

1312
import click
1413

@@ -41,7 +40,7 @@ def _showwarning(message, category, filename, lineno, file=None, line=None):
4140
stack = [frame for frame in traceback.extract_stack() if frame.line][-4:-2]
4241
# Make sure the actual affected file's name is still present (the case of syntax warning):
4342
if not any(frame.filename == filename for frame in stack):
44-
stack = stack[-1:] + [traceback.FrameSummary(filename, lineno, '')]
43+
stack = [*stack[-1:], traceback.FrameSummary(filename, lineno, '')]
4544

4645
tb = ''.join(traceback.format_list(stack))
4746
except Exception:
@@ -64,7 +63,7 @@ def _enable_warnings():
6463

6564

6665
class ColorFormatter(logging.Formatter):
67-
colors = {
66+
colors: ClassVar = {
6867
'CRITICAL': 'red',
6968
'ERROR': 'red',
7069
'WARNING': 'yellow',

properdocs/commands/build.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,7 @@ def _build_template(
8787
output = template.render(context)
8888

8989
# Run `post_template` plugin events.
90-
output = config.plugins.on_post_template(output, template_name=name, config=config)
91-
92-
return output
90+
return config.plugins.on_post_template(output, template_name=name, config=config)
9391

9492

9593
def _build_theme_template(
@@ -321,8 +319,8 @@ def build(config: ProperDocsConfig, *, serve_url: str | None = None, dirty: bool
321319
if excluded:
322320
log.info(
323321
"The following pages are being built only for the preview "
324-
"but will be excluded from `properdocs build` per `draft_docs` config:\n - "
325-
+ "\n - ".join(excluded)
322+
"but will be excluded from `properdocs build` per `draft_docs` config:\n - %s",
323+
"\n - ".join(excluded),
326324
)
327325

328326
# Run `env` plugin events.

properdocs/commands/get_deps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
log = logging.getLogger(__name__)
2828

2929

30-
class YamlLoaderWithSuppressions(SafeLoader): # type: ignore
30+
class YamlLoaderWithSuppressions(SafeLoader): # type: ignore # noqa: PGH003
3131
pass
3232

3333

properdocs/commands/gh_deploy.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import subprocess
77
from typing import TYPE_CHECKING
88

9-
import ghp_import # type: ignore
9+
import ghp_import # type: ignore[import-untyped]
1010
from packaging import version
1111

1212
import properdocs
@@ -43,8 +43,7 @@ def _get_current_sha(repo_path) -> str:
4343
)
4444

4545
stdout, _ = proc.communicate()
46-
sha = stdout.decode('utf-8').strip()
47-
return sha
46+
return stdout.decode('utf-8').strip()
4847

4948

5049
def _get_remote_url(remote_name: str) -> tuple[str, str] | tuple[None, None]:
@@ -78,7 +77,9 @@ def _check_version(branch: str) -> None:
7877

7978
stdout, _ = proc.communicate()
8079
msg = stdout.decode('utf-8').strip()
81-
m = re.search(r'\d+(\.\d+)+((a|b|rc)\d+)?(\.post\d+)?(\.dev\d+)?', msg, re.X | re.I)
80+
m = re.search(
81+
r'\d+(\.\d+)+((a|b|rc)\d+)?(\.post\d+)?(\.dev\d+)?', msg, re.VERBOSE | re.IGNORECASE
82+
)
8283
previousv = version.parse(m.group()) if m else None
8384
currentv = version.parse(properdocs.__version__)
8485
if not previousv:
@@ -145,7 +146,7 @@ def gh_deploy(
145146
# Does this repository have a CNAME set for GitHub Pages?
146147
if os.path.isfile(cname_file):
147148
# This GitHub Pages repository has a CNAME configured.
148-
with open(cname_file) as f:
149+
with open(cname_file, encoding='utf-8') as f:
149150
cname_host = f.read().strip()
150151
log.info(
151152
f'Based on your CNAME file, your documentation should be '
@@ -163,7 +164,6 @@ def gh_deploy(
163164
log.info('Your documentation should be available shortly.')
164165
else:
165166
username, repo = path.split('/', 1)
166-
if repo.endswith('.git'):
167-
repo = repo[: -len('.git')]
167+
repo = repo.removesuffix('.git')
168168
url = f'https://{username}.github.io/{repo}/'
169169
log.info(f"Your documentation should shortly be available at: {url}")

properdocs/config/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
from properdocs.config.base import Config, load_config
22

3-
__all__ = ['load_config', 'Config']
3+
__all__ = ['Config', 'load_config']

properdocs/config/base.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from __future__ import annotations
22

3+
import contextlib
34
import functools
45
import logging
56
import os
67
import sys
78
import warnings
89
from collections import UserDict
910
from collections.abc import Iterator, Mapping, Sequence
10-
from contextlib import contextmanager
1111
from typing import IO, TYPE_CHECKING, Any, Generic, TypeVar, overload
1212

1313
from properdocs import exceptions, utils
@@ -136,7 +136,7 @@ def __init_subclass__(cls):
136136
"All values are required, or can be wrapped into config_options.Optional"
137137
)
138138

139-
def __new__(cls, *args, **kwargs) -> Config:
139+
def __new__(cls, *args, **kwargs) -> Config: # noqa: PYI034
140140
"""Compatibility: allow referring to `LegacyConfig(...)` constructor as `Config(...)`."""
141141
if cls is Config:
142142
return LegacyConfig(*args, **kwargs)
@@ -273,7 +273,7 @@ def __init__(self, schema: PlainConfigSchema, config_file_path: str | None = Non
273273
super().__init__(config_file_path)
274274

275275

276-
@contextmanager
276+
@contextlib.contextmanager
277277
def _open_config_file(config_file: str | IO | None) -> Iterator[IO]:
278278
"""
279279
A context manager which yields an open file descriptor ready to be read.
@@ -314,10 +314,8 @@ def _open_config_file(config_file: str | IO | None) -> Iterator[IO]:
314314
else:
315315
log.debug(f"Loading configuration file: {result_config_file}")
316316
# Ensure file descriptor is at beginning
317-
try:
317+
with contextlib.suppress(OSError):
318318
result_config_file.seek(0)
319-
except OSError:
320-
pass
321319

322320
try:
323321
yield result_config_file

properdocs/config/config_options.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import contextlib
34
import functools
45
import importlib.util
56
import ipaddress
@@ -13,7 +14,7 @@
1314
from collections import Counter, UserString
1415
from collections.abc import Callable, Collection, Iterator, Mapping, MutableMapping
1516
from types import SimpleNamespace
16-
from typing import Any, Generic, NamedTuple, TypeVar, Union, overload
17+
from typing import Any, Generic, NamedTuple, TypeVar, overload
1718
from urllib.parse import quote as urlquote
1819
from urllib.parse import urlsplit, urlunsplit
1920

@@ -93,7 +94,7 @@ def pre_validation(self, config: Config, key_name: str):
9394
def run_validation(self, value: object) -> SomeConfig:
9495
config = self.config_class(config_file_path=self._config_file_path)
9596
try:
96-
config.load_dict(value) # type: ignore
97+
config.load_dict(value) # type: ignore[arg-type]
9798
failed, warnings = config.validate()
9899
except ConfigurationError as e:
99100
raise ValidationError(str(e))
@@ -204,15 +205,13 @@ def run_validation(self, value: object) -> list[T]:
204205
return value
205206

206207
fake_config = LegacyConfig(())
207-
try:
208+
with contextlib.suppress(AttributeError):
208209
fake_config.config_file_path = self._config.config_file_path
209-
except AttributeError:
210-
pass
211210

212211
# Emulate a config-like environment for pre_validation and post_validation.
213212
parent_key_name = getattr(self, '_key_name', '')
214213
fake_keys = [f'{parent_key_name}[{i}]' for i in range(len(value))]
215-
fake_config.data = dict(zip(fake_keys, value))
214+
fake_config.data = dict(zip(fake_keys, value, strict=True))
216215

217216
self.option_type.warnings = self.warnings
218217
for key_name in fake_config:
@@ -259,10 +258,8 @@ def run_validation(self, value: object) -> dict[str, T]:
259258
return value
260259

261260
fake_config = LegacyConfig(())
262-
try:
261+
with contextlib.suppress(AttributeError):
263262
fake_config.config_file_path = self._config.config_file_path
264-
except AttributeError:
265-
pass
266263

267264
# Emulate a config-like environment for pre_validation and post_validation.
268265
fake_config.data = value
@@ -362,7 +359,7 @@ def __init__(self, choices: Collection[T], default: T | None = None, **kwargs) -
362359
def run_validation(self, value: object) -> T:
363360
if value not in self.choices:
364361
raise ValidationError(f"Expected one of: {self.choices} but received: {value!r}")
365-
return value # type: ignore
362+
return value # type: ignore[return-value]
366363

367364

368365
class Deprecated(BaseConfigOption):
@@ -508,7 +505,7 @@ def run_validation(self, value: object) -> str:
508505
raise ValidationError("The URL isn't valid, it should include the http:// (scheme)")
509506

510507

511-
class Optional(Generic[T], BaseConfigOption[Union[T, None]]):
508+
class Optional(Generic[T], BaseConfigOption[T | None]):
512509
"""
513510
Wraps a field and makes a None value possible for it when no value is set.
514511
@@ -539,7 +536,7 @@ def run_validation(self, value: object) -> T | None:
539536
return self.option.validate(value)
540537

541538
def post_validation(self, config: Config, key_name: str):
542-
result = self.option.post_validation(config, key_name) # type: ignore
539+
result = self.option.post_validation(config, key_name) # type: ignore[func-returns-value]
543540
self.warnings = self.option.warnings
544541
return result
545542

@@ -940,7 +937,7 @@ def __fspath__(self):
940937
return self.path
941938

942939

943-
class ExtraScript(BaseConfigOption[Union[ExtraScriptValue, str]]):
940+
class ExtraScript(BaseConfigOption[ExtraScriptValue | str]):
944941
def __init__(self):
945942
super().__init__()
946943
self.option_type = SubConfig[ExtraScriptValue]()

properdocs/contrib/search/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def get_lunr_supported_lang(self, lang):
3030
lang_part = fallback.get(lang_part, lang_part)
3131
if os.path.isfile(os.path.join(base_path, 'lunr-language', f'lunr.{lang_part}.js')):
3232
return lang_part
33+
return None
3334

3435
def run_validation(self, value: object):
3536
if isinstance(value, str):
@@ -70,7 +71,7 @@ def on_config(self, config: ProperDocsConfig, **kwargs) -> ProperDocsConfig:
7071
path = os.path.join(base_path, 'templates')
7172
config.theme.dirs.append(path)
7273
if 'search/main.js' not in config.extra_javascript:
73-
config.extra_javascript.append('search/main.js') # type: ignore
74+
config.extra_javascript.append('search/main.js')
7475
if self.config.lang is None:
7576
# lang setting undefined. Set default based on theme locale
7677
validate = _PluginConfig.lang.run_validation

properdocs/contrib/search/search_index.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from properdocs.structure.toc import AnchorLink, TableOfContents
1414

1515
try:
16-
from lunr import lunr # type: ignore
16+
from lunr import lunr # type: ignore[import-not-found]
1717

1818
haslunrpy = True
1919
except ImportError:

properdocs/livereload/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import contextlib
34
import functools
45
import io
56
import ipaddress
@@ -375,8 +376,6 @@ def _timestamp() -> int:
375376
def _try_relativize_path(path: str) -> str:
376377
"""Make the path relative to current directory if it's under that directory."""
377378
p = pathlib.Path(path)
378-
try:
379+
with contextlib.suppress(ValueError):
379380
p = p.relative_to(os.getcwd())
380-
except ValueError:
381-
pass
382381
return str(p)

0 commit comments

Comments
 (0)