Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions properdocs/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python

from __future__ import annotations

import logging
Expand All @@ -9,6 +7,7 @@
import textwrap
import traceback
import warnings
from typing import ClassVar

import click

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

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


class ColorFormatter(logging.Formatter):
colors = {
colors: ClassVar = {
'CRITICAL': 'red',
'ERROR': 'red',
'WARNING': 'yellow',
Expand Down
8 changes: 3 additions & 5 deletions properdocs/commands/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ def _build_template(
output = template.render(context)

# Run `post_template` plugin events.
output = config.plugins.on_post_template(output, template_name=name, config=config)

return output
return config.plugins.on_post_template(output, template_name=name, config=config)


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

# Run `env` plugin events.
Expand Down
2 changes: 1 addition & 1 deletion properdocs/commands/get_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
log = logging.getLogger(__name__)


class YamlLoaderWithSuppressions(SafeLoader): # type: ignore
class YamlLoaderWithSuppressions(SafeLoader): # type: ignore # noqa: PGH003
pass


Expand Down
14 changes: 7 additions & 7 deletions properdocs/commands/gh_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import subprocess
from typing import TYPE_CHECKING

import ghp_import # type: ignore
import ghp_import # type: ignore[import-untyped]
from packaging import version

import properdocs
Expand Down Expand Up @@ -43,8 +43,7 @@ def _get_current_sha(repo_path) -> str:
)

stdout, _ = proc.communicate()
sha = stdout.decode('utf-8').strip()
return sha
return stdout.decode('utf-8').strip()


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

stdout, _ = proc.communicate()
msg = stdout.decode('utf-8').strip()
m = re.search(r'\d+(\.\d+)+((a|b|rc)\d+)?(\.post\d+)?(\.dev\d+)?', msg, re.X | re.I)
m = re.search(
r'\d+(\.\d+)+((a|b|rc)\d+)?(\.post\d+)?(\.dev\d+)?', msg, re.VERBOSE | re.IGNORECASE
)
previousv = version.parse(m.group()) if m else None
currentv = version.parse(properdocs.__version__)
if not previousv:
Expand Down Expand Up @@ -145,7 +146,7 @@ def gh_deploy(
# Does this repository have a CNAME set for GitHub Pages?
if os.path.isfile(cname_file):
# This GitHub Pages repository has a CNAME configured.
with open(cname_file) as f:
with open(cname_file, encoding='utf-8') as f:
cname_host = f.read().strip()
log.info(
f'Based on your CNAME file, your documentation should be '
Expand All @@ -163,7 +164,6 @@ def gh_deploy(
log.info('Your documentation should be available shortly.')
else:
username, repo = path.split('/', 1)
if repo.endswith('.git'):
repo = repo[: -len('.git')]
repo = repo.removesuffix('.git')
url = f'https://{username}.github.io/{repo}/'
log.info(f"Your documentation should shortly be available at: {url}")
2 changes: 1 addition & 1 deletion properdocs/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from properdocs.config.base import Config, load_config

__all__ = ['load_config', 'Config']
__all__ = ['Config', 'load_config']
10 changes: 4 additions & 6 deletions properdocs/config/base.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from __future__ import annotations

import contextlib
import functools
import logging
import os
import sys
import warnings
from collections import UserDict
from collections.abc import Iterator, Mapping, Sequence
from contextlib import contextmanager
from typing import IO, TYPE_CHECKING, Any, Generic, TypeVar, overload

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

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


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

try:
yield result_config_file
Expand Down
23 changes: 10 additions & 13 deletions properdocs/config/config_options.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import contextlib
import functools
import importlib.util
import ipaddress
Expand All @@ -13,7 +14,7 @@
from collections import Counter, UserString
from collections.abc import Callable, Collection, Iterator, Mapping, MutableMapping
from types import SimpleNamespace
from typing import Any, Generic, NamedTuple, TypeVar, Union, overload
from typing import Any, Generic, NamedTuple, TypeVar, overload
from urllib.parse import quote as urlquote
from urllib.parse import urlsplit, urlunsplit

Expand Down Expand Up @@ -93,7 +94,7 @@ def pre_validation(self, config: Config, key_name: str):
def run_validation(self, value: object) -> SomeConfig:
config = self.config_class(config_file_path=self._config_file_path)
try:
config.load_dict(value) # type: ignore
config.load_dict(value) # type: ignore[arg-type]
failed, warnings = config.validate()
except ConfigurationError as e:
raise ValidationError(str(e))
Expand Down Expand Up @@ -204,15 +205,13 @@ def run_validation(self, value: object) -> list[T]:
return value

fake_config = LegacyConfig(())
try:
with contextlib.suppress(AttributeError):
fake_config.config_file_path = self._config.config_file_path
except AttributeError:
pass

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

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

fake_config = LegacyConfig(())
try:
with contextlib.suppress(AttributeError):
fake_config.config_file_path = self._config.config_file_path
except AttributeError:
pass

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


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


class Optional(Generic[T], BaseConfigOption[Union[T, None]]):
class Optional(Generic[T], BaseConfigOption[T | None]):
"""
Wraps a field and makes a None value possible for it when no value is set.

Expand Down Expand Up @@ -539,7 +536,7 @@ def run_validation(self, value: object) -> T | None:
return self.option.validate(value)

def post_validation(self, config: Config, key_name: str):
result = self.option.post_validation(config, key_name) # type: ignore
result = self.option.post_validation(config, key_name) # type: ignore[func-returns-value]
self.warnings = self.option.warnings
return result

Expand Down Expand Up @@ -940,7 +937,7 @@ def __fspath__(self):
return self.path


class ExtraScript(BaseConfigOption[Union[ExtraScriptValue, str]]):
class ExtraScript(BaseConfigOption[ExtraScriptValue | str]):
def __init__(self):
super().__init__()
self.option_type = SubConfig[ExtraScriptValue]()
Expand Down
3 changes: 2 additions & 1 deletion properdocs/contrib/search/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def get_lunr_supported_lang(self, lang):
lang_part = fallback.get(lang_part, lang_part)
if os.path.isfile(os.path.join(base_path, 'lunr-language', f'lunr.{lang_part}.js')):
return lang_part
return None

def run_validation(self, value: object):
if isinstance(value, str):
Expand Down Expand Up @@ -70,7 +71,7 @@ def on_config(self, config: ProperDocsConfig, **kwargs) -> ProperDocsConfig:
path = os.path.join(base_path, 'templates')
config.theme.dirs.append(path)
if 'search/main.js' not in config.extra_javascript:
config.extra_javascript.append('search/main.js') # type: ignore
config.extra_javascript.append('search/main.js')
if self.config.lang is None:
# lang setting undefined. Set default based on theme locale
validate = _PluginConfig.lang.run_validation
Expand Down
2 changes: 1 addition & 1 deletion properdocs/contrib/search/search_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from properdocs.structure.toc import AnchorLink, TableOfContents

try:
from lunr import lunr # type: ignore
from lunr import lunr # type: ignore[import-not-found]

haslunrpy = True
except ImportError:
Expand Down
5 changes: 2 additions & 3 deletions properdocs/livereload/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import contextlib
import functools
import io
import ipaddress
Expand Down Expand Up @@ -375,8 +376,6 @@ def _timestamp() -> int:
def _try_relativize_path(path: str) -> str:
"""Make the path relative to current directory if it's under that directory."""
p = pathlib.Path(path)
try:
with contextlib.suppress(ValueError):
p = p.relative_to(os.getcwd())
except ValueError:
pass
return str(p)
2 changes: 1 addition & 1 deletion properdocs/localization.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

has_babel = True
except ImportError: # pragma: no cover
from properdocs.utils.babel_stub import Locale, UnknownLocaleError # type: ignore
from properdocs.utils.babel_stub import Locale, UnknownLocaleError # type: ignore[assignment]

has_babel = False

Expand Down
15 changes: 7 additions & 8 deletions properdocs/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

from __future__ import annotations

import contextlib
import logging
from collections.abc import Callable, MutableMapping
from importlib.metadata import EntryPoint, entry_points
from typing import TYPE_CHECKING, Any, Concatenate, Generic, Literal, TypeVar, overload

if TYPE_CHECKING:
import jinja2

from properdocs import utils
from properdocs.config.base import (
Config,
Expand All @@ -20,6 +18,8 @@
)

if TYPE_CHECKING:
import jinja2

from properdocs.config.defaults import ProperDocsConfig
from properdocs.livereload import LiveReloadServer
from properdocs.structure.files import Files
Expand Down Expand Up @@ -67,7 +67,7 @@ class BasePlugin(Generic[SomeConfig]):

config_class: type[SomeConfig] = LegacyConfig # type: ignore[assignment]
config_scheme: PlainConfigSchema = ()
config: SomeConfig = {} # type: ignore[assignment]
config: SomeConfig = {} # type: ignore[assignment] # noqa: RUF012

supports_multiple_instances: bool = False
"""Set to true in subclasses to declare support for adding the same plugin multiple times."""
Expand All @@ -90,7 +90,7 @@ def load_config(
) -> tuple[ConfigErrors, ConfigWarnings]:
"""Load config from a dict of options. Returns a tuple of (errors, warnings)."""
if self.config_class is LegacyConfig:
self.config = LegacyConfig(self.config_scheme, config_file_path=config_file_path) # type: ignore
self.config = LegacyConfig(self.config_scheme, config_file_path=config_file_path) # type: ignore[assignment]
else:
self.config = self.config_class(config_file_path=config_file_path)

Expand Down Expand Up @@ -527,10 +527,9 @@ def _register_event(
)
utils.insort(events, method, key=lambda m: -getattr(m, 'mkdocs_priority', 0))
if plugin_name:
try:
# Suppress in case the method is somehow not hashable.
with contextlib.suppress(TypeError):
self._event_origins[method] = plugin_name
except TypeError: # If the method is somehow not hashable.
pass

def __getitem__(self, key: str) -> BasePlugin:
return super().__getitem__(key)
Expand Down
2 changes: 1 addition & 1 deletion properdocs/replacement_warning.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@


def setup():
global _warning_message
global _warning_message # noqa: PLW0603
if not _warning_message:
return

Expand Down
2 changes: 1 addition & 1 deletion properdocs/structure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from properdocs.structure.nav import Section


class StructureItem(metaclass=abc.ABCMeta):
class StructureItem(abc.ABC):
"""An item in ProperDocs structure - see concrete subclasses Section, Page or Link."""

@abc.abstractmethod
Expand Down
Loading
Loading