Skip to content

Commit

Permalink
Turn on all ruff checks, and address them
Browse files Browse the repository at this point in the history
  • Loading branch information
SethMMorton committed Oct 14, 2024
1 parent 6136fa6 commit 9381114
Show file tree
Hide file tree
Showing 33 changed files with 380 additions and 290 deletions.
52 changes: 27 additions & 25 deletions dev/bump.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
#! /usr/bin/env python

"""
Bump version of natsort.
Cross-platform bump of version with special CHANGELOG modification.
INTENDED TO BE CALLED FROM PROJECT ROOT, NOT FROM dev/!
"""

from __future__ import annotations

import datetime
import pathlib
import subprocess
import sys

Expand All @@ -32,14 +37,11 @@
sys.exit('bump_type must be one of "major", "minor", or "patch"!')


def git(cmd, *args):
"""Wrapper for calling git"""
def git(cmd: str, *args: str) -> None:
"""Call git."""
try:
subprocess.run(["git", cmd, *args], check=True, text=True)
except subprocess.CalledProcessError as e:
print("Call to git failed!", file=sys.stderr)
print("STDOUT:", e.stdout, file=sys.stderr)
print("STDERR:", e.stderr, file=sys.stderr)
sys.exit(e.returncode)


Expand All @@ -60,26 +62,26 @@ def git(cmd, *args):
next_version = ".".join(map(str, version_components))

# Update the changelog.
with open("CHANGELOG.md") as fl:
changelog = fl.read()

# Add a date to this entry.
changelog = changelog.replace(
"Unreleased",
f"Unreleased\n---\n\n[{next_version}] - {datetime.datetime.now():%Y-%m-%d}",
)

# Add links to the entries.
changelog = changelog.replace(
"<!---Comparison links-->",
"<!---Comparison links-->\n[{new}]: {url}/{current}...{new}".format(
new=next_version,
current=current_version,
url="https://github.com/SethMMorton/natsort/compare",
),
)
with open("CHANGELOG.md", "w") as fl:
fl.write(changelog)
changelog = pathlib.Path("CHANGELOG.md").read_text()

# Add a date to this entry.
changelog = changelog.replace(
"Unreleased",
f"Unreleased\n---\n\n[{next_version}] - {datetime.datetime.now():%Y-%m-%d}",
)

# Add links to the entries.
changelog = changelog.replace(
"<!---Comparison links-->",
"<!---Comparison links-->\n[{new}]: {url}/{current}...{new}".format(
new=next_version,
current=current_version,
url="https://github.com/SethMMorton/natsort/compare",
),
)

# Write the changelog
pathlib.Path("CHANGELOG.md").write_text(changelog)

# Add the CHANGELOG.md changes and commit & tag.
git("add", "CHANGELOG.md")
Expand Down
3 changes: 3 additions & 0 deletions dev/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

"""
Cross-platform clean of working directory.
INTENDED TO BE CALLED FROM PROJECT ROOT, NOT FROM dev/!
"""

from __future__ import annotations

import pathlib
import shutil

Expand Down
21 changes: 10 additions & 11 deletions dev/generate_new_unicode_numbers.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
#! /usr/bin/env python
"""
Generate the numeric hex list of unicode numerals
"""
"""Generate the numeric hex list of unicode numerals."""

from __future__ import annotations

import os
import os.path
import pathlib
import sys
import unicodedata

# This is intended to be called from project root. Enforce this.
this_file = os.path.abspath(__file__)
this_base = os.path.basename(this_file)
cwd = os.path.abspath(os.getcwd())
desired_this_file = os.path.join(cwd, "dev", this_base)
this_file = pathlib.Path(__file__).absolute()
this_base = this_file.name
cwd = pathlib.Path.cwd().absolute()
desired_this_file = cwd / "dev" / this_base
if this_file != desired_this_file:
sys.exit(this_base + " must be called from project root")

