Skip to content

Commit

Permalink
Introduce more ruff rules
Browse files Browse the repository at this point in the history
  • Loading branch information
Secrus committed Aug 30, 2024
1 parent da12e58 commit beb0492
Show file tree
Hide file tree
Showing 12 changed files with 117 additions and 109 deletions.
27 changes: 19 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,35 @@ fix = true
src = ["src"]
extend-exclude = [
"noxfile.py",
"docs/*"
"docs/*",
"tests/*"
]

[tool.ruff.lint]
select = [
"E",
"F",
"W",
"I",
"D",
extend-select = [
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"ERA", # flake8-eradicate/eradicate
"I", # isort
"N", # pep8-naming
"PIE", # flake8-pie
"PGH", # pygrep
"RUF", # ruff checks
"SIM", # flake8-simplify
"T20", # flake8-print
"TCH", # flake8-type-checking
"TID", # flake8-tidy-imports
"UP", # pyupgrade
"D", # pydocstyle
"PTH", # flake8-use-pathlib
]
ignore = [
"D105", "D203", "D213", "E501"
]

[tool.ruff.lint.per-file-ignores]
"tests/*" = ["D"]
"tools/*" = ["D"]
"tools/*" = ["D", "T20"]

[tool.ruff.lint.isort]
known-first-party = ["src"]
Expand Down
2 changes: 1 addition & 1 deletion src/installer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
__version__ = "1.0.0.dev0"
__all__ = ["install"]

from installer._core import install # noqa
from installer._core import install
2 changes: 1 addition & 1 deletion src/installer/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def _get_scheme_dict(
# calculate 'headers' path, not currently in sysconfig - see
# https://bugs.python.org/issue44445. This is based on what distutils does.
# TODO: figure out original vs normalised distribution names
scheme_dict["headers"] = os.path.join(
scheme_dict["headers"] = os.path.join( # noqa: PTH118
sysconfig.get_path("include", vars={"installed_base": installed_base}),
distribution_name,
)
Expand Down
2 changes: 1 addition & 1 deletion src/installer/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
__all__ = ["install"]


def _process_WHEEL_file(source: WheelSource) -> Scheme:
def _process_WHEEL_file(source: WheelSource) -> Scheme: # noqa: N802
"""Process the WHEEL file, from ``source``.
Returns the scheme that the archive root should go in.
Expand Down
30 changes: 14 additions & 16 deletions src/installer/destinations.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,11 @@ class SchemeDictionaryDestination(WheelDestination):
overwrite_existing: bool = False
"""Silently overwrite existing files."""

def _path_with_destdir(self, scheme: Scheme, path: str) -> str:
file = os.path.join(self.scheme_dict[scheme], path)
def _path_with_destdir(self, scheme: Scheme, path: str) -> Path:
file = Path(self.scheme_dict[scheme]) / path
if self.destdir is not None:
file_path = Path(file)
rel_path = file_path.relative_to(file_path.anchor)
return os.path.join(self.destdir, rel_path)
rel_path = file.relative_to(file.anchor)
return Path(self.destdir) / rel_path
return file

def write_to_fs(
Expand All @@ -164,15 +163,15 @@ def write_to_fs(
- Hashes the written content, to determine the entry in the ``RECORD`` file.
"""
target_path = self._path_with_destdir(scheme, path)
if not self.overwrite_existing and os.path.exists(target_path):
message = f"File already exists: {target_path}"
if not self.overwrite_existing and target_path.exists():
message = f"File already exists: {target_path!s}"
raise FileExistsError(message)

parent_folder = os.path.dirname(target_path)
if not os.path.exists(parent_folder):
os.makedirs(parent_folder)
parent_folder = target_path.parent
if not parent_folder.exists():
parent_folder.mkdir(parents=True)

with open(target_path, "wb") as f:
with target_path.open("wb") as f:
hash_, size = copyfileobj_with_hashing(stream, f, self.hash_algorithm)

if is_executable:
Expand Down Expand Up @@ -234,9 +233,9 @@ def write_script(
)

path = self._path_with_destdir(Scheme("scripts"), script_name)
mode = os.stat(path).st_mode
mode = path.stat().st_mode
mode |= (mode & 0o444) >> 2
os.chmod(path, mode)
path.chmod(mode)

return entry

Expand All @@ -248,9 +247,8 @@ def _compile_bytecode(self, scheme: Scheme, record: RecordEntry) -> None:
import compileall

target_path = self._path_with_destdir(scheme, record.path)
dir_path_to_embed = os.path.dirname( # Without destdir
os.path.join(self.scheme_dict[scheme], record.path)
)
dir_path_to_embed = (Path(self.scheme_dict[scheme]) / record.path).parent

for level in self.bytecode_optimization_levels:
compileall.compile_file(
target_path, optimize=level, quiet=1, ddir=dir_path_to_embed
Expand Down
2 changes: 1 addition & 1 deletion src/installer/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ class InstallerError(Exception):
"""All exceptions raised from this package's code."""


class InvalidWheelSource(InstallerError):
class InvalidWheelSource(InstallerError): # noqa: N818
"""When a wheel source violates a contract, or is not supported."""
13 changes: 5 additions & 8 deletions src/installer/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import hashlib
import os
from dataclasses import dataclass
from pathlib import Path
from typing import BinaryIO, Iterable, Iterator, Optional, Tuple, cast

from installer.utils import copyfileobj_with_hashing, get_stream_length
Expand All @@ -18,7 +19,7 @@


@dataclass
class InvalidRecordEntry(Exception):
class InvalidRecordEntry(Exception): # noqa: N818
"""Raised when a RecordEntry is not valid, due to improper element values or count."""

elements: Iterable[str]
Expand Down Expand Up @@ -152,23 +153,19 @@ def validate_stream(self, stream: BinaryIO) -> bool:
:return: Whether data read from stream matches hash and size.
"""
if self.hash_ is not None:
with open(os.devnull, "wb") as new_target:
with Path(os.devnull).open("wb") as new_target:
hash_, size = copyfileobj_with_hashing(
stream, cast("BinaryIO", new_target), self.hash_.name
)

if self.size is not None and size != self.size:
return False
if self.hash_.value != hash_:
return False
return True
return self.hash_.value == hash_

elif self.size is not None:
assert self.hash_ is None
size = get_stream_length(stream)
if size != self.size:
return False
return True
return size == self.size

return True

Expand Down
4 changes: 2 additions & 2 deletions src/installer/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def _build_shebang(executable: str, forlauncher: bool) -> bytes:
return b"#!/bin/sh\n'''exec' " + quoted + b' "$0" "$@"\n' + b"' '''"


class InvalidScript(ValueError):
class InvalidScript(ValueError): # noqa: N818
"""Raised if the user provides incorrect script section or kind."""


Expand Down Expand Up @@ -129,7 +129,7 @@ def _get_alternate_executable(self, executable: str, kind: "LauncherKind") -> st
if self.section == "gui" and kind != "posix":
dn, fn = os.path.split(executable)
fn = fn.replace("python", "pythonw")
executable = os.path.join(dn, fn)
executable = os.path.join(dn, fn) # noqa: PTH118
return executable

def generate(self, executable: str, kind: "LauncherKind") -> Tuple[str, bytes]:
Expand Down
21 changes: 17 additions & 4 deletions src/installer/sources.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
"""Source of information about a wheel file."""

import os
import posixpath
import stat
import zipfile
from contextlib import contextmanager
from typing import BinaryIO, ClassVar, Iterator, List, Optional, Tuple, Type, cast
from pathlib import Path
from typing import (
TYPE_CHECKING,
BinaryIO,
ClassVar,
Iterator,
List,
Optional,
Tuple,
Type,
cast,
)

from installer.exceptions import InstallerError
from installer.records import RecordEntry, parse_record_file
from installer.utils import canonicalize_name, parse_wheel_filename

if TYPE_CHECKING:
import os

WheelContentElement = Tuple[Tuple[str, str, str], BinaryIO, bool]


Expand Down Expand Up @@ -121,7 +134,7 @@ def __repr__(self) -> str:
return f"WheelFileValidationError(issues={self.issues!r})"


class _WheelFileBadDistInfo(ValueError, InstallerError):
class _WheelFileBadDistInfo(ValueError, InstallerError): # noqa: N818
"""Raised when a wheel file has issues around `.dist-info`."""

def __init__(self, *, reason: str, filename: Optional[str], dist_info: str) -> None:
Expand Down Expand Up @@ -155,7 +168,7 @@ def __init__(self, f: zipfile.ZipFile) -> None:
self._zipfile = f
assert f.filename

basename = os.path.basename(f.filename)
basename = Path(f.filename).name
parsed_name = parse_wheel_filename(basename)
super().__init__(
version=parsed_name.version,
Expand Down
10 changes: 5 additions & 5 deletions src/installer/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from email.message import Message
from email.parser import FeedParser
from email.policy import compat32
from pathlib import Path
from typing import (
TYPE_CHECKING,
BinaryIO,
Expand All @@ -22,7 +23,6 @@
NewType,
Optional,
Tuple,
Union,
cast,
)

Expand Down Expand Up @@ -67,7 +67,7 @@
"WheelFilename", ["distribution", "version", "build_tag", "tag"]
)

# Adapted from https://github.com/python/importlib_metadata/blob/v3.4.0/importlib_metadata/__init__.py#L90 # noqa
# Adapted from https://github.com/python/importlib_metadata/blob/v3.4.0/importlib_metadata/__init__.py#L90
_ENTRYPOINT_REGEX = re.compile(
r"""
(?P<module>[\w.]+)\s*
Expand Down Expand Up @@ -235,7 +235,7 @@ def parse_entrypoints(text: str) -> Iterable[Tuple[str, str, str, "ScriptSection
:return:
name of the script, module to use, attribute to call, kind of script (cli / gui)
"""
# Borrowed from https://github.com/python/importlib_metadata/blob/v3.4.0/importlib_metadata/__init__.py#L115 # noqa
# Borrowed from https://github.com/python/importlib_metadata/blob/v3.4.0/importlib_metadata/__init__.py#L115
config = ConfigParser(delimiters="=")
config.optionxform = str # type: ignore[assignment, method-assign]
config.read_string(text)
Expand Down Expand Up @@ -271,6 +271,6 @@ def _current_umask() -> int:

# Borrowed from:
# https://github.com/pypa/pip/blob/0f21fb92/src/pip/_internal/utils/unpacking.py#L93
def make_file_executable(path: Union[str, "os.PathLike[str]"]) -> None:
def make_file_executable(path: Path) -> None:
"""Make the file at the provided path executable."""
os.chmod(path, (0o777 & ~_current_umask() | 0o111))
path.chmod(0o777 & ~_current_umask() | 0o111)
Loading

0 comments on commit beb0492

Please sign in to comment.