diff --git a/pyproject.toml b/pyproject.toml index c7ec2070..2c9faa23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,13 +9,12 @@ build-backend = "hatchling.build" name = "attrs" authors = [{ name = "Hynek Schlawack", email = "hs@ox.cx" }] license = "MIT" -requires-python = ">=3.7" +requires-python = ">=3.8" description = "Classes Without Boilerplate" keywords = ["class", "attribute", "boilerplate"] classifiers = [ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", diff --git a/src/attr/__init__.py b/src/attr/__init__.py index 9226258a..7cd4734e 100644 --- a/src/attr/__init__.py +++ b/src/attr/__init__.py @@ -98,10 +98,7 @@ def __getattr__(name: str) -> str: import sys import warnings - if sys.version_info < (3, 8): - from importlib_metadata import metadata - else: - from importlib.metadata import metadata + from importlib.metadata import metadata if name not in ("__version__", "__version_info__"): warnings.warn( diff --git a/src/attr/_compat.py b/src/attr/_compat.py index b7d7a4b8..7edb762a 100644 --- a/src/attr/_compat.py +++ b/src/attr/_compat.py @@ -17,13 +17,7 @@ PY_3_13_PLUS = sys.version_info[:2] >= (3, 13) -if sys.version_info < (3, 8): - try: - from typing_extensions import Protocol - except ImportError: # pragma: no cover - Protocol = object -else: - from typing import Protocol # noqa: F401 +from typing import Protocol # noqa: F401 class _AnnotationExtractor: diff --git a/src/attr/_make.py b/src/attr/_make.py index 0114582a..6be03b66 100644 --- a/src/attr/_make.py +++ b/src/attr/_make.py @@ -1979,9 +1979,9 @@ def _make_repr(attrs, ns, cls): "self." + name if i else 'getattr(self, "' + name + '", NOTHING)' ) fragment = ( - "%s={%s!r}" % (name, accessor) + f"{name}={{{accessor}!r}}" if r == repr - else "%s={%s_repr(%s)}" % (name, name, accessor) + else f"{name}={{{name}_repr({accessor})}}" ) attribute_fragments.append(fragment) repr_fragment = ", ".join(attribute_fragments) @@ -2208,11 +2208,7 @@ def _setattr_with_converter(attr_name, value_var, has_on_setattr): Use the cached object.setattr to set *attr_name* to *value_var*, but run its converter first. """ - return "_setattr('%s', %s(%s))" % ( - attr_name, - _INIT_CONVERTER_PAT % (attr_name,), - value_var, - ) + return f"_setattr('{attr_name}', {_INIT_CONVERTER_PAT % (attr_name,)}({value_var}))" def _assign(attr_name, value, has_on_setattr): @@ -2234,10 +2230,8 @@ def _assign_with_converter(attr_name, value_var, has_on_setattr): if has_on_setattr: return _setattr_with_converter(attr_name, value_var, True) - return "self.%s = %s(%s)" % ( - attr_name, - _INIT_CONVERTER_PAT % (attr_name,), - value_var, + return ( + f"self.{attr_name} = {_INIT_CONVERTER_PAT % (attr_name,)}({value_var})" ) @@ -2267,11 +2261,7 @@ def fmt_setter_with_converter(attr_name, value_var, has_on_setattr): attr_name, value_var, has_on_setattr ) - return "_inst_dict['%s'] = %s(%s)" % ( - attr_name, - _INIT_CONVERTER_PAT % (attr_name,), - value_var, - ) + return f"_inst_dict['{attr_name}'] = {_INIT_CONVERTER_PAT % (attr_name,)}({value_var})" return ( ("_inst_dict = self.__dict__",), @@ -2514,12 +2504,12 @@ def _attrs_to_init_script( args = ", ".join(args) pre_init_args = args if kw_only_args: - args += "%s*, %s" % ( + args += "{}*, {}".format( ", " if args else "", # leading comma ", ".join(kw_only_args), # kw_only args ) pre_init_kw_only_args = ", ".join( - ["%s=%s" % (kw_arg, kw_arg) for kw_arg in kw_only_args] + [f"{kw_arg}={kw_arg}" for kw_arg in kw_only_args] ) pre_init_args += ( ", " if pre_init_args else "" diff --git a/tests/test_packaging.py b/tests/test_packaging.py index 5a2fdb26..f2246434 100644 --- a/tests/test_packaging.py +++ b/tests/test_packaging.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: MIT -import sys + +from importlib import metadata import pytest @@ -8,12 +9,6 @@ import attrs -if sys.version_info < (3, 8): - import importlib_metadata as metadata -else: - from importlib import metadata - - @pytest.fixture(name="mod", params=(attr, attrs)) def _mod(request): return request.param diff --git a/tests/test_slots.py b/tests/test_slots.py index c1332f2d..7dd6224a 100644 --- a/tests/test_slots.py +++ b/tests/test_slots.py @@ -597,7 +597,7 @@ class C: field = attr.ib() def f(self, a): - super(C, self).__init__() # noqa: UP008 + super().__init__() C(field=1) @@ -685,7 +685,7 @@ def f(self): class C(A): @property def f(self): - return super(C, self).f ** 2 # noqa: UP008 + return super().f ** 2 assert B(11).f == 121 assert B(17).f == 289 diff --git a/tests/typing_example.py b/tests/typing_example.py index 2124912c..d5899ddc 100644 --- a/tests/typing_example.py +++ b/tests/typing_example.py @@ -56,7 +56,7 @@ class DD: @attr.s class EE: - y: "list[int]" = attr.ib() + y: list[int] = attr.ib() @attr.s