# We will write the new numeric hex collection to a natsort package file.
target = os.path.join(cwd, "natsort", "unicode_numeric_hex.py")
with open(target, "w") as fl:
target = cwd / "natsort" / "unicode_numeric_hex.py"
with target.open("w") as fl:
print(
'''# -*- coding: utf-8 -*-
"""
Expand Down
4 changes: 4 additions & 0 deletions natsort/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""Public interface for the natsort package."""

from __future__ import annotations

try:
# The redundant "as" tells mypy to treat as explict import
from natsort._version import __version__ as __version__
Expand Down
42 changes: 25 additions & 17 deletions natsort/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
"""Entry-point for command-line interface."""

from __future__ import annotations

import argparse
import sys
from typing import Callable, Iterable, List, Optional, Pattern, Tuple, Union, cast
from typing import Callable, Iterable, Pattern, Tuple, Union, cast

import natsort
from natsort.utils import regex_chooser
Expand All @@ -13,27 +17,29 @@


class TypedArgs(argparse.Namespace):
"""Typed command-line argument namespace."""

paths: bool
filter: Optional[List[NumPair]]
reverse_filter: Optional[List[NumPair]]
exclude: List[Num]
filter: list[NumPair] | None
reverse_filter: list[NumPair] | None
exclude: list[Num]
reverse: bool
number_type: str
nosign: bool
sign: bool
noexp: bool
locale: bool
entries: List[str]
entries: list[str]

def __init__(
self,
filter: Optional[List[NumPair]] = None,
reverse_filter: Optional[List[NumPair]] = None,
exclude: Optional[List[Num]] = None,
paths: bool = False,
reverse: bool = False,
filter: list[NumPair] | None = None,
reverse_filter: list[NumPair] | None = None,
exclude: list[Num] | None = None,
paths: bool = False, # noqa: FBT001, FBT002
reverse: bool = False, # noqa: FBT001, FBT002
) -> None:
"""Used by testing only"""
"""To be used by testing only."""
self.filter = filter
self.reverse_filter = reverse_filter
self.exclude = [] if exclude is None else exclude
Expand All @@ -47,11 +53,10 @@ def __init__(

def main(*arguments: str) -> None:
"""
Performs a natural sort on entries given on the command-line.
Perform a natural sort on entries given on the command-line.
Arguments are read from sys.argv.
"""

from argparse import ArgumentParser, RawDescriptionHelpFormatter
from textwrap import dedent

Expand Down Expand Up @@ -186,7 +191,9 @@ def range_check(low: Num, high: Num) -> NumPair:
Parameters
----------
low : {float, int}
Low end of the range.
high : {float, int}
High end of the range.
Returns
-------
Expand All @@ -204,7 +211,7 @@ def range_check(low: Num, high: Num) -> NumPair:
return low, high


def check_filters(filters: Optional[NumPairIter]) -> Optional[List[NumPair]]:
def check_filters(filters: NumPairIter | None) -> list[NumPair] | None:
"""
Execute range_check for every element of an iterable.
Expand Down Expand Up @@ -249,6 +256,7 @@ def keep_entry_range(
Parameters
----------
entry : str
The string to check.
lows : iterable
Collection of low values against which to compare the entry.
highs : iterable
Expand Down Expand Up @@ -285,6 +293,7 @@ def keep_entry_value(
Parameters
----------
entry : str
The string to check.
values : iterable
Collection of values against which to compare the entry.
converter : callable
Expand All @@ -300,9 +309,8 @@ def keep_entry_value(
return not any(converter(num) in values for num in regex.findall(entry))


def sort_and_print_entries(entries: List[str], args: TypedArgs) -> None:
def sort_and_print_entries(entries: list[str], args: TypedArgs) -> None:
"""Sort the entries, applying the filters first if necessary."""

# Extract the proper number type.
is_float = args.number_type in ("float", "real", "f", "r")
signed = args.signed or args.number_type in ("real", "r")
Expand Down Expand Up @@ -352,7 +360,7 @@ def sort_and_print_entries(entries: List[str], args: TypedArgs) -> None:

# Print off the sorted results
for entry in natsort.natsorted(entries, reverse=args.reverse, alg=alg):
print(entry)
print(entry) # noqa: T201


if __name__ == "__main__":
Expand Down
18 changes: 11 additions & 7 deletions natsort/compat/fake_fastnumbers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"""
This module is intended to replicate some of the functionality
from the fastnumbers module in the event that module is not installed.
Replication of fastnumbers functionality.
Used when the fastnumbers module is not installed.
"""

from __future__ import annotations

import unicodedata
from typing import Callable, FrozenSet, Union
from typing import Callable, Union

from natsort.unicode_numbers import decimal_chars

Expand Down Expand Up @@ -40,8 +43,8 @@ def fast_float(
key: Callable[[str], str] = lambda x: x,
nan: float = float("inf"),
_uni: Callable[[str, StrOrFloat], StrOrFloat] = unicodedata.numeric,
_nan_inf: FrozenSet[str] = NAN_INF,
_first_char: FrozenSet[str] = POTENTIAL_FIRST_CHAR,
_nan_inf: frozenset[str] = NAN_INF,
_first_char: frozenset[str] = POTENTIAL_FIRST_CHAR,
) -> StrOrFloat:
"""
Convert a string to a float quickly, return input as-is if not possible.
Expand All @@ -66,12 +69,13 @@ def fast_float(
if x[0] in _first_char or x.lstrip()[:3] in _nan_inf:
try:
ret = float(x)
return nan if ret != ret else ret
except ValueError:
try:
return _uni(x, key(x)) if len(x) == 1 else key(x)
except TypeError: # pragma: no cover
return key(x)
else:
return nan if ret != ret else ret
else:
try:
return _uni(x, key(x)) if len(x) == 1 else key(x)
Expand All @@ -83,7 +87,7 @@ def fast_int(
x: str,
key: Callable[[str], str] = lambda x: x,
_uni: Callable[[str, StrOrInt], StrOrInt] = unicodedata.digit,
_first_char: FrozenSet[str] = POTENTIAL_FIRST_CHAR,
_first_char: frozenset[str] = POTENTIAL_FIRST_CHAR,
) -> StrOrInt:
"""
Convert a string to a int quickly, return input as-is if not possible.
Expand Down
33 changes: 24 additions & 9 deletions natsort/compat/fastnumbers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"""
Interface for natsort to access fastnumbers functions without
having to worry if it is actually installed.
Compatibility interface for fastnumbers.
Provides a uniform interface to fastnumbers or the fallbacks.
"""

from __future__ import annotations

import re
from typing import Callable, Iterable, Iterator, Tuple, Union
from typing import Callable, Iterable, Iterator, Union

StrOrFloat = Union[str, float]
StrOrInt = Union[str, int]
Expand All @@ -14,7 +17,7 @@

def is_supported_fastnumbers(
fastnumbers_version: str,
minimum: Tuple[int, int, int] = (2, 0, 0),
minimum: tuple[int, int, int] = (2, 0, 0),
) -> bool:
match = re.match(
r"^(\d+)\.(\d+)(\.(\d+))?([ab](\d+))?$",
Expand All @@ -31,6 +34,12 @@ def is_supported_fastnumbers(
return (int(major), int(minor), int(patch)) >= minimum


def ensure_minimum_fastnumbers(fastnumbers_version: str) -> None:
if not is_supported_fastnumbers(fastnumbers_version):
msg = "fastnumbers package version not modern enough"
raise ImportError(msg)


# If the user has fastnumbers installed, they will get great speed
# benefits. If not, we use the simulated functions that come with natsort.
try:
Expand All @@ -39,15 +48,17 @@ def is_supported_fastnumbers(
from fastnumbers import fast_float, fast_int

# Require >= version 2.0.0.
if not is_supported_fastnumbers(fn_ver):
raise ImportError # pragma: no cover
ensure_minimum_fastnumbers(fn_ver)

# For versions of fastnumbers with mapping capability, use that
if is_supported_fastnumbers(fn_ver, (5, 0, 0)):
del fast_float, fast_int
from fastnumbers import try_float, try_int
except ImportError:
from natsort.compat.fake_fastnumbers import fast_float, fast_int # type: ignore
from natsort.compat.fake_fastnumbers import ( # type: ignore[no-redef]
fast_float,
fast_int,
)

# Re-map the old-or-compatibility functions fast_float/fast_int to the
# newer API of try_float/try_int. If we already imported try_float/try_int
Expand All @@ -56,20 +67,24 @@ def is_supported_fastnumbers(

def try_float( # type: ignore[no-redef]
x: Iterable[str],
*,
map: bool,
nan: float = float("inf"),
on_fail: Callable[[str], str] = lambda x: x,
) -> Iterator[StrOrFloat]:
assert map is True
"""Attempt to convert a string to a float."""
assert map is True # noqa: S101
return (fast_float(y, nan=nan, key=on_fail) for y in x)


if "try_int" not in globals():

def try_int( # type: ignore[no-redef]
x: Iterable[str],
*,
map: bool,
on_fail: Callable[[str], str] = lambda x: x,
) -> Iterator[StrOrInt]:
assert map is True
"""Attempt to convert a string to an int."""
assert map is True # noqa: S101
return (fast_int(y, key=on_fail) for y in x)
Loading

0 comments on commit 9381114

Please sign in to comment.