From 6ceff2eea2c2ea245121c13d2d6604fed2f2a91a Mon Sep 17 00:00:00 2001 From: Hasan Ramezani Date: Wed, 6 Jul 2022 08:52:01 +0200 Subject: [PATCH] Add Pyupgrade (#4214) --- .github/workflows/ci.yml | 3 +++ .pre-commit-config.yaml | 5 +++++ Makefile | 5 +++++ pydantic/color.py | 10 +++++----- pydantic/generics.py | 2 +- pydantic/mypy.py | 2 +- tests/requirements-linting.txt | 1 + tests/test_dataclasses.py | 2 +- tests/test_json.py | 2 +- tests/test_orm_mode.py | 3 +-- tests/test_schema.py | 6 +++--- tests/test_types.py | 7 +++---- 12 files changed, 30 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec98dc7..240a25b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,9 @@ jobs: - name: lint run: make lint + - name: pyupgrade + run: make pyupgrade + - name: mypy run: make mypy diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3f5cd0a..f73ebce 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,3 +17,8 @@ repos: entry: make mypy types: [python] language: system + - id: pyupgrade + name: Pyupgrade + entry: make pyupgrade + types: [python] + language: system diff --git a/Makefile b/Makefile index cf84606..e4eed75 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ build: .PHONY: format format: + pyupgrade --py37-plus --exit-zero-even-if-changed `find pydantic tests -name "*.py" -type f` $(isort) $(black) @@ -54,6 +55,10 @@ check-dist: mypy: mypy pydantic +.PHONY: pyupgrade +pyupgrade: + pyupgrade --py37-plus `find pydantic tests -name "*.py" -type f` + .PHONY: pyright pyright: cd tests/pyright && pyright diff --git a/pydantic/color.py b/pydantic/color.py index b074f2e..269aff5 100644 --- a/pydantic/color.py +++ b/pydantic/color.py @@ -138,7 +138,7 @@ class Color(Representation): True - always include alpha, False - always omit alpha, """ - r, g, b = [float_to_255(c) for c in self._rgba[:3]] + r, g, b = (float_to_255(c) for c in self._rgba[:3]) if alpha is None: if self._rgba.alpha is None: return r, g, b @@ -204,10 +204,10 @@ def parse_tuple(value: Tuple[Any, ...]) -> RGBA: Parse a tuple or list as a color. """ if len(value) == 3: - r, g, b = [parse_color_value(v) for v in value] + r, g, b = (parse_color_value(v) for v in value) return RGBA(r, g, b, None) elif len(value) == 4: - r, g, b = [parse_color_value(v) for v in value[:3]] + r, g, b = (parse_color_value(v) for v in value[:3]) return RGBA(r, g, b, parse_float_alpha(value[3])) else: raise ColorError(reason='tuples must have length 3 or 4') @@ -233,7 +233,7 @@ def parse_str(value: str) -> RGBA: m = re.fullmatch(r_hex_short, value_lower) if m: *rgb, a = m.groups() - r, g, b = [int(v * 2, 16) for v in rgb] + r, g, b = (int(v * 2, 16) for v in rgb) if a: alpha: Optional[float] = int(a * 2, 16) / 255 else: @@ -243,7 +243,7 @@ def parse_str(value: str) -> RGBA: m = re.fullmatch(r_hex_long, value_lower) if m: *rgb, a = m.groups() - r, g, b = [int(v, 16) for v in rgb] + r, g, b = (int(v, 16) for v in rgb) if a: alpha = int(a, 16) / 255 else: diff --git a/pydantic/generics.py b/pydantic/generics.py index 2467bb7..c43ac3e 100644 --- a/pydantic/generics.py +++ b/pydantic/generics.py @@ -181,7 +181,7 @@ class GenericModel(BaseModel): def build_base_model( base_model: Type[GenericModel], mapped_types: Parametrization ) -> Iterator[Type[GenericModel]]: - base_parameters = tuple([mapped_types[param] for param in base_model.__parameters__]) + base_parameters = tuple(mapped_types[param] for param in base_model.__parameters__) parameterized_base = base_model.__class_getitem__(base_parameters) if parameterized_base is base_model or parameterized_base is cls: # Avoid duplication in MRO diff --git a/pydantic/mypy.py b/pydantic/mypy.py index d89fe04..8229b72 100644 --- a/pydantic/mypy.py +++ b/pydantic/mypy.py @@ -309,7 +309,7 @@ class PydanticModelTransformer: known_fields.add(name) superclass_fields.append(field) else: - (field,) = [a for a in all_fields if a.name == name] + (field,) = (a for a in all_fields if a.name == name) all_fields.remove(field) superclass_fields.append(field) all_fields = superclass_fields + all_fields diff --git a/tests/requirements-linting.txt b/tests/requirements-linting.txt index 8e721d7..b8e2452 100644 --- a/tests/requirements-linting.txt +++ b/tests/requirements-linting.txt @@ -3,6 +3,7 @@ flake8==4.0.1 flake8-quotes==3.3.1 hypothesis==6.48.2 isort==5.10.1 +pyupgrade==2.34.0 mypy==0.950 pre-commit==2.19.0 pycodestyle==2.8.0 diff --git a/tests/test_dataclasses.py b/tests/test_dataclasses.py index ef5968c..434742a 100644 --- a/tests/test_dataclasses.py +++ b/tests/test_dataclasses.py @@ -205,7 +205,7 @@ def test_post_init_post_parse(): def test_post_init_post_parse_types(): @pydantic.dataclasses.dataclass - class CustomType(object): + class CustomType: b: int @pydantic.dataclasses.dataclass diff --git a/tests/test_json.py b/tests/test_json.py index 5871446..6f3cdc3 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -73,7 +73,7 @@ def test_path_encoding(tmpdir): dir_path = tmpdir / 'baz' dir_path.mkdir() model = PathModel(path=Path('/path/test/example/'), file_path=file_path, dir_path=dir_path) - expected = '{{"path": "/path/test/example", "file_path": "{}", "dir_path": "{}"}}'.format(file_path, dir_path) + expected = f'{{"path": "/path/test/example", "file_path": "{file_path}", "dir_path": "{dir_path}"}}' assert json.dumps(model, default=pydantic_encoder) == expected diff --git a/tests/test_orm_mode.py b/tests/test_orm_mode.py index 36a8c8c..af31fd2 100644 --- a/tests/test_orm_mode.py +++ b/tests/test_orm_mode.py @@ -274,8 +274,7 @@ def test_custom_getter_dict_derived_model_class(): __custom__ = True def __iter__(self): - for elem in range(5): - yield elem + yield from range(5) class Example: def __init__(self, *args, **kwargs): diff --git a/tests/test_schema.py b/tests/test_schema.py index a483e3f..52f9dff 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -1134,7 +1134,7 @@ def test_flat_models_unique_models(): from pydantic_schema_test.moduled.modeld import Model as ModelD flat_models = get_flat_models_from_models([ModelA, ModelB, ModelD]) - assert flat_models == set([ModelA, ModelB]) + assert flat_models == {ModelA, ModelB} def test_flat_models_with_submodels(): @@ -1148,7 +1148,7 @@ def test_flat_models_with_submodels(): c: Dict[str, Bar] flat_models = get_flat_models_from_model(Baz) - assert flat_models == set([Foo, Bar, Baz]) + assert flat_models == {Foo, Bar, Baz} def test_flat_models_with_submodels_from_sequence(): @@ -1166,7 +1166,7 @@ def test_flat_models_with_submodels_from_sequence(): ingredients: List[Ingredient] flat_models = get_flat_models_from_models([Bar, Pizza]) - assert flat_models == set([Foo, Bar, Ingredient, Pizza]) + assert flat_models == {Foo, Bar, Ingredient, Pizza} def test_model_name_maps(): diff --git a/tests/test_types.py b/tests/test_types.py index 8e54817..d21d45f 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -418,7 +418,7 @@ def test_constrained_set_too_long(): v: conset(int, max_items=10) = [] with pytest.raises(ValidationError) as exc_info: - ConSetModelMax(v=set(str(i) for i in range(11))) + ConSetModelMax(v={str(i) for i in range(11)}) assert exc_info.value.errors() == [ { 'loc': ('v',), @@ -1390,8 +1390,7 @@ def test_infinite_iterable_validate_first(): def str_iterable(): while True: - for c in 'foobarbaz': - yield c + yield from 'foobarbaz' with pytest.raises(ValidationError) as exc_info: Model(it=str_iterable(), b=3) @@ -1618,7 +1617,7 @@ def test_strict_bytes_subclass(): b = Model(v=MyStrictBytes(bytearray('foobar', 'utf-8'))) assert isinstance(b.v, MyStrictBytes) - assert b.v == 'foobar'.encode() + assert b.v == b'foobar' def test_strict_str():