diff --git a/pyproject.toml b/pyproject.toml index 2e61171..59970dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,29 +48,80 @@ quote-style = "single" skip-magic-trailing-comma = true [tool.ruff.lint] +preview = true select = [ + # flake8-builtins + "A", + # flake8-annotations + "ANN", + # flake8-unused-arguments + "ARG", # flake8-bugbear "B", + # flake8-blind-except + "BLE", + # flake8-comprehensions + "C4", # pycodestyle "E", # Pyflakes "F", # flake8-future-annotations "FA", + # flake8-boolean-trap + "FBT", + # refurb + "FURB", # isort "I", + # flake8-implicit-str-concat + "ISC", + # pep8-naming + "N", + # Perflint + "PERF", + # flake8-pie + "PIE", + # flake8-pytest-style + "PT", + # flake8-quotes + "Q", + # flake8-return + "RET", + # flake8-raise + "RSE", + # Ruff-specific rules + "RUF", # flake8-simplify "SIM", + # flake8-self + "SLF", + # flake8-debugger + "T10", + # flake8-print + "T20", + # flake8-tidy-imports + "TID", # pyupgrade "UP", + # pycodestyle + "W", ] ignore = [ - "E203", # Whitespace before ':' + # disallows `typing.Any` annotation + "ANN401", + # whitespace before ':' + "E203", ] +[tool.ruff.lint.flake8-quotes] +docstring-quotes = "double" +inline-quotes = "single" + [tool.ruff.lint.isort] case-sensitive = true combine-as-imports = true +order-by-type = false relative-imports-order = "closest-to-furthest" split-on-trailing-comma = false diff --git a/setup.py b/setup.py index 7ba2ecb..c93631a 100644 --- a/setup.py +++ b/setup.py @@ -6,11 +6,11 @@ from setuptools import find_packages, setup project_base_url = 'https://github.com/lycantropos/cfractions/' -parameters: dict[str, t.Any] = dict( - packages=find_packages(exclude=('tests', 'tests.*')), - url=project_base_url, - download_url=project_base_url + 'archive/master.zip', -) +parameters: dict[str, t.Any] = { + 'packages': find_packages(exclude=('tests', 'tests.*')), + 'url': project_base_url, + 'download_url': project_base_url + 'archive/master.zip', +} if sys.implementation.name == 'cpython': from glob import glob @@ -19,18 +19,15 @@ class BuildExt(build_ext): def build_extensions(self) -> None: - compile_args = [] + compile_args: list[str] = [] compiler_type = self.compiler.compiler_type if compiler_type == 'unix': - compile_args.append('-Werror') - compile_args.append('-Wall') - compile_args.append('-Wextra') + compile_args.extend(('-Werror', '-Wall', '-Wextra')) if sys.version_info < (3, 12): # Python3.12 introduces conversion warnings compile_args.append('-Wconversion') elif compiler_type == 'msvc': - compile_args.append('/WX') - compile_args.append('/W3') + compile_args.extend(('/WX', '/W3')) for extension in self.extensions: extension.extra_compile_args += compile_args super().build_extensions() diff --git a/tests/conftest.py b/tests/conftest.py index 69f9e7b..d2f1d82 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,7 +4,7 @@ import pytest from hypothesis import HealthCheck, settings -on_ci = bool(os.getenv('CI', False)) +on_ci = bool(os.getenv('CI')) is_pypy = platform.python_implementation() == 'PyPy' max_examples = ( -(-settings.default.max_examples // 10) diff --git a/tests/fraction_tests/test___add__.py b/tests/fraction_tests/test___add__.py index 580ff8d..ae11291 100644 --- a/tests/fraction_tests/test___add__.py +++ b/tests/fraction_tests/test___add__.py @@ -55,7 +55,7 @@ def test_float_argument(first: Fraction, second: float) -> None: assert implication(math.isfinite(result), math.isfinite(second)) assert equivalence(math.isnan(result), math.isnan(second)) assert implication( - math.isinf(second) or not first and not math.isnan(second), + math.isinf(second) or (not first and not math.isnan(second)), result == second, ) diff --git a/tests/fraction_tests/test___floordiv__.py b/tests/fraction_tests/test___floordiv__.py index 2445cdf..46783c0 100644 --- a/tests/fraction_tests/test___floordiv__.py +++ b/tests/fraction_tests/test___floordiv__.py @@ -27,10 +27,8 @@ def test_value(dividend: Fraction, divisor: Rational) -> None: result = dividend // divisor assert ( - dividend % divisor == 0 - and result == dividend / divisor - or result < dividend / divisor - ) + dividend % divisor == 0 and result == dividend / divisor + ) or result < dividend / divisor @given(strategies.fractions) diff --git a/tests/fraction_tests/test___mod__.py b/tests/fraction_tests/test___mod__.py index 5861c87..a9503fb 100644 --- a/tests/fraction_tests/test___mod__.py +++ b/tests/fraction_tests/test___mod__.py @@ -36,11 +36,9 @@ def test_float_argument(dividend: Fraction, divisor: int) -> None: def test_value(dividend: Fraction, divisor: Fraction) -> None: result = dividend % divisor - assert ( - result == 0 - and (dividend / divisor == dividend // divisor) - or (result > 0) is (divisor > 0) - ) + assert (result == 0 and (dividend / divisor == dividend // divisor)) or ( + result > 0 + ) is (divisor > 0) assert abs(result) < abs(divisor) diff --git a/tests/fraction_tests/test___mul__.py b/tests/fraction_tests/test___mul__.py index 5d6df3d..b376ae0 100644 --- a/tests/fraction_tests/test___mul__.py +++ b/tests/fraction_tests/test___mul__.py @@ -52,7 +52,7 @@ def test_float_argument(first: Fraction, second: float) -> None: assert isinstance(result, float) assert equivalence( math.isnan(result), - math.isnan(second) or not first and math.isinf(second), + math.isnan(second) or (not first and math.isinf(second)), ) diff --git a/tests/fraction_tests/test___round__.py b/tests/fraction_tests/test___round__.py index 2ed7187..f7944b2 100644 --- a/tests/fraction_tests/test___round__.py +++ b/tests/fraction_tests/test___round__.py @@ -24,8 +24,10 @@ def test_value(fraction: Fraction, precision: int | None) -> None: ( result == truncated_fraction + (-1 if fraction < 0 else 1) if ( - abs(truncated_fraction - fraction) == Fraction(1, 2) - and truncated_fraction % 2 == 1 + ( + abs(truncated_fraction - fraction) == Fraction(1, 2) + and truncated_fraction % 2 == 1 + ) or abs(truncated_fraction - fraction) > Fraction(1, 2) ) else result == truncated_fraction diff --git a/tests/fraction_tests/test___str__.py b/tests/fraction_tests/test___str__.py index cce1af8..916d833 100644 --- a/tests/fraction_tests/test___str__.py +++ b/tests/fraction_tests/test___str__.py @@ -13,12 +13,10 @@ def test_basic(fraction: Fraction) -> None: result = str(fraction) assert ( - fraction.denominator == 1 - and result == str(fraction.numerator) - or ( - str(fraction.numerator) in result - and str(fraction.denominator) in result - ) + fraction.denominator == 1 and result == str(fraction.numerator) + ) or ( + str(fraction.numerator) in result + and str(fraction.denominator) in result ) diff --git a/tests/fraction_tests/test___sub__.py b/tests/fraction_tests/test___sub__.py index 1e28420..757a3df 100644 --- a/tests/fraction_tests/test___sub__.py +++ b/tests/fraction_tests/test___sub__.py @@ -53,7 +53,7 @@ def test_float_argument(first: Fraction, second: float) -> None: assert implication(math.isfinite(result), math.isfinite(second)) assert equivalence(math.isnan(result), math.isnan(second)) assert implication( - math.isinf(second) or not first and not math.isnan(second), + math.isinf(second) or (not first and not math.isnan(second)), result == -second, ) diff --git a/tests/fraction_tests/test___truediv__.py b/tests/fraction_tests/test___truediv__.py index 4c38585..e072d58 100644 --- a/tests/fraction_tests/test___truediv__.py +++ b/tests/fraction_tests/test___truediv__.py @@ -50,7 +50,7 @@ def test_float_argument(dividend: Fraction, divisor: float) -> None: assert isinstance(result, float) assert equivalence(math.isnan(result), math.isnan(divisor)) assert implication( - math.isinf(divisor) or not dividend and not math.isnan(divisor), + math.isinf(divisor) or (not dividend and not math.isnan(divisor)), not result, ) diff --git a/tests/fraction_tests/test_constructor.py b/tests/fraction_tests/test_constructor.py index 1cf4bd2..ed3ea74 100644 --- a/tests/fraction_tests/test_constructor.py +++ b/tests/fraction_tests/test_constructor.py @@ -16,15 +16,11 @@ def test_basic(numerator: int, denominator: int) -> None: result = Fraction(numerator, denominator) assert ( - not numerator - and not result.numerator - or not numerator % result.numerator - ) + not numerator and not result.numerator + ) or not numerator % result.numerator assert ( - not numerator - and not result.numerator - or not denominator % result.denominator - ) + not numerator and not result.numerator + ) or not denominator % result.denominator def test_no_argument() -> None: @@ -47,10 +43,8 @@ def test_string_argument(value: str) -> None: try: Fraction(value) except ZeroDivisionError: - assert ( - '/' in value - and int(value[value.find('/') + 1 : len(value.rstrip())]) == 0 - ) + assert '/' in value + assert int(value[value.find('/') + 1 : len(value.rstrip())]) == 0 except ValueError: assert fraction_pattern.fullmatch(value) is None @@ -127,7 +121,7 @@ def test_infinite_float_argument(value: float) -> None: @given(strategies.nans) def test_nan_float_argument(value: float) -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError): # noqa: PT011 Fraction(value) diff --git a/tests/utils.py b/tests/utils.py index b0751a2..cccfb3c 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -19,11 +19,19 @@ Real: te.TypeAlias = t.Union[Rational, float] -def equivalence(left_statement: bool, right_statement: bool) -> bool: +def equivalence( + left_statement: bool, # noqa: FBT001 + right_statement: bool, # noqa: FBT001 + /, +) -> bool: return left_statement is right_statement -def implication(antecedent: bool, consequent: bool) -> bool: +def implication( + antecedent: bool, # noqa: FBT001 + consequent: bool, # noqa: FBT001 + /, +) -> bool: return not antecedent or consequent