From 8def7714d12889c71f55b0089d5b7d65b45851a9 Mon Sep 17 00:00:00 2001 From: Thiago Bellini Ribeiro Date: Thu, 17 Oct 2024 10:53:38 -0300 Subject: [PATCH] feat: Official support for Python 3.13 and drop support for Python 3.8 --- .github/workflows/tests.yml | 14 +- docs/guide/fields.md | 4 +- docs/guide/mutations.md | 4 +- docs/guide/optimizer.md | 2 +- docs/guide/relay.md | 2 +- docs/guide/resolvers.md | 6 +- docs/guide/types.md | 9 +- examples/django/app/schema.py | 18 +- examples/django/app/types.py | 4 +- poetry.lock | 472 ++++++++---------- pyproject.toml | 12 +- strawberry_django/arguments.py | 4 +- strawberry_django/auth/mutations.py | 4 +- strawberry_django/descriptors.py | 18 +- .../extensions/django_cache_base.py | 5 +- .../extensions/django_validation_cache.py | 2 +- strawberry_django/fields/field.py | 4 +- strawberry_django/fields/filter_order.py | 4 +- strawberry_django/fields/filter_types.py | 3 +- strawberry_django/fields/types.py | 92 ++-- strawberry_django/filters.py | 50 +- strawberry_django/integrations/guardian.py | 4 +- strawberry_django/mutations/fields.py | 5 +- strawberry_django/mutations/mutations.py | 49 +- strawberry_django/mutations/resolvers.py | 20 +- strawberry_django/optimizer.py | 12 +- strawberry_django/ordering.py | 6 +- strawberry_django/pagination.py | 6 +- strawberry_django/permissions.py | 33 +- strawberry_django/relay.py | 67 ++- strawberry_django/test/client.py | 17 +- strawberry_django/type.py | 52 +- strawberry_django/utils/inspect.py | 8 +- strawberry_django/utils/pyutils.py | 7 +- strawberry_django/utils/query.py | 10 +- strawberry_django/utils/typing.py | 4 +- tests/conftest.py | 12 +- tests/fields/test_attributes.py | 8 +- tests/fields/test_get_result.py | 10 +- tests/fields/test_relations.py | 6 +- tests/fields/test_types.py | 8 +- tests/filters/test_filters.py | 42 +- tests/filters/test_filters_v2.py | 14 +- tests/mutations/conftest.py | 22 +- tests/mutations/test_permission_classes.py | 8 +- tests/polymorphism/schema.py | 4 +- tests/projects/faker.py | 6 +- tests/projects/schema.py | 44 +- tests/queries/test_fields.py | 8 +- tests/queries/test_files.py | 4 +- tests/queries/test_m2m_through.py | 8 +- tests/relay/lazy/a.py | 4 +- tests/relay/lazy/b.py | 4 +- tests/relay/mptt/a.py | 4 +- tests/relay/mptt/b.py | 4 +- tests/relay/schema.py | 11 +- tests/test_commands.py | 9 +- tests/test_optimizer.py | 12 +- tests/test_ordering.py | 4 +- tests/test_pagination.py | 10 +- tests/test_permissions.py | 4 +- tests/test_queries.py | 12 +- tests/types.py | 18 +- tests/types2/test_type.py | 4 +- tests/utils.py | 16 +- 65 files changed, 613 insertions(+), 740 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f50d586b..775923f3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -46,20 +46,18 @@ jobs: - 4.2.* - 5.0.* python-version: - - '3.8' - - '3.9' - - '3.10' - - '3.11' - - '3.12' + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" mode: - std - geos exclude: # Django 5.0 only supports python 3.10+ - django-version: 5.0.* - python-version: '3.8' - - django-version: 5.0.* - python-version: '3.9' + python-version: "3.9" steps: - name: Checkout uses: actions/checkout@v4 diff --git a/docs/guide/fields.md b/docs/guide/fields.md index 8eaa9d1a..1f2d27c0 100644 --- a/docs/guide/fields.md +++ b/docs/guide/fields.md @@ -39,8 +39,6 @@ All one-to-one, one-to-many, many-to-one and many-to-many relationship types are The default resolver of `strawberry_django.fields()` resolves the relationship based on given type information. ```python title="types.py" -from typing import List - @strawberry_django.type(models.Fruit) class Fruit: id: auto @@ -52,7 +50,7 @@ class Fruit: class Color: id: auto name: auto - fruits: List[Fruit] + fruits: list[Fruit] ``` Note that all relations can naturally trigger the n+1 problem. To avoid that, you can either diff --git a/docs/guide/mutations.md b/docs/guide/mutations.md index 2d197edd..9c46ed5c 100644 --- a/docs/guide/mutations.md +++ b/docs/guide/mutations.md @@ -180,8 +180,8 @@ from strawberry_django import mutations @strawberry.type class Mutation: - updateFruits: List[Fruit] = mutations.update(FruitPartialInput, filters=FruitFilter) - deleteFruits: List[Fruit] = mutations.delete(filters=FruitFilter) + updateFruits: list[Fruit] = mutations.update(FruitPartialInput, filters=FruitFilter) + deleteFruits: list[Fruit] = mutations.delete(filters=FruitFilter) schema = strawberry.Schema(mutation=Mutation) ``` diff --git a/docs/guide/optimizer.md b/docs/guide/optimizer.md index 2abbd6b2..cff69e7b 100644 --- a/docs/guide/optimizer.md +++ b/docs/guide/optimizer.md @@ -91,7 +91,7 @@ class SongType: @strawberry.type class Query: artist: Artist = strawberry_django.field() - songs: List[SongType] = strawberry_django.field() + songs: list[SongType] = strawberry_django.field() ``` Querying for `artist` and `songs` like this: diff --git a/docs/guide/relay.md b/docs/guide/relay.md index 1533b4e0..cd4438f2 100644 --- a/docs/guide/relay.md +++ b/docs/guide/relay.md @@ -37,7 +37,7 @@ class Query: # Option 3: You can manually create resolver by your method manually. @strawberry_django.connection(ListConnectionWithTotalCount[FruitType]) - def fruit_with_custom_resolver(self) -> List[SomeModel]: + def fruit_with_custom_resolver(self) -> list[SomeModel]: return Fruit.objects.all() ``` diff --git a/docs/guide/resolvers.md b/docs/guide/resolvers.md index 2608c670..dbd43693 100644 --- a/docs/guide/resolvers.md +++ b/docs/guide/resolvers.md @@ -16,7 +16,6 @@ in `sync_to_async` when running async. ```python title="types.py" import strawberry_django from strawberry import auto -from typing import List from . import models @strawberry_django.type(models.Color) @@ -25,7 +24,7 @@ class Color: name: auto @strawberry_django.field - def fruits(self) -> List[Fruit]: + def fruits(self) -> list[Fruit]: return self.fruits.objects.filter(...) ``` @@ -36,7 +35,6 @@ Async resolvers can be used when running using ASGI. ```python title="types.py" import strawberry_django from strawberry import auto -from typing import List from . import models from asgiref.sync import sync_to_async @@ -46,7 +44,7 @@ class Color: name: auto @strawberry_django.field - async def fruits(self) -> List[Fruit]: + async def fruits(self) -> list[Fruit]: return sync_to_async(list)(self.fruits.objects.filter(...)) ``` diff --git a/docs/guide/types.md b/docs/guide/types.md index ebfbea8b..52bec269 100644 --- a/docs/guide/types.md +++ b/docs/guide/types.md @@ -20,7 +20,6 @@ More information about that can be read from [resolvers](resolvers.md) page. import strawberry_django from strawberry import auto -from typing import List @strawberry_django.type(models.Fruit) class Fruit: @@ -32,7 +31,7 @@ class Fruit: class Color: id: auto name: auto - fruits: List[Fruit] + fruits: list[Fruit] ``` ## Input types @@ -56,21 +55,21 @@ Non-`auto` type annotations will be respected—and therefore required—unless ```python title="types.py" @strawberry_django.input(models.Color, partial=True) class FruitPartialInput(FruitInput): - color: List["ColorPartialInput"] + color: list["ColorPartialInput"] # Auto fields are optional @strawberry_django.input(models.Color, partial=True) class ColorPartialInput: id: auto name: auto - fruits: List[FruitPartialInput] + fruits: list[FruitPartialInput] # Alternate input; "name" field will be required @strawberry_django.input(models.Color, partial=True) class ColorNameRequiredPartialInput: id: auto name: str - fruits: List[FruitPartialInput] + fruits: list[FruitPartialInput] ``` ## Types from Django models diff --git a/examples/django/app/schema.py b/examples/django/app/schema.py index 6744f7a2..d0170c30 100644 --- a/examples/django/app/schema.py +++ b/examples/django/app/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -20,23 +18,23 @@ @strawberry.type class Query: fruit: Fruit = strawberry_django.field() - fruits: List[Fruit] = strawberry_django.field() + fruits: list[Fruit] = strawberry_django.field() color: Color = strawberry_django.field() - colors: List[Color] = strawberry_django.field() + colors: list[Color] = strawberry_django.field() @strawberry.type class Mutation: create_fruit: Fruit = mutations.create(FruitInput) - create_fruits: List[Fruit] = mutations.create(FruitInput) - update_fruits: List[Fruit] = mutations.update(FruitPartialInput) - delete_fruits: List[Fruit] = mutations.delete() + create_fruits: list[Fruit] = mutations.create(FruitInput) + update_fruits: list[Fruit] = mutations.update(FruitPartialInput) + delete_fruits: list[Fruit] = mutations.delete() create_color: Color = mutations.create(ColorInput) - create_colors: List[Color] = mutations.create(ColorInput) - update_colors: List[Color] = mutations.update(ColorPartialInput) - delete_colors: List[Color] = mutations.delete() + create_colors: list[Color] = mutations.create(ColorInput) + update_colors: list[Color] = mutations.update(ColorPartialInput) + delete_colors: list[Color] = mutations.delete() register: User = auth.register(UserInput) diff --git a/examples/django/app/types.py b/examples/django/app/types.py index dc2c2c3b..125b9f9d 100644 --- a/examples/django/app/types.py +++ b/examples/django/app/types.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Optional from strawberry import auto @@ -76,7 +76,7 @@ class Fruit: class Color: id: auto name: auto - fruits: List[Fruit] + fruits: list[Fruit] @strawberry_django.type(get_user_model()) diff --git a/poetry.lock b/poetry.lock index c1665529..8d70b470 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "asgiref" @@ -17,49 +17,6 @@ typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} [package.extras] tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] -[[package]] -name = "astunparse" -version = "1.6.3" -description = "An AST unparser for Python" -optional = false -python-versions = "*" -files = [ - {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, - {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, -] - -[package.dependencies] -six = ">=1.6.1,<2.0" -wheel = ">=0.23.0,<1.0" - -[[package]] -name = "backports-zoneinfo" -version = "0.2.1" -description = "Backport of the standard library zoneinfo module" -optional = false -python-versions = ">=3.6" -files = [ - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, - {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, -] - -[package.extras] -tzdata = ["tzdata"] - [[package]] name = "channels" version = "4.1.0" @@ -92,83 +49,73 @@ files = [ [[package]] name = "coverage" -version = "7.6.1" +version = "7.6.3" description = "Code coverage measurement for Python" optional = false -python-versions = ">=3.8" -files = [ - {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, - {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, - {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, - {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, - {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, - {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, - {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, - {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, - {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, - {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, - {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, - {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, - {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, - {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, - {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, - {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, - {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, - {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, +python-versions = ">=3.9" +files = [ + {file = "coverage-7.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6da42bbcec130b188169107ecb6ee7bd7b4c849d24c9370a0c884cf728d8e976"}, + {file = "coverage-7.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c222958f59b0ae091f4535851cbb24eb57fc0baea07ba675af718fb5302dddb2"}, + {file = "coverage-7.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab84a8b698ad5a6c365b08061920138e7a7dd9a04b6feb09ba1bfae68346ce6d"}, + {file = "coverage-7.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70a6756ce66cd6fe8486c775b30889f0dc4cb20c157aa8c35b45fd7868255c5c"}, + {file = "coverage-7.6.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c2e6fa98032fec8282f6b27e3f3986c6e05702828380618776ad794e938f53a"}, + {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:921fbe13492caf6a69528f09d5d7c7d518c8d0e7b9f6701b7719715f29a71e6e"}, + {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6d99198203f0b9cb0b5d1c0393859555bc26b548223a769baf7e321a627ed4fc"}, + {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:87cd2e29067ea397a47e352efb13f976eb1b03e18c999270bb50589323294c6e"}, + {file = "coverage-7.6.3-cp310-cp310-win32.whl", hash = "sha256:a3328c3e64ea4ab12b85999eb0779e6139295bbf5485f69d42cf794309e3d007"}, + {file = "coverage-7.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:bca4c8abc50d38f9773c1ec80d43f3768df2e8576807d1656016b9d3eeaa96fd"}, + {file = "coverage-7.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c51ef82302386d686feea1c44dbeef744585da16fcf97deea2a8d6c1556f519b"}, + {file = "coverage-7.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0ca37993206402c6c35dc717f90d4c8f53568a8b80f0bf1a1b2b334f4d488fba"}, + {file = "coverage-7.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c77326300b839c44c3e5a8fe26c15b7e87b2f32dfd2fc9fee1d13604347c9b38"}, + {file = "coverage-7.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e484e479860e00da1f005cd19d1c5d4a813324e5951319ac3f3eefb497cc549"}, + {file = "coverage-7.6.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c6c0f4d53ef603397fc894a895b960ecd7d44c727df42a8d500031716d4e8d2"}, + {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:37be7b5ea3ff5b7c4a9db16074dc94523b5f10dd1f3b362a827af66a55198175"}, + {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:43b32a06c47539fe275106b376658638b418c7cfdfff0e0259fbf877e845f14b"}, + {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ee77c7bef0724165e795b6b7bf9c4c22a9b8468a6bdb9c6b4281293c6b22a90f"}, + {file = "coverage-7.6.3-cp311-cp311-win32.whl", hash = "sha256:43517e1f6b19f610a93d8227e47790722c8bf7422e46b365e0469fc3d3563d97"}, + {file = "coverage-7.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:04f2189716e85ec9192df307f7c255f90e78b6e9863a03223c3b998d24a3c6c6"}, + {file = "coverage-7.6.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27bd5f18d8f2879e45724b0ce74f61811639a846ff0e5c0395b7818fae87aec6"}, + {file = "coverage-7.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d546cfa78844b8b9c1c0533de1851569a13f87449897bbc95d698d1d3cb2a30f"}, + {file = "coverage-7.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9975442f2e7a5cfcf87299c26b5a45266ab0696348420049b9b94b2ad3d40234"}, + {file = "coverage-7.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:583049c63106c0555e3ae3931edab5669668bbef84c15861421b94e121878d3f"}, + {file = "coverage-7.6.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2341a78ae3a5ed454d524206a3fcb3cec408c2a0c7c2752cd78b606a2ff15af4"}, + {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a4fb91d5f72b7e06a14ff4ae5be625a81cd7e5f869d7a54578fc271d08d58ae3"}, + {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e279f3db904e3b55f520f11f983cc8dc8a4ce9b65f11692d4718ed021ec58b83"}, + {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aa23ce39661a3e90eea5f99ec59b763b7d655c2cada10729ed920a38bfc2b167"}, + {file = "coverage-7.6.3-cp312-cp312-win32.whl", hash = "sha256:52ac29cc72ee7e25ace7807249638f94c9b6a862c56b1df015d2b2e388e51dbd"}, + {file = "coverage-7.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:40e8b1983080439d4802d80b951f4a93d991ef3261f69e81095a66f86cf3c3c6"}, + {file = "coverage-7.6.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9134032f5aa445ae591c2ba6991d10136a1f533b1d2fa8f8c21126468c5025c6"}, + {file = "coverage-7.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:99670790f21a96665a35849990b1df447993880bb6463a0a1d757897f30da929"}, + {file = "coverage-7.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc7d6b380ca76f5e817ac9eef0c3686e7834c8346bef30b041a4ad286449990"}, + {file = "coverage-7.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7b26757b22faf88fcf232f5f0e62f6e0fd9e22a8a5d0d5016888cdfe1f6c1c4"}, + {file = "coverage-7.6.3-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c59d6a4a4633fad297f943c03d0d2569867bd5372eb5684befdff8df8522e39"}, + {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f263b18692f8ed52c8de7f40a0751e79015983dbd77b16906e5b310a39d3ca21"}, + {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:79644f68a6ff23b251cae1c82b01a0b51bc40c8468ca9585c6c4b1aeee570e0b"}, + {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:71967c35828c9ff94e8c7d405469a1fb68257f686bca7c1ed85ed34e7c2529c4"}, + {file = "coverage-7.6.3-cp313-cp313-win32.whl", hash = "sha256:e266af4da2c1a4cbc6135a570c64577fd3e6eb204607eaff99d8e9b710003c6f"}, + {file = "coverage-7.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:ea52bd218d4ba260399a8ae4bb6b577d82adfc4518b93566ce1fddd4a49d1dce"}, + {file = "coverage-7.6.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8d4c6ea0f498c7c79111033a290d060c517853a7bcb2f46516f591dab628ddd3"}, + {file = "coverage-7.6.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:331b200ad03dbaa44151d74daeb7da2cf382db424ab923574f6ecca7d3b30de3"}, + {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54356a76b67cf8a3085818026bb556545ebb8353951923b88292556dfa9f812d"}, + {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebec65f5068e7df2d49466aab9128510c4867e532e07cb6960075b27658dca38"}, + {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d33a785ea8354c480515e781554d3be582a86297e41ccbea627a5c632647f2cd"}, + {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f7ddb920106bbbbcaf2a274d56f46956bf56ecbde210d88061824a95bdd94e92"}, + {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:70d24936ca6c15a3bbc91ee9c7fc661132c6f4c9d42a23b31b6686c05073bde5"}, + {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c30e42ea11badb147f0d2e387115b15e2bd8205a5ad70d6ad79cf37f6ac08c91"}, + {file = "coverage-7.6.3-cp313-cp313t-win32.whl", hash = "sha256:365defc257c687ce3e7d275f39738dcd230777424117a6c76043459db131dd43"}, + {file = "coverage-7.6.3-cp313-cp313t-win_amd64.whl", hash = "sha256:23bb63ae3f4c645d2d82fa22697364b0046fbafb6261b258a58587441c5f7bd0"}, + {file = "coverage-7.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:da29ceabe3025a1e5a5aeeb331c5b1af686daab4ff0fb4f83df18b1180ea83e2"}, + {file = "coverage-7.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:df8c05a0f574d480947cba11b947dc41b1265d721c3777881da2fb8d3a1ddfba"}, + {file = "coverage-7.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec1e3b40b82236d100d259854840555469fad4db64f669ab817279eb95cd535c"}, + {file = "coverage-7.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4adeb878a374126f1e5cf03b87f66279f479e01af0e9a654cf6d1509af46c40"}, + {file = "coverage-7.6.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43d6a66e33b1455b98fc7312b124296dad97a2e191c80320587234a77b1b736e"}, + {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1990b1f4e2c402beb317840030bb9f1b6a363f86e14e21b4212e618acdfce7f6"}, + {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:12f9515d875859faedb4144fd38694a761cd2a61ef9603bf887b13956d0bbfbb"}, + {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:99ded130555c021d99729fabd4ddb91a6f4cc0707df4b1daf912c7850c373b13"}, + {file = "coverage-7.6.3-cp39-cp39-win32.whl", hash = "sha256:c3a79f56dee9136084cf84a6c7c4341427ef36e05ae6415bf7d787c96ff5eaa3"}, + {file = "coverage-7.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:aac7501ae73d4a02f4b7ac8fcb9dc55342ca98ffb9ed9f2dfb8a25d53eda0e4d"}, + {file = "coverage-7.6.3-pp39.pp310-none-any.whl", hash = "sha256:b9853509b4bf57ba7b1f99b9d866c422c9c5248799ab20e652bbb8a184a38181"}, + {file = "coverage-7.6.3.tar.gz", hash = "sha256:bb7d5fe92bd0dc235f63ebe9f8c6e0884f7360f88f3411bfed1350c872ef2054"}, ] [package.dependencies] @@ -190,7 +137,6 @@ files = [ [package.dependencies] asgiref = ">=3.6.0,<4" -"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} sqlparse = ">=0.3.1" tzdata = {version = "*", markers = "sys_platform == \"win32\""} @@ -348,13 +294,13 @@ doc = ["Sphinx", "sphinx-rtd-theme", "sphinxcontrib-spelling"] [[package]] name = "faker" -version = "30.3.0" +version = "30.6.0" description = "Faker is a Python package that generates fake data for you." optional = false python-versions = ">=3.8" files = [ - {file = "Faker-30.3.0-py3-none-any.whl", hash = "sha256:e8a15fd1b0f72992b008f5ea94c70d3baa0cb51b0d5a0e899c17b1d1b23d2771"}, - {file = "faker-30.3.0.tar.gz", hash = "sha256:8760fbb34564fbb2f394345eef24aec5b8f6506b6cfcefe8195ed66dd1032bdb"}, + {file = "Faker-30.6.0-py3-none-any.whl", hash = "sha256:37b5ab951f7367ea93edb865120e9717a7a649d6a4b223f1e4a47a8a20d9e85f"}, + {file = "faker-30.6.0.tar.gz", hash = "sha256:be0e548352c1be6f6d9c982003848a0d305868f160bb1fb7f945acffc347e676"}, ] [package.dependencies] @@ -363,15 +309,18 @@ typing-extensions = "*" [[package]] name = "graphql-core" -version = "3.2.4" +version = "3.2.5" description = "GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL." optional = false python-versions = "<4,>=3.6" files = [ - {file = "graphql-core-3.2.4.tar.gz", hash = "sha256:acbe2e800980d0e39b4685dd058c2f4042660b89ebca38af83020fd872ff1264"}, - {file = "graphql_core-3.2.4-py3-none-any.whl", hash = "sha256:1604f2042edc5f3114f49cac9d77e25863be51b23a54a61a23245cf32f6476f0"}, + {file = "graphql_core-3.2.5-py3-none-any.whl", hash = "sha256:2f150d5096448aa4f8ab26268567bbfeef823769893b39c1a2e1409590939c8a"}, + {file = "graphql_core-3.2.5.tar.gz", hash = "sha256:e671b90ed653c808715645e3998b7ab67d382d55467b7e2978549111bbabf8d5"}, ] +[package.dependencies] +typing-extensions = {version = ">=4,<5", markers = "python_version < \"3.10\""} + [[package]] name = "iniconfig" version = "2.0.0" @@ -508,105 +457,96 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "psycopg2" -version = "2.9.9" +version = "2.9.10" description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "psycopg2-2.9.9-cp310-cp310-win32.whl", hash = "sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516"}, - {file = "psycopg2-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3"}, - {file = "psycopg2-2.9.9-cp311-cp311-win32.whl", hash = "sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372"}, - {file = "psycopg2-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981"}, - {file = "psycopg2-2.9.9-cp312-cp312-win32.whl", hash = "sha256:d735786acc7dd25815e89cc4ad529a43af779db2e25aa7c626de864127e5a024"}, - {file = "psycopg2-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:a7653d00b732afb6fc597e29c50ad28087dcb4fbfb28e86092277a559ae4e693"}, - {file = "psycopg2-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa"}, - {file = "psycopg2-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a"}, - {file = "psycopg2-2.9.9-cp38-cp38-win32.whl", hash = "sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c"}, - {file = "psycopg2-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e"}, - {file = "psycopg2-2.9.9-cp39-cp39-win32.whl", hash = "sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59"}, - {file = "psycopg2-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913"}, - {file = "psycopg2-2.9.9.tar.gz", hash = "sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156"}, + {file = "psycopg2-2.9.10-cp310-cp310-win32.whl", hash = "sha256:5df2b672140f95adb453af93a7d669d7a7bf0a56bcd26f1502329166f4a61716"}, + {file = "psycopg2-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:c6f7b8561225f9e711a9c47087388a97fdc948211c10a4bccbf0ba68ab7b3b5a"}, + {file = "psycopg2-2.9.10-cp311-cp311-win32.whl", hash = "sha256:47c4f9875125344f4c2b870e41b6aad585901318068acd01de93f3677a6522c2"}, + {file = "psycopg2-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4"}, + {file = "psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067"}, + {file = "psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e"}, + {file = "psycopg2-2.9.10-cp39-cp39-win32.whl", hash = "sha256:9d5b3b94b79a844a986d029eee38998232451119ad653aea42bb9220a8c5066b"}, + {file = "psycopg2-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:88138c8dedcbfa96408023ea2b0c369eda40fe5d75002c0964c78f46f11fa442"}, + {file = "psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11"}, ] [[package]] name = "psycopg2-binary" -version = "2.9.9" +version = "2.9.10" description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "psycopg2-binary-2.9.9.tar.gz", hash = "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-win32.whl", hash = "sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-win32.whl", hash = "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-win32.whl", hash = "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-win32.whl", hash = "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-win32.whl", hash = "sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957"}, + {file = "psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-win32.whl", hash = "sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-win32.whl", hash = "sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-win32.whl", hash = "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-win32.whl", hash = "sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5"}, ] [[package]] @@ -775,13 +715,13 @@ files = [ [[package]] name = "setuptools" -version = "75.1.0" +version = "75.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, + {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, ] [package.extras] @@ -821,17 +761,16 @@ doc = ["sphinx"] [[package]] name = "strawberry-graphql" -version = "0.246.1" +version = "0.246.2" description = "A library for creating GraphQL APIs" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "strawberry_graphql-0.246.1-py3-none-any.whl", hash = "sha256:4d2e7dd7b4f0776a31aefd60bb30430e28c9431bd5fe851637c328416cd1a413"}, - {file = "strawberry_graphql-0.246.1.tar.gz", hash = "sha256:f6eecca7eb823e55da9c20a9d4408c4fa029aac7ada83a0414e9fec1c11644a9"}, + {file = "strawberry_graphql-0.246.2-py3-none-any.whl", hash = "sha256:a18d6404ac982b6ddca937c34e2832910fbdb38945bce656498c8d30c341277b"}, + {file = "strawberry_graphql-0.246.2.tar.gz", hash = "sha256:ab3908014493cc0b98e45a8af2acd9980d18bd92a13d0c16811b1f49f3c62977"}, ] [package.dependencies] -astunparse = {version = ">=1.6.3,<2.0.0", markers = "python_version < \"3.9\""} graphql-core = ">=3.2.0,<3.4.0" python-dateutil = ">=2.7.0,<3.0.0" typing-extensions = ">=4.5.0" @@ -900,70 +839,51 @@ files = [ [[package]] name = "watchdog" -version = "4.0.2" +version = "5.0.3" description = "Filesystem events monitoring" optional = false -python-versions = ">=3.8" -files = [ - {file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ede7f010f2239b97cc79e6cb3c249e72962404ae3865860855d5cbe708b0fd22"}, - {file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2cffa171445b0efa0726c561eca9a27d00a1f2b83846dbd5a4f639c4f8ca8e1"}, - {file = "watchdog-4.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c50f148b31b03fbadd6d0b5980e38b558046b127dc483e5e4505fcef250f9503"}, - {file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7c7d4bf585ad501c5f6c980e7be9c4f15604c7cc150e942d82083b31a7548930"}, - {file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:914285126ad0b6eb2258bbbcb7b288d9dfd655ae88fa28945be05a7b475a800b"}, - {file = "watchdog-4.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:984306dc4720da5498b16fc037b36ac443816125a3705dfde4fd90652d8028ef"}, - {file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1cdcfd8142f604630deef34722d695fb455d04ab7cfe9963055df1fc69e6727a"}, - {file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7ab624ff2f663f98cd03c8b7eedc09375a911794dfea6bf2a359fcc266bff29"}, - {file = "watchdog-4.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:132937547a716027bd5714383dfc40dc66c26769f1ce8a72a859d6a48f371f3a"}, - {file = "watchdog-4.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd67c7df93eb58f360c43802acc945fa8da70c675b6fa37a241e17ca698ca49b"}, - {file = "watchdog-4.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcfd02377be80ef3b6bc4ce481ef3959640458d6feaae0bd43dd90a43da90a7d"}, - {file = "watchdog-4.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:980b71510f59c884d684b3663d46e7a14b457c9611c481e5cef08f4dd022eed7"}, - {file = "watchdog-4.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:aa160781cafff2719b663c8a506156e9289d111d80f3387cf3af49cedee1f040"}, - {file = "watchdog-4.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f6ee8dedd255087bc7fe82adf046f0b75479b989185fb0bdf9a98b612170eac7"}, - {file = "watchdog-4.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0b4359067d30d5b864e09c8597b112fe0a0a59321a0f331498b013fb097406b4"}, - {file = "watchdog-4.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:770eef5372f146997638d737c9a3c597a3b41037cfbc5c41538fc27c09c3a3f9"}, - {file = "watchdog-4.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eeea812f38536a0aa859972d50c76e37f4456474b02bd93674d1947cf1e39578"}, - {file = "watchdog-4.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b2c45f6e1e57ebb4687690c05bc3a2c1fb6ab260550c4290b8abb1335e0fd08b"}, - {file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:10b6683df70d340ac3279eff0b2766813f00f35a1d37515d2c99959ada8f05fa"}, - {file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7c739888c20f99824f7aa9d31ac8a97353e22d0c0e54703a547a218f6637eb3"}, - {file = "watchdog-4.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c100d09ac72a8a08ddbf0629ddfa0b8ee41740f9051429baa8e31bb903ad7508"}, - {file = "watchdog-4.0.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:f5315a8c8dd6dd9425b974515081fc0aadca1d1d61e078d2246509fd756141ee"}, - {file = "watchdog-4.0.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:2d468028a77b42cc685ed694a7a550a8d1771bb05193ba7b24006b8241a571a1"}, - {file = "watchdog-4.0.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f15edcae3830ff20e55d1f4e743e92970c847bcddc8b7509bcd172aa04de506e"}, - {file = "watchdog-4.0.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:936acba76d636f70db8f3c66e76aa6cb5136a936fc2a5088b9ce1c7a3508fc83"}, - {file = "watchdog-4.0.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:e252f8ca942a870f38cf785aef420285431311652d871409a64e2a0a52a2174c"}, - {file = "watchdog-4.0.2-py3-none-manylinux2014_i686.whl", hash = "sha256:0e83619a2d5d436a7e58a1aea957a3c1ccbf9782c43c0b4fed80580e5e4acd1a"}, - {file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:88456d65f207b39f1981bf772e473799fcdc10801062c36fd5ad9f9d1d463a73"}, - {file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:32be97f3b75693a93c683787a87a0dc8db98bb84701539954eef991fb35f5fbc"}, - {file = "watchdog-4.0.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:c82253cfc9be68e3e49282831afad2c1f6593af80c0daf1287f6a92657986757"}, - {file = "watchdog-4.0.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c0b14488bd336c5b1845cee83d3e631a1f8b4e9c5091ec539406e4a324f882d8"}, - {file = "watchdog-4.0.2-py3-none-win32.whl", hash = "sha256:0d8a7e523ef03757a5aa29f591437d64d0d894635f8a50f370fe37f913ce4e19"}, - {file = "watchdog-4.0.2-py3-none-win_amd64.whl", hash = "sha256:c344453ef3bf875a535b0488e3ad28e341adbd5a9ffb0f7d62cefacc8824ef2b"}, - {file = "watchdog-4.0.2-py3-none-win_ia64.whl", hash = "sha256:baececaa8edff42cd16558a639a9b0ddf425f93d892e8392a56bf904f5eff22c"}, - {file = "watchdog-4.0.2.tar.gz", hash = "sha256:b4dfbb6c49221be4535623ea4474a4d6ee0a9cef4a80b20c28db4d858b64e270"}, +python-versions = ">=3.9" +files = [ + {file = "watchdog-5.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:85527b882f3facda0579bce9d743ff7f10c3e1e0db0a0d0e28170a7d0e5ce2ea"}, + {file = "watchdog-5.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:53adf73dcdc0ef04f7735066b4a57a4cd3e49ef135daae41d77395f0b5b692cb"}, + {file = "watchdog-5.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e25adddab85f674acac303cf1f5835951345a56c5f7f582987d266679979c75b"}, + {file = "watchdog-5.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f01f4a3565a387080dc49bdd1fefe4ecc77f894991b88ef927edbfa45eb10818"}, + {file = "watchdog-5.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:91b522adc25614cdeaf91f7897800b82c13b4b8ac68a42ca959f992f6990c490"}, + {file = "watchdog-5.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d52db5beb5e476e6853da2e2d24dbbbed6797b449c8bf7ea118a4ee0d2c9040e"}, + {file = "watchdog-5.0.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d11b07c64f63f49876e0ab8042ae034674c8653bfcdaa8c4b32e71cfff87e8"}, + {file = "watchdog-5.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:349c9488e1d85d0a58e8cb14222d2c51cbc801ce11ac3936ab4c3af986536926"}, + {file = "watchdog-5.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:53a3f10b62c2d569e260f96e8d966463dec1a50fa4f1b22aec69e3f91025060e"}, + {file = "watchdog-5.0.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:950f531ec6e03696a2414b6308f5c6ff9dab7821a768c9d5788b1314e9a46ca7"}, + {file = "watchdog-5.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae6deb336cba5d71476caa029ceb6e88047fc1dc74b62b7c4012639c0b563906"}, + {file = "watchdog-5.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1021223c08ba8d2d38d71ec1704496471ffd7be42cfb26b87cd5059323a389a1"}, + {file = "watchdog-5.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:752fb40efc7cc8d88ebc332b8f4bcbe2b5cc7e881bccfeb8e25054c00c994ee3"}, + {file = "watchdog-5.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a2e8f3f955d68471fa37b0e3add18500790d129cc7efe89971b8a4cc6fdeb0b2"}, + {file = "watchdog-5.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b8ca4d854adcf480bdfd80f46fdd6fb49f91dd020ae11c89b3a79e19454ec627"}, + {file = "watchdog-5.0.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:90a67d7857adb1d985aca232cc9905dd5bc4803ed85cfcdcfcf707e52049eda7"}, + {file = "watchdog-5.0.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:720ef9d3a4f9ca575a780af283c8fd3a0674b307651c1976714745090da5a9e8"}, + {file = "watchdog-5.0.3-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:223160bb359281bb8e31c8f1068bf71a6b16a8ad3d9524ca6f523ac666bb6a1e"}, + {file = "watchdog-5.0.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:560135542c91eaa74247a2e8430cf83c4342b29e8ad4f520ae14f0c8a19cfb5b"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dd021efa85970bd4824acacbb922066159d0f9e546389a4743d56919b6758b91"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_armv7l.whl", hash = "sha256:78864cc8f23dbee55be34cc1494632a7ba30263951b5b2e8fc8286b95845f82c"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_i686.whl", hash = "sha256:1e9679245e3ea6498494b3028b90c7b25dbb2abe65c7d07423ecfc2d6218ff7c"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_ppc64.whl", hash = "sha256:9413384f26b5d050b6978e6fcd0c1e7f0539be7a4f1a885061473c5deaa57221"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:294b7a598974b8e2c6123d19ef15de9abcd282b0fbbdbc4d23dfa812959a9e05"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_s390x.whl", hash = "sha256:26dd201857d702bdf9d78c273cafcab5871dd29343748524695cecffa44a8d97"}, + {file = "watchdog-5.0.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:0f9332243355643d567697c3e3fa07330a1d1abf981611654a1f2bf2175612b7"}, + {file = "watchdog-5.0.3-py3-none-win32.whl", hash = "sha256:c66f80ee5b602a9c7ab66e3c9f36026590a0902db3aea414d59a2f55188c1f49"}, + {file = "watchdog-5.0.3-py3-none-win_amd64.whl", hash = "sha256:f00b4cf737f568be9665563347a910f8bdc76f88c2970121c86243c8cfdf90e9"}, + {file = "watchdog-5.0.3-py3-none-win_ia64.whl", hash = "sha256:49f4d36cb315c25ea0d946e018c01bb028048023b9e103d3d3943f58e109dd45"}, + {file = "watchdog-5.0.3.tar.gz", hash = "sha256:108f42a7f0345042a854d4d0ad0834b741d421330d5f575b81cb27b883500176"}, ] [package.extras] watchmedo = ["PyYAML (>=3.10)"] -[[package]] -name = "wheel" -version = "0.44.0" -description = "A built-package format for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "wheel-0.44.0-py3-none-any.whl", hash = "sha256:2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f"}, - {file = "wheel-0.44.0.tar.gz", hash = "sha256:a29c3f2817e95ab89aa4660681ad547c0e9547f20e75b0562fe7723c9a2a9d49"}, -] - -[package.extras] -test = ["pytest (>=6.0.0)", "setuptools (>=65)"] - [extras] debug-toolbar = ["django-debug-toolbar"] enum = ["django-choices-field"] [metadata] lock-version = "2.0" -python-versions = ">=3.8,<4.0" -content-hash = "b840b15c90ddd22f5123b16c4afed71b653a4742c61e8e3365eeafa31d93acb5" +python-versions = ">=3.9,<4.0" +content-hash = "11cdb8955be26da989f5d6274e42d2680e3a50c69a24bca3f6ce2b894808d110" diff --git a/pyproject.toml b/pyproject.toml index 7f6933de..d45f8e5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,19 +20,19 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Framework :: Django", "Framework :: Django :: 4.2", "Framework :: Django :: 5.0", ] [tool.poetry.dependencies] -python = ">=3.8,<4.0" -django = ">=3.2" +python = ">=3.9,<4.0" +django = ">=4.2" asgiref = ">=3.8" django-choices-field = { version = ">=2.2.2", optional = true } django-debug-toolbar = { version = ">=3.4", optional = true } @@ -69,7 +69,7 @@ requires = ["poetry-core>=1.0.0", "setuptools"] build-backend = "poetry.core.masonry.api" [tool.ruff] -target-version = "py38" +target-version = "py39" preview = true [tool.ruff.lint] @@ -147,8 +147,6 @@ extend-ignore = [ "Q003", "W191", ] -# FIXME: Enable autofix for UP006 when we don't need to support django 3.8 anymore -extend-unfixable = ["UP006"] exclude = [ ".eggs", ".git", @@ -176,7 +174,7 @@ max-nested-blocks = 7 [tool.ruff.format] [tool.pyright] -pythonVersion = "3.8" +pythonVersion = "3.9" useLibraryCodeForTypes = true exclude = [".venv", "**/migrations", "dist", "docs"] reportCallInDefaultInitializer = "warning" diff --git a/strawberry_django/arguments.py b/strawberry_django/arguments.py index ecf55f29..e715c7af 100644 --- a/strawberry_django/arguments.py +++ b/strawberry_django/arguments.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Optional from strawberry import UNSET from strawberry.annotation import StrawberryAnnotation @@ -14,7 +14,7 @@ def argument( default: object = UNSET, ): if is_list: - type_ = List[type_] + type_ = list[type_] if is_optional: type_ = Optional[type_] diff --git a/strawberry_django/auth/mutations.py b/strawberry_django/auth/mutations.py index fc109b96..d7658e5f 100644 --- a/strawberry_django/auth/mutations.py +++ b/strawberry_django/auth/mutations.py @@ -1,7 +1,7 @@ from __future__ import annotations import functools -from typing import TYPE_CHECKING, Any, Type, cast +from typing import TYPE_CHECKING, Any, cast import strawberry from asgiref.sync import async_to_sync @@ -77,7 +77,7 @@ def resolve_logout(info: Info) -> bool: class DjangoRegisterMutation(DjangoCreateMutation): def create(self, data: dict[str, Any], *, info: Info): - model = cast(Type["AbstractBaseUser"], self.django_model) + model = cast(type["AbstractBaseUser"], self.django_model) assert model is not None password = data.pop("password") diff --git a/strawberry_django/descriptors.py b/strawberry_django/descriptors.py index b1df22db..acd7fcdd 100644 --- a/strawberry_django/descriptors.py +++ b/strawberry_django/descriptors.py @@ -3,10 +3,8 @@ TYPE_CHECKING, Any, Callable, - Dict, Generic, Optional, - Type, TypeVar, Union, overload, @@ -42,7 +40,7 @@ def __init__( func: Callable[[_M], _R], *, cached: bool = False, - meta: Optional[Dict[Any, Any]] = None, + meta: Optional[dict[Any, Any]] = None, only: Optional["TypeOrSequence[str]"] = None, select_related: Optional["TypeOrSequence[str]"] = None, prefetch_related: Optional["TypeOrSequence[PrefetchType]"] = None, @@ -62,15 +60,15 @@ def __init__( annotate=annotate, ) - def __set_name__(self, owner: Type[_M], name: str): + def __set_name__(self, owner: type[_M], name: str): self.origin = owner self.name = name @overload - def __get__(self, obj: _M, cls: Type[_M]) -> _R: ... + def __get__(self, obj: _M, cls: type[_M]) -> _R: ... @overload - def __get__(self, obj: None, cls: Type[_M]) -> Self: ... + def __get__(self, obj: None, cls: type[_M]) -> Self: ... def __get__(self, obj, cls=None): if obj is None: @@ -106,7 +104,7 @@ def model_property( func: Callable[[_M], _R], *, cached: bool = False, - meta: Optional[Dict[Any, Any]] = None, + meta: Optional[dict[Any, Any]] = None, only: Optional["TypeOrSequence[str]"] = None, select_related: Optional["TypeOrSequence[str]"] = None, prefetch_related: Optional["TypeOrSequence[PrefetchType]"] = None, @@ -119,7 +117,7 @@ def model_property( func: None = ..., *, cached: bool = False, - meta: Optional[Dict[Any, Any]] = None, + meta: Optional[dict[Any, Any]] = None, only: Optional["TypeOrSequence[str]"] = None, select_related: Optional["TypeOrSequence[str]"] = None, prefetch_related: Optional["TypeOrSequence[PrefetchType]"] = None, @@ -131,7 +129,7 @@ def model_property( func=None, *, cached: bool = False, - meta: Optional[Dict[Any, Any]] = None, + meta: Optional[dict[Any, Any]] = None, only: Optional["TypeOrSequence[str]"] = None, select_related: Optional["TypeOrSequence[str]"] = None, prefetch_related: Optional["TypeOrSequence[PrefetchType]"] = None, @@ -157,7 +155,7 @@ def wrapper(f): def model_cached_property( func=None, *, - meta: Optional[Dict[Any, Any]] = None, + meta: Optional[dict[Any, Any]] = None, only: Optional["TypeOrSequence[str]"] = None, select_related: Optional["TypeOrSequence[str]"] = None, prefetch_related: Optional["TypeOrSequence[PrefetchType]"] = None, diff --git a/strawberry_django/extensions/django_cache_base.py b/strawberry_django/extensions/django_cache_base.py index 68b67087..8882b13a 100644 --- a/strawberry_django/extensions/django_cache_base.py +++ b/strawberry_django/extensions/django_cache_base.py @@ -1,5 +1,6 @@ +from collections.abc import Hashable from functools import _make_key # noqa: PLC2701 -from typing import Callable, Dict, Hashable, Optional, Tuple, cast +from typing import Callable, Optional, cast from django.core.cache import caches from django.core.cache.backends.base import DEFAULT_TIMEOUT @@ -31,7 +32,7 @@ def __init__( self, cache_name: str = "default", timeout: Optional[int] = None, - hash_fn: Optional[Callable[[Tuple, Dict], Hashable]] = None, + hash_fn: Optional[Callable[[tuple, dict], Hashable]] = None, *, execution_context: Optional[ExecutionContext] = None, ): diff --git a/strawberry_django/extensions/django_validation_cache.py b/strawberry_django/extensions/django_validation_cache.py index 384a7efa..4d49fdd4 100644 --- a/strawberry_django/extensions/django_validation_cache.py +++ b/strawberry_django/extensions/django_validation_cache.py @@ -1,4 +1,4 @@ -from typing import Iterator +from collections.abc import Iterator from strawberry.schema.execute import validate_document diff --git a/strawberry_django/fields/field.py b/strawberry_django/fields/field.py index 9c48352d..20a512fc 100644 --- a/strawberry_django/fields/field.py +++ b/strawberry_django/fields/field.py @@ -2,14 +2,12 @@ import dataclasses import inspect +from collections.abc import Iterable, Mapping, Sequence from functools import cached_property from typing import ( TYPE_CHECKING, Any, Callable, - Iterable, - Mapping, - Sequence, TypeVar, cast, overload, diff --git a/strawberry_django/fields/filter_order.py b/strawberry_django/fields/filter_order.py index d00e4a5d..a8ef5c9e 100644 --- a/strawberry_django/fields/filter_order.py +++ b/strawberry_django/fields/filter_order.py @@ -3,7 +3,7 @@ import dataclasses import inspect from functools import cached_property -from typing import TYPE_CHECKING, Any, Final, Literal, Optional, Sequence, overload +from typing import TYPE_CHECKING, Any, Final, Literal, Optional, overload from strawberry import UNSET from strawberry.annotation import StrawberryAnnotation @@ -19,7 +19,7 @@ from strawberry_django.utils.typing import is_auto if TYPE_CHECKING: - from collections.abc import Callable, MutableMapping + from collections.abc import Callable, MutableMapping, Sequence from strawberry.extensions.field_extension import FieldExtension from strawberry.types import Info diff --git a/strawberry_django/fields/filter_types.py b/strawberry_django/fields/filter_types.py index 9468afd9..1c05ccbb 100644 --- a/strawberry_django/fields/filter_types.py +++ b/strawberry_django/fields/filter_types.py @@ -3,7 +3,6 @@ import uuid from typing import ( Generic, - List, Optional, TypeVar, ) @@ -25,7 +24,7 @@ class BaseFilterLookup(Generic[T]): exact: Optional[T] = filter_field(description=f"Exact match. {_SKIP_MSG}") is_null: Optional[bool] = filter_field(description=f"Assignment test. {_SKIP_MSG}") - in_list: Optional[List[T]] = filter_field( + in_list: Optional[list[T]] = filter_field( description=f"Exact match of items in a given list. {_SKIP_MSG}" ) diff --git a/strawberry_django/fields/types.py b/strawberry_django/fields/types.py index fae48869..7eecd83b 100644 --- a/strawberry_django/fields/types.py +++ b/strawberry_django/fields/types.py @@ -7,13 +7,9 @@ from typing import ( TYPE_CHECKING, Any, - Dict, Generic, - List, NewType, Optional, - Tuple, - Type, TypeVar, Union, ) @@ -88,16 +84,16 @@ class OneToManyInput: @strawberry.input class ManyToOneInput: - add: Optional[List[strawberry.ID]] = UNSET - remove: Optional[List[strawberry.ID]] = UNSET - set: Optional[List[strawberry.ID]] = UNSET + add: Optional[list[strawberry.ID]] = UNSET + remove: Optional[list[strawberry.ID]] = UNSET + set: Optional[list[strawberry.ID]] = UNSET @strawberry.input class ManyToManyInput: - add: Optional[List[strawberry.ID]] = UNSET - remove: Optional[List[strawberry.ID]] = UNSET - set: Optional[List[strawberry.ID]] = UNSET + add: Optional[list[strawberry.ID]] = UNSET + remove: Optional[list[strawberry.ID]] = UNSET + set: Optional[list[strawberry.ID]] = UNSET @strawberry.input( @@ -142,13 +138,13 @@ class ListInput(Generic[K]): # FIXME: Without this pyright will not let any class inheric from this and define # a field that doesn't contain a default value... if TYPE_CHECKING: - set: Optional[List[K]] - add: Optional[List[K]] - remove: Optional[List[K]] + set: Optional[list[K]] + add: Optional[list[K]] + remove: Optional[list[K]] else: - set: Optional[List[K]] = UNSET - add: Optional[List[K]] = UNSET - remove: Optional[List[K]] = UNSET + set: Optional[list[K]] = UNSET + add: Optional[list[K]] = UNSET + remove: Optional[list[K]] = UNSET def __eq__(self, other: object): if not isinstance(other, ListInput): @@ -214,7 +210,7 @@ def __hash__(self): class OperationInfo: """Multiple messages returned by an operation.""" - messages: List[OperationMessage] = strawberry.field( + messages: list[OperationMessage] = strawberry.field( description="List of messages returned by the operation.", ) @@ -228,11 +224,11 @@ def __hash__(self): return hash((self.__class__, *tuple(self.messages))) -field_type_map: Dict[ +field_type_map: dict[ Union[ - Type[fields.Field], - Type[related.RelatedField], - Type[reverse_related.ForeignObjectRel], + type[fields.Field], + type[related.RelatedField], + type[reverse_related.ForeignObjectRel], ], type, ] = { @@ -263,10 +259,10 @@ def __hash__(self): files.FileField: DjangoFileType, files.ImageField: DjangoImageType, related.ForeignKey: DjangoModelType, - related.ManyToManyField: List[DjangoModelType], + related.ManyToManyField: list[DjangoModelType], related.OneToOneField: DjangoModelType, - reverse_related.ManyToManyRel: List[DjangoModelType], - reverse_related.ManyToOneRel: List[DjangoModelType], + reverse_related.ManyToManyRel: list[DjangoModelType], + reverse_related.ManyToOneRel: list[DjangoModelType], reverse_related.OneToOneRel: DjangoModelType, } @@ -285,14 +281,14 @@ def __hash__(self): MultiPolygon = None else: Point = strawberry.scalar( - NewType("Point", Tuple[float, float, Optional[float]]), + NewType("Point", tuple[float, float, Optional[float]]), serialize=lambda v: v.tuple if isinstance(v, geos.Point) else v, parse_value=geos.Point, description="Represents a point as `(x, y, z)` or `(x, y)`.", ) LineString = strawberry.scalar( - NewType("LineString", Tuple[Point]), + NewType("LineString", tuple[Point]), serialize=lambda v: v.tuple if isinstance(v, geos.LineString) else v, parse_value=geos.LineString, description=( @@ -302,7 +298,7 @@ def __hash__(self): ) LinearRing = strawberry.scalar( - NewType("LinearRing", Tuple[Point]), + NewType("LinearRing", tuple[Point]), serialize=lambda v: v.tuple if isinstance(v, geos.LinearRing) else v, parse_value=geos.LinearRing, description=( @@ -313,7 +309,7 @@ def __hash__(self): ) Polygon = strawberry.scalar( - NewType("Polygon", Tuple[LinearRing]), + NewType("Polygon", tuple[LinearRing]), serialize=lambda v: v.tuple if isinstance(v, geos.Polygon) else v, parse_value=lambda v: geos.Polygon(*[geos.LinearRing(x) for x in v]), description=( @@ -323,21 +319,21 @@ def __hash__(self): ) MultiPoint = strawberry.scalar( - NewType("MultiPoint", Tuple[Point]), + NewType("MultiPoint", tuple[Point]), serialize=lambda v: v.tuple if isinstance(v, geos.MultiPoint) else v, parse_value=lambda v: geos.MultiPoint(*[geos.Point(x) for x in v]), description="A geographical object that contains multiple Points.", ) MultiLineString = strawberry.scalar( - NewType("MultiLineString", Tuple[LineString]), + NewType("MultiLineString", tuple[LineString]), serialize=lambda v: v.tuple if isinstance(v, geos.MultiLineString) else v, parse_value=lambda v: geos.MultiLineString(*[geos.LineString(x) for x in v]), description="A geographical object that contains multiple line strings.", ) MultiPolygon = strawberry.scalar( - NewType("MultiPolygon", Tuple[Polygon]), + NewType("MultiPolygon", tuple[Polygon]), serialize=lambda v: v.tuple if isinstance(v, geos.MultiPolygon) else v, parse_value=lambda v: geos.MultiPolygon( *[geos.Polygon(*list(x)) for x in v], @@ -357,11 +353,11 @@ def __hash__(self): ) -input_field_type_map: Dict[ +input_field_type_map: dict[ Union[ - Type[fields.Field], - Type[related.RelatedField], - Type[reverse_related.ForeignObjectRel], + type[fields.Field], + type[related.RelatedField], + type[reverse_related.ForeignObjectRel], ], type, ] = { @@ -376,30 +372,30 @@ def __hash__(self): } -relay_field_type_map: Dict[ +relay_field_type_map: dict[ Union[ - Type[fields.Field], - Type[related.RelatedField], - Type[reverse_related.ForeignObjectRel], + type[fields.Field], + type[related.RelatedField], + type[reverse_related.ForeignObjectRel], ], type, ] = { fields.AutoField: relay.GlobalID, fields.BigAutoField: relay.GlobalID, related.ForeignKey: relay.Node, - related.ManyToManyField: List[relay.Node], + related.ManyToManyField: list[relay.Node], related.OneToOneField: relay.Node, - reverse_related.ManyToManyRel: List[relay.Node], - reverse_related.ManyToOneRel: List[relay.Node], + reverse_related.ManyToManyRel: list[relay.Node], + reverse_related.ManyToOneRel: list[relay.Node], reverse_related.OneToOneRel: relay.Node, } -relay_input_field_type_map: Dict[ +relay_input_field_type_map: dict[ Union[ - Type[fields.Field], - Type[related.RelatedField], - Type[reverse_related.ForeignObjectRel], + type[fields.Field], + type[related.RelatedField], + type[reverse_related.ForeignObjectRel], ], type, ] = { @@ -415,7 +411,7 @@ def __hash__(self): def _resolve_array_field_type(model_field: Field): assert ArrayField is not None if isinstance(model_field, ArrayField): - return List[_resolve_array_field_type(model_field.base_field)] + return list[_resolve_array_field_type(model_field.base_field)] base_field = field_type_map.get(type(model_field), NotImplemented) if base_field is NotImplemented: # type: ignore @@ -565,7 +561,7 @@ def resolve_model_field_name( return model_field.name -def get_model_field(model: Type[Model], field_name: str): +def get_model_field(model: type[Model], field_name: str): try: return model._meta.get_field(field_name) except FieldDoesNotExist as e: diff --git a/strawberry_django/filters.py b/strawberry_django/filters.py index 5cfdbf1b..dd5d789a 100644 --- a/strawberry_django/filters.py +++ b/strawberry_django/filters.py @@ -10,12 +10,7 @@ Any, Callable, Generic, - List, - Optional, - Sequence, - Tuple, TypeVar, - Union, cast, ) @@ -45,6 +40,7 @@ from .settings import strawberry_django_settings if TYPE_CHECKING: + from collections.abc import Sequence from types import FunctionType from django.db.models import Model @@ -87,23 +83,23 @@ def _get_id(root) -> str: @strawberry.input class FilterLookup(Generic[T]): - exact: Optional[T] = UNSET - i_exact: Optional[T] = UNSET - contains: Optional[T] = UNSET - i_contains: Optional[T] = UNSET - in_list: Optional[List[T]] = UNSET - gt: Optional[T] = UNSET - gte: Optional[T] = UNSET - lt: Optional[T] = UNSET - lte: Optional[T] = UNSET - starts_with: Optional[T] = UNSET - i_starts_with: Optional[T] = UNSET - ends_with: Optional[T] = UNSET - i_ends_with: Optional[T] = UNSET - range: Optional[List[T]] = UNSET - is_null: Optional[bool] = UNSET - regex: Optional[str] = UNSET - i_regex: Optional[str] = UNSET + exact: T | None = UNSET + i_exact: T | None = UNSET + contains: T | None = UNSET + i_contains: T | None = UNSET + in_list: list[T] | None = UNSET + gt: T | None = UNSET + gte: T | None = UNSET + lt: T | None = UNSET + lte: T | None = UNSET + starts_with: T | None = UNSET + i_starts_with: T | None = UNSET + ends_with: T | None = UNSET + i_ends_with: T | None = UNSET + range: list[T] | None = UNSET + is_null: bool | None = UNSET + regex: str | None = UNSET + i_regex: str | None = UNSET lookup_name_conversion_map = { @@ -162,7 +158,7 @@ def process_filters( info: Info | None, prefix: str = "", skip_object_filter_method: bool = False, -) -> Tuple[_QS, Q]: +) -> tuple[_QS, Q]: using_old_filters = strawberry_django_settings()["USE_DEPRECATED_FILTERS"] q = Q() @@ -276,7 +272,7 @@ def apply( class StrawberryDjangoFieldFilters(StrawberryDjangoFieldBase): - def __init__(self, filters: Union[type, UnsetType, None] = UNSET, **kwargs): + def __init__(self, filters: type | UnsetType | None = UNSET, **kwargs): if filters and not has_object_definition(filters): raise TypeError("filters needs to be a strawberry type") @@ -289,7 +285,7 @@ def __copy__(self) -> Self: return new_field @property - def arguments(self) -> List[StrawberryArgument]: + def arguments(self) -> list[StrawberryArgument]: arguments = [] if self.base_resolver is None: filters = self.get_filters() @@ -303,7 +299,7 @@ def arguments(self) -> List[StrawberryArgument]: ): arguments.append( ( - argument("ids", List[relay.GlobalID]) + argument("ids", list[relay.GlobalID]) if self.is_list else argument("id", relay.GlobalID) ), @@ -348,7 +344,7 @@ def get_queryset( queryset: _QS, info: Info, *, - filters: Optional[WithStrawberryDjangoObjectDefinition] = None, + filters: WithStrawberryDjangoObjectDefinition | None = None, **kwargs, ) -> _QS: settings = strawberry_django_settings() diff --git a/strawberry_django/integrations/guardian.py b/strawberry_django/integrations/guardian.py index b1656dc1..1c7c6d20 100644 --- a/strawberry_django/integrations/guardian.py +++ b/strawberry_django/integrations/guardian.py @@ -1,6 +1,6 @@ import contextlib import dataclasses -from typing import Type, Union, cast +from typing import Union, cast from django.contrib.auth import get_user_model from django.db import models @@ -19,7 +19,7 @@ class ObjectPermissionModels: def get_object_permission_models( - model: Union[models.Model, Type[models.Model]], + model: Union[models.Model, type[models.Model]], ) -> ObjectPermissionModels: return ObjectPermissionModels( user=cast(UserObjectPermissionBase, get_user_obj_perms_model(model)), diff --git a/strawberry_django/mutations/fields.py b/strawberry_django/mutations/fields.py index f9ef37c6..5296cd37 100644 --- a/strawberry_django/mutations/fields.py +++ b/strawberry_django/mutations/fields.py @@ -1,7 +1,7 @@ from __future__ import annotations import inspect -from typing import TYPE_CHECKING, Any, Iterable, Union +from typing import TYPE_CHECKING, Annotated, Any, Union import strawberry from django.core.exceptions import ( @@ -15,7 +15,6 @@ from strawberry.annotation import StrawberryAnnotation from strawberry.types.field import UNRESOLVED from strawberry.utils.str_converters import capitalize_first, to_camel_case -from typing_extensions import Annotated from strawberry_django.arguments import argument from strawberry_django.fields.field import ( @@ -32,6 +31,8 @@ from . import resolvers if TYPE_CHECKING: + from collections.abc import Iterable + from graphql.pyutils import AwaitableOrValue from strawberry.types import Info from strawberry.types.arguments import StrawberryArgument diff --git a/strawberry_django/mutations/mutations.py b/strawberry_django/mutations/mutations.py index ebd4f523..405488ef 100644 --- a/strawberry_django/mutations/mutations.py +++ b/strawberry_django/mutations/mutations.py @@ -1,12 +1,9 @@ import dataclasses +from collections.abc import Mapping, Sequence from typing import ( Any, Callable, - List, - Mapping, Optional, - Sequence, - Type, TypeVar, Union, overload, @@ -39,14 +36,14 @@ def mutation( is_subscription: bool = False, description: Optional[str] = None, init: Literal[False] = False, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), graphql_type: Optional[Any] = None, - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore handle_django_errors: Optional[bool] = None, ) -> _T: ... @@ -59,14 +56,14 @@ def mutation( is_subscription: bool = False, description: Optional[str] = None, init: Literal[True] = True, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), graphql_type: Optional[Any] = None, - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore handle_django_errors: Optional[bool] = None, ) -> Any: ... @@ -79,14 +76,14 @@ def mutation( field_name: Optional[str] = None, is_subscription: bool = False, description: Optional[str] = None, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), graphql_type: Optional[Any] = None, - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore handle_django_errors: Optional[bool] = None, ) -> DjangoMutationBase: ... @@ -98,14 +95,14 @@ def mutation( field_name: Optional[str] = None, is_subscription: bool = False, description: Optional[str] = None, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), graphql_type: Optional[Any] = None, - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore handle_django_errors: Optional[bool] = None, # This init parameter is used by pyright to determine whether this field # is added in the constructor or not. It is not used to change @@ -145,14 +142,14 @@ def input_mutation( is_subscription: bool = False, description: Optional[str] = None, init: Literal[False] = False, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), graphql_type: Optional[Any] = None, - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore handle_django_errors: Optional[bool] = None, ) -> _T: ... @@ -165,14 +162,14 @@ def input_mutation( is_subscription: bool = False, description: Optional[str] = None, init: Literal[True] = True, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), graphql_type: Optional[Any] = None, - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore handle_django_errors: Optional[bool] = None, ) -> Any: ... @@ -185,14 +182,14 @@ def input_mutation( field_name: Optional[str] = None, is_subscription: bool = False, description: Optional[str] = None, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), graphql_type: Optional[Any] = None, - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore handle_django_errors: Optional[bool] = None, ) -> DjangoMutationBase: ... @@ -204,14 +201,14 @@ def input_mutation( field_name: Optional[str] = None, is_subscription: bool = False, description: Optional[str] = None, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), graphql_type: Optional[Any] = None, - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore handle_django_errors: Optional[bool] = None, # This init parameter is used by pyright to determine whether this field # is added in the constructor or not. It is not used to change @@ -251,14 +248,14 @@ def create( is_subscription: bool = False, description: Optional[str] = None, init: Literal[True] = True, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), graphql_type: Optional[Any] = None, - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore argument_name: Optional[str] = None, handle_django_errors: Optional[bool] = None, ) -> Any: @@ -309,14 +306,14 @@ def update( is_subscription: bool = False, description: Optional[str] = None, init: Literal[True] = True, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), graphql_type: Optional[Any] = None, - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore argument_name: Optional[str] = None, handle_django_errors: Optional[bool] = None, key_attr: Optional[str] = None, @@ -368,13 +365,13 @@ def delete( is_subscription: bool = False, description: Optional[str] = None, init: Literal[True] = True, - permission_classes: Optional[List[Type[BasePermission]]] = None, + permission_classes: Optional[list[type[BasePermission]]] = None, deprecation_reason: Optional[str] = None, default: Any = dataclasses.MISSING, default_factory: Union[Callable[..., object], object] = dataclasses.MISSING, metadata: Optional[Mapping[Any, Any]] = None, directives: Optional[Sequence[object]] = (), - extensions: List[FieldExtension] = (), # type: ignore + extensions: list[FieldExtension] = (), # type: ignore graphql_type: Optional[Any] = None, argument_name: Optional[str] = None, handle_django_errors: Optional[bool] = None, diff --git a/strawberry_django/mutations/resolvers.py b/strawberry_django/mutations/resolvers.py index db8b5315..6be05e9d 100644 --- a/strawberry_django/mutations/resolvers.py +++ b/strawberry_django/mutations/resolvers.py @@ -1,14 +1,12 @@ from __future__ import annotations import dataclasses +from collections.abc import Iterable from enum import Enum from typing import ( TYPE_CHECKING, Any, Callable, - Iterable, - List, - Type, TypeVar, cast, overload, @@ -192,13 +190,13 @@ def parse_input( return ParsedObjectList( add=cast( - List[InputListTypes], parse_input(info, data.add, key_attr=key_attr) + list[InputListTypes], parse_input(info, data.add, key_attr=key_attr) ), remove=cast( - List[InputListTypes], parse_input(info, data.remove, key_attr=key_attr) + list[InputListTypes], parse_input(info, data.remove, key_attr=key_attr) ), set=cast( - List[InputListTypes], parse_input(info, data.set, key_attr=key_attr) + list[InputListTypes], parse_input(info, data.set, key_attr=key_attr) ), ) @@ -265,7 +263,7 @@ def prepare_create_update( ): value, value_data = _parse_data( # noqa: PLW2901 info, - cast(Type[Model], field.related_model), + cast(type[Model], field.related_model), value, key_attr=key_attr, ) @@ -513,7 +511,7 @@ def update_field(info: Info, instance: Model, field: models.Field, value: Any): and isinstance(field, models.ForeignObject) and not isinstance(value, Model) ): - value, data = _parse_pk(value, cast(Type[Model], field.related_model)) + value, data = _parse_pk(value, cast(type[Model], field.related_model)) field.save_form_data(instance, value) # If data was passed to the foreign key, update it recursively @@ -580,7 +578,7 @@ def update_m2m( need_remove_cache = need_remove_cache or bool(values) for v in values: obj, data = _parse_data( - info, cast(Type[Model], manager.model), v, key_attr=key_attr + info, cast(type[Model], manager.model), v, key_attr=key_attr ) if obj: data.pop(key_attr, None) @@ -641,7 +639,7 @@ def update_m2m( for v in value.add or []: obj, data = _parse_data( info, - cast(Type[Model], manager.model), + cast(type[Model], manager.model), v, key_attr=key_attr, ) @@ -666,7 +664,7 @@ def update_m2m( need_remove_cache = need_remove_cache or bool(value.remove) for v in value.remove or []: obj, data = _parse_data( - info, cast(Type[Model], manager.model), v, key_attr=key_attr + info, cast(type[Model], manager.model), v, key_attr=key_attr ) data.pop(key_attr, None) assert not data diff --git a/strawberry_django/optimizer.py b/strawberry_django/optimizer.py index 468438cb..cf3b6d86 100644 --- a/strawberry_django/optimizer.py +++ b/strawberry_django/optimizer.py @@ -10,8 +10,6 @@ TYPE_CHECKING, Any, Callable, - Generator, - Type, TypeVar, cast, ) @@ -75,10 +73,12 @@ ) if TYPE_CHECKING: - from strawberry.types.field import StrawberryField # noqa: I001 + from collections.abc import Generator + + from django.contrib.contenttypes.fields import GenericRelation from strawberry.types.execution import ExecutionContext + from strawberry.types.field import StrawberryField from strawberry.utils.await_maybe import AwaitableOrValue - from django.contrib.contenttypes.fields import GenericRelation __all__ = [ @@ -1111,7 +1111,7 @@ def _get_model_hints_from_connection( e_definition = get_object_definition(relay.Edge, strict=True) e_type = e_definition.resolve_generic( - relay.Edge[cast(Type[relay.Node], n_type)], + relay.Edge[cast(type[relay.Node], n_type)], ) e_gql_definition = _get_gql_definition( schema, @@ -1346,7 +1346,7 @@ def __init__( self.enable_nested_relations_prefetch = enable_nested_relations_prefetch self.prefetch_custom_queryset = prefetch_custom_queryset - def on_execute(self) -> Generator[None, None, None]: + def on_execute(self) -> Generator[None]: token = optimizer.set(self) try: yield diff --git a/strawberry_django/ordering.py b/strawberry_django/ordering.py index 8cd1be02..a520792f 100644 --- a/strawberry_django/ordering.py +++ b/strawberry_django/ordering.py @@ -5,9 +5,7 @@ from typing import ( TYPE_CHECKING, Callable, - Collection, Optional, - Sequence, TypeVar, cast, ) @@ -34,6 +32,8 @@ from .arguments import argument if TYPE_CHECKING: + from collections.abc import Collection, Sequence + from django.db.models import Model from strawberry.types import Info from strawberry.types.arguments import StrawberryArgument @@ -266,7 +266,7 @@ def wrapper(cls): try: cls.__annotations__ # noqa: B018 except AttributeError: - # Manual creation for python 3.8 / 3.9 + # FIXME: Manual creation for python 3.9 (remove when 3.9 is dropped) cls.__annotations__ = {} for fname, type_ in cls.__annotations__.items(): diff --git a/strawberry_django/pagination.py b/strawberry_django/pagination.py index cec44699..ef224db0 100644 --- a/strawberry_django/pagination.py +++ b/strawberry_django/pagination.py @@ -1,5 +1,5 @@ import sys -from typing import TYPE_CHECKING, List, Optional, TypeVar, Union +from typing import TYPE_CHECKING, Optional, TypeVar, Union import strawberry from django.db import DEFAULT_DB_ALIAS @@ -127,7 +127,7 @@ def __copy__(self) -> Self: return new_field @property - def arguments(self) -> List[StrawberryArgument]: + def arguments(self) -> list[StrawberryArgument]: arguments = [] if self.base_resolver is None and self.is_list: pagination = self.get_pagination() @@ -138,7 +138,7 @@ def arguments(self) -> List[StrawberryArgument]: return super().arguments + arguments @arguments.setter - def arguments(self, value: List[StrawberryArgument]): + def arguments(self, value: list[StrawberryArgument]): args_prop = super(StrawberryDjangoPagination, self.__class__).arguments return args_prop.fset(self, value) # type: ignore diff --git a/strawberry_django/permissions.py b/strawberry_django/permissions.py index 1af4e70a..dab1995a 100644 --- a/strawberry_django/permissions.py +++ b/strawberry_django/permissions.py @@ -6,18 +6,13 @@ import enum import functools import inspect +from collections.abc import Hashable, Iterable from typing import ( TYPE_CHECKING, Any, Callable, ClassVar, - Dict, - Hashable, - Iterable, - List, Optional, - Tuple, - Type, TypeVar, Union, cast, @@ -68,8 +63,8 @@ def _get_user_or_anonymous_getter() -> Optional[Callable[[UserType], UserType]]: @dataclasses.dataclass class PermContext: - is_safe_list: List[bool] = dataclasses.field(default_factory=list) - checkers: List["HasPerm"] = dataclasses.field(default_factory=list) + is_safe_list: list[bool] = dataclasses.field(default_factory=list) + checkers: list["HasPerm"] = dataclasses.field(default_factory=list) def __copy__(self): return self.__class__( @@ -145,7 +140,7 @@ def get_with_perms( info: Info, *, required: Literal[True], - model: Type[_M], + model: type[_M], key_attr: Optional[str] = ..., ) -> _M: ... @@ -156,7 +151,7 @@ def get_with_perms( info: Info, *, required: bool = ..., - model: Type[_M], + model: type[_M], key_attr: Optional[str] = ..., ) -> Optional[_M]: ... @@ -167,7 +162,7 @@ def get_with_perms( info: Info, *, required: Literal[True], - model: Type[_M], + model: type[_M], key_attr: Optional[str] = ..., ) -> _M: ... @@ -178,7 +173,7 @@ def get_with_perms( info: Info, *, required: bool = ..., - model: Type[_M], + model: type[_M], key_attr: Optional[str] = ..., ) -> Optional[_M]: ... @@ -259,7 +254,7 @@ class DjangoPermissionExtension(FieldExtension, abc.ABC): """Base django permission extension.""" DEFAULT_ERROR_MESSAGE: ClassVar[str] = "User does not have permission." - SCHEMA_DIRECTIVE_LOCATIONS: ClassVar[List[Location]] = [Location.FIELD_DEFINITION] + SCHEMA_DIRECTIVE_LOCATIONS: ClassVar[list[Location]] = [Location.FIELD_DEFINITION] SCHEMA_DIRECTIVE_DESCRIPTION: ClassVar[Optional[str]] = None def __init__( @@ -306,7 +301,7 @@ def resolve( next_: SyncExtensionResolver, source: Any, info: Info, - **kwargs: Dict[str, Any], + **kwargs: dict[str, Any], ) -> Any: user = get_current_user(info) @@ -336,7 +331,7 @@ async def resolve_async( next_: AsyncExtensionResolver, source: Any, info: Info, - **kwargs: Dict[str, Any], + **kwargs: dict[str, Any], ) -> Any: user = await aget_current_user(info) @@ -641,7 +636,7 @@ class HasPerm(DjangoPermissionExtension): def __init__( self, - perms: Union[List[str], str], + perms: Union[list[str], str], *, message: Optional[str] = None, use_directives: bool = True, @@ -669,7 +664,7 @@ def __init__( if not perms: raise TypeError(f"At least one perm is required for {self!r}") - self.perms: Tuple[PermDefinition, ...] = tuple( + self.perms: tuple[PermDefinition, ...] = tuple( PermDefinition.from_perm(p) if isinstance(p, str) else p for p in perms ) @@ -702,7 +697,7 @@ def schema_directive(self) -> object: repeatable=True, ) class AutoDirective: - permissions: List[PermDefinition] = strawberry.field( + permissions: list[PermDefinition] = strawberry.field( description="Required perms to access this resource.", default_factory=list, ) @@ -778,7 +773,7 @@ def _get_cache( self, info: Info, user: UserType, - ) -> Dict[Tuple[Hashable, ...], bool]: + ) -> dict[tuple[Hashable, ...], bool]: cache_key = "_strawberry_django_permissions_cache" cache = getattr(user, cache_key, None) diff --git a/strawberry_django/relay.py b/strawberry_django/relay.py index 45d19ac9..b8db964d 100644 --- a/strawberry_django/relay.py +++ b/strawberry_django/relay.py @@ -1,12 +1,9 @@ import inspect import warnings +from collections.abc import Iterable, Sized from typing import ( Any, - Iterable, - List, Optional, - Sized, - Type, TypeVar, Union, cast, @@ -58,7 +55,7 @@ def total_count(self) -> Optional[int]: if isinstance(self.nodes, models.QuerySet) and is_optimized_by_prefetching( self.nodes ): - result = cast(List[relay.NodeType], self.nodes._result_cache) # type: ignore + result = cast(list[relay.NodeType], self.nodes._result_cache) # type: ignore try: return ( result[0]._strawberry_total_count # type: ignore @@ -180,7 +177,7 @@ def resolve_connection_from_cache( edge_class = cast(relay.Edge[relay.NodeType], field) - edges: List[relay.Edge] = [ + edges: list[relay.Edge] = [ edge_class.resolve_edge( cls.resolve_node(node, info=info, **kwargs), cursor=node._strawberry_row_number - 1, @@ -208,9 +205,9 @@ def resolve_connection_from_cache( @overload def resolve_model_nodes( source: Union[ - Type[WithStrawberryDjangoObjectDefinition], - Type[relay.Node], - Type[_M], + type[WithStrawberryDjangoObjectDefinition], + type[relay.Node], + type[_M], ], *, info: Optional[Info] = None, @@ -223,9 +220,9 @@ def resolve_model_nodes( @overload def resolve_model_nodes( source: Union[ - Type[WithStrawberryDjangoObjectDefinition], - Type[relay.Node], - Type[_M], + type[WithStrawberryDjangoObjectDefinition], + type[relay.Node], + type[_M], ], *, info: Optional[Info] = None, @@ -238,9 +235,9 @@ def resolve_model_nodes( @overload def resolve_model_nodes( source: Union[ - Type[WithStrawberryDjangoObjectDefinition], - Type[relay.Node], - Type[_M], + type[WithStrawberryDjangoObjectDefinition], + type[relay.Node], + type[_M], ], *, info: Optional[Info] = None, @@ -253,9 +250,9 @@ def resolve_model_nodes( @overload def resolve_model_nodes( source: Union[ - Type[WithStrawberryDjangoObjectDefinition], - Type[relay.Node], - Type[_M], + type[WithStrawberryDjangoObjectDefinition], + type[relay.Node], + type[_M], ], *, info: Optional[Info] = None, @@ -268,9 +265,9 @@ def resolve_model_nodes( @overload def resolve_model_nodes( source: Union[ - Type[WithStrawberryDjangoObjectDefinition], - Type[relay.Node], - Type[_M], + type[WithStrawberryDjangoObjectDefinition], + type[relay.Node], + type[_M], ], *, info: Optional[Info] = None, @@ -333,7 +330,7 @@ def resolve_model_nodes( else: origin = source django_type = get_django_definition(source, strict=True) - source = cast(Type[_M], django_type.model) + source = cast(type[_M], django_type.model) qs = cast(models.QuerySet[_M], source._default_manager.all()) qs = run_type_get_queryset(qs, origin, info) @@ -371,9 +368,9 @@ def resolve_model_nodes( if not node_ids: return retval - def map_results(results: models.QuerySet[_M]) -> List[_M]: + def map_results(results: models.QuerySet[_M]) -> list[_M]: results_map = {str(getattr(obj, id_attr)): obj for obj in results} - retval: List[Optional[_M]] = [] + retval: list[Optional[_M]] = [] for node_id in node_ids: if required: retval.append(results_map[str(node_id)]) @@ -395,9 +392,9 @@ async def async_resolver(): @overload def resolve_model_node( source: Union[ - Type[WithStrawberryDjangoObjectDefinition], - Type[relay.Node], - Type[_M], + type[WithStrawberryDjangoObjectDefinition], + type[relay.Node], + type[_M], ], node_id: Union[str, relay.GlobalID], *, @@ -410,9 +407,9 @@ def resolve_model_node( @overload def resolve_model_node( source: Union[ - Type[WithStrawberryDjangoObjectDefinition], - Type[relay.Node], - Type[_M], + type[WithStrawberryDjangoObjectDefinition], + type[relay.Node], + type[_M], ], node_id: Union[str, relay.GlobalID], *, @@ -460,7 +457,7 @@ def resolve_model_node( else: origin = source django_type = get_django_definition(source, strict=True) - source = cast(Type[models.Model], django_type.model) + source = cast(type[models.Model], django_type.model) if isinstance(node_id, relay.GlobalID): node_id = node_id.node_id @@ -483,7 +480,7 @@ def resolve_model_node( return django_resolver(lambda: qs.get() if required else qs.first())() -def resolve_model_id_attr(source: Type) -> str: +def resolve_model_id_attr(source: type) -> str: """Resolve the model id, ensuring it is retrieved in a sync context. Args: @@ -506,9 +503,9 @@ def resolve_model_id_attr(source: Type) -> str: def resolve_model_id( source: Union[ - Type[WithStrawberryDjangoObjectDefinition], - Type[relay.Node], - Type[_M], + type[WithStrawberryDjangoObjectDefinition], + type[relay.Node], + type[_M], ], root: models.Model, *, diff --git a/strawberry_django/test/client.py b/strawberry_django/test/client.py index cfe889c0..5bd40dfc 100644 --- a/strawberry_django/test/client.py +++ b/strawberry_django/test/client.py @@ -1,6 +1,7 @@ import contextlib import warnings -from typing import Any, Awaitable, Dict, Optional, cast +from collections.abc import Awaitable +from typing import Any, Optional, cast from asgiref.sync import sync_to_async from django.contrib.auth.base_user import AbstractBaseUser @@ -21,11 +22,11 @@ def client(self) -> Client: def request( self, - body: Dict[str, object], - headers: Optional[Dict[str, object]] = None, - files: Optional[Dict[str, object]] = None, + body: dict[str, object], + headers: Optional[dict[str, object]] = None, + files: Optional[dict[str, object]] = None, ): - kwargs: Dict[str, object] = {"data": body, "headers": headers} + kwargs: dict[str, object] = {"data": body, "headers": headers} if files: kwargs["format"] = "multipart" else: @@ -55,10 +56,10 @@ def client(self) -> AsyncClient: async def query( self, query: str, - variables: Optional[Dict[str, Any]] = None, - headers: Optional[Dict[str, object]] = None, + variables: Optional[dict[str, Any]] = None, + headers: Optional[dict[str, object]] = None, asserts_errors: Optional[bool] = None, - files: Optional[Dict[str, object]] = None, + files: Optional[dict[str, object]] = None, assert_no_errors: Optional[bool] = True, ) -> Response: body = self._build_body(query, variables, files) diff --git a/strawberry_django/type.py b/strawberry_django/type.py index 66a0ed81..3ca5c2a4 100644 --- a/strawberry_django/type.py +++ b/strawberry_django/type.py @@ -1,17 +1,15 @@ +import builtins import copy import dataclasses import functools import inspect import sys import types +from collections.abc import Collection, Sequence from typing import ( Callable, - Collection, Generic, - List, Optional, - Sequence, - Type, TypeVar, Union, cast, @@ -66,15 +64,15 @@ ] _T = TypeVar("_T", bound=type) -_O = TypeVar("_O", bound=Type[WithStrawberryObjectDefinition]) +_O = TypeVar("_O", bound=type[WithStrawberryObjectDefinition]) _M = TypeVar("_M", bound=Model) def _process_type( cls: _T, - model: Type[Model], + model: type[Model], *, - field_cls: Type[StrawberryDjangoField] = StrawberryDjangoField, + field_cls: type[StrawberryDjangoField] = StrawberryDjangoField, filters: Optional[type] = None, order: Optional[type] = None, pagination: bool = False, @@ -85,8 +83,8 @@ def _process_type( prefetch_related: Optional[TypeOrSequence[PrefetchType]] = None, annotate: Optional[TypeOrMapping[AnnotateType]] = None, disable_optimization: bool = False, - fields: Optional[Union[List[str], Literal["__all__"]]] = None, - exclude: Optional[List[str]] = None, + fields: Optional[Union[list[str], Literal["__all__"]]] = None, + exclude: Optional[list[str]] = None, **kwargs, ) -> _T: is_input = kwargs.get("is_input", False) @@ -127,7 +125,7 @@ def _process_type( ) django_type = StrawberryDjangoDefinition( - origin=cast(Type[WithStrawberryObjectDefinition], cls), + origin=cast(builtins.type[WithStrawberryObjectDefinition], cls), model=model, field_cls=field_cls, is_partial=partial, @@ -228,7 +226,7 @@ def _process_type( # update annotations and fields type_def = get_object_definition(cls, strict=True) description_from_doc = settings["FIELD_DESCRIPTION_FROM_HELP_TEXT"] - new_fields: List[StrawberryField] = [] + new_fields: list[StrawberryField] = [] for f in type_def.fields: django_name: Optional[str] = ( getattr(f, "django_name", None) or f.python_name or f.name @@ -403,7 +401,7 @@ def _process_type( @dataclasses.dataclass class StrawberryDjangoDefinition(Generic[_O, _M]): origin: _O - model: Type[_M] + model: type[_M] store: OptimizerStore is_input: bool = False is_partial: bool = False @@ -411,7 +409,7 @@ class StrawberryDjangoDefinition(Generic[_O, _M]): filters: Optional[type] = None order: Optional[type] = None pagination: bool = False - field_cls: Type[StrawberryDjangoField] = StrawberryDjangoField + field_cls: type[StrawberryDjangoField] = StrawberryDjangoField disable_optimization: bool = False @@ -423,10 +421,10 @@ class StrawberryDjangoDefinition(Generic[_O, _M]): ), ) def type( # noqa: A001 - model: Type[Model], + model: type[Model], *, name: Optional[str] = None, - field_cls: Type[StrawberryDjangoField] = StrawberryDjangoField, + field_cls: type[StrawberryDjangoField] = StrawberryDjangoField, is_input: bool = False, is_interface: bool = False, is_filter: Union[Literal["lookups"], bool] = False, @@ -441,8 +439,8 @@ def type( # noqa: A001 prefetch_related: Optional[TypeOrSequence[PrefetchType]] = None, annotate: Optional[TypeOrMapping[AnnotateType]] = None, disable_optimization: bool = False, - fields: Optional[Union[List[str], Literal["__all__"]]] = None, - exclude: Optional[List[str]] = None, + fields: Optional[Union[list[str], Literal["__all__"]]] = None, + exclude: Optional[list[str]] = None, ) -> Callable[[_T], _T]: """Annotates a class as a Django GraphQL type. @@ -492,10 +490,10 @@ def wrapper(cls: _T) -> _T: ), ) def interface( - model: Type[Model], + model: builtins.type[Model], *, name: Optional[str] = None, - field_cls: Type[StrawberryDjangoField] = StrawberryDjangoField, + field_cls: builtins.type[StrawberryDjangoField] = StrawberryDjangoField, description: Optional[str] = None, directives: Optional[Sequence[object]] = (), disable_optimization: bool = False, @@ -536,16 +534,16 @@ def wrapper(cls: _T) -> _T: ), ) def input( # noqa: A001 - model: Type[Model], + model: builtins.type[Model], *, name: Optional[str] = None, - field_cls: Type[StrawberryDjangoField] = StrawberryDjangoField, + field_cls: builtins.type[StrawberryDjangoField] = StrawberryDjangoField, description: Optional[str] = None, directives: Optional[Sequence[object]] = (), is_filter: Union[Literal["lookups"], bool] = False, partial: bool = False, - fields: Optional[Union[List[str], Literal["__all__"]]] = None, - exclude: Optional[List[str]] = None, + fields: Optional[Union[list[str], Literal["__all__"]]] = None, + exclude: Optional[list[str]] = None, ) -> Callable[[_T], _T]: """Annotates a class as a Django GraphQL input. @@ -586,14 +584,14 @@ def wrapper(cls: _T) -> _T: ), ) def partial( - model: Type[Model], + model: builtins.type[Model], *, name: Optional[str] = None, - field_cls: Type[StrawberryDjangoField] = StrawberryDjangoField, + field_cls: builtins.type[StrawberryDjangoField] = StrawberryDjangoField, description: Optional[str] = None, directives: Optional[Sequence[object]] = (), - fields: Optional[Union[List[str], Literal["__all__"]]] = None, - exclude: Optional[List[str]] = None, + fields: Optional[Union[list[str], Literal["__all__"]]] = None, + exclude: Optional[list[str]] = None, ) -> Callable[[_T], _T]: """Annotates a class as a Django GraphQL partial. diff --git a/strawberry_django/utils/inspect.py b/strawberry_django/utils/inspect.py index ca08257a..60a1cc7c 100644 --- a/strawberry_django/utils/inspect.py +++ b/strawberry_django/utils/inspect.py @@ -5,8 +5,6 @@ import itertools from typing import ( TYPE_CHECKING, - Generator, - Iterable, cast, ) @@ -29,6 +27,8 @@ from .pyutils import DictTree, dicttree_insersection_differs, dicttree_merge if TYPE_CHECKING: + from collections.abc import Generator, Iterable + from django.db import models from django.db.models.expressions import Expression from django.db.models.fields import Field @@ -78,7 +78,7 @@ def get_possible_types( gql_type: StrawberryObjectDefinition | StrawberryType | type, *, object_definition: StrawberryObjectDefinition | None = None, -) -> Generator[type, None, None]: +) -> Generator[type]: """Resolve all possible types for gql_type. Args: @@ -119,7 +119,7 @@ def get_possible_types( def get_possible_type_definitions( gql_type: StrawberryObjectDefinition | StrawberryType | type, -) -> Generator[StrawberryObjectDefinition, None, None]: +) -> Generator[StrawberryObjectDefinition]: """Resolve all possible type definitions for gql_type. Args: diff --git a/strawberry_django/utils/pyutils.py b/strawberry_django/utils/pyutils.py index 206080f5..55f0a5b7 100644 --- a/strawberry_django/utils/pyutils.py +++ b/strawberry_django/utils/pyutils.py @@ -1,14 +1,15 @@ -from typing import Any, Dict, Mapping, TypeVar +from collections.abc import Mapping +from typing import Any, TypeVar from typing_extensions import TypeAlias _K = TypeVar("_K", bound=Any) _V = TypeVar("_V", bound=Any) -DictTree: TypeAlias = Dict[str, "DictTree"] +DictTree: TypeAlias = dict[str, "DictTree"] -def dicttree_merge(dict1: Mapping[_K, _V], dict2: Mapping[_K, _V]) -> Dict[_K, _V]: +def dicttree_merge(dict1: Mapping[_K, _V], dict2: Mapping[_K, _V]) -> dict[_K, _V]: new = { **dict1, **dict2, diff --git a/strawberry_django/utils/query.py b/strawberry_django/utils/query.py index d92bb5da..a26f3a80 100644 --- a/strawberry_django/utils/query.py +++ b/strawberry_django/utils/query.py @@ -1,5 +1,5 @@ import functools -from typing import TYPE_CHECKING, List, Optional, Set, Type, TypeVar, cast +from typing import TYPE_CHECKING, Optional, TypeVar, cast from django.core.exceptions import FieldDoesNotExist from django.db.models import Exists, F, Model, Q, QuerySet @@ -21,10 +21,10 @@ def _filter( qs: _Q, - perms: List[str], + perms: list[str], *, lookup: str = "", - model: Type[Model], + model: type[Model], any_perm: bool = True, ctype: Optional["ContentType"] = None, ) -> _Q: @@ -80,7 +80,7 @@ def filter_for_user_q( if isinstance(perms, str): perms = [perms] - model = cast(Type[Model], qs.model) + model = cast(type[Model], qs.model) if model._meta.concrete_model: model = model._meta.concrete_model @@ -125,7 +125,7 @@ def filter_for_user_q( raise ValueError(f"Cannot mix app_labels ({app_labels!r})") # Small optimization if the user's permissions are cached - perm_cache: Optional[Set[str]] = getattr(user, "_perm_cache", None) + perm_cache: Optional[set[str]] = getattr(user, "_perm_cache", None) if perm_cache is not None: f = any if any_perm else all if f(p in perm_cache for p in perms_list): diff --git a/strawberry_django/utils/typing.py b/strawberry_django/utils/typing.py index 949f6f79..2f0a55a9 100644 --- a/strawberry_django/utils/typing.py +++ b/strawberry_django/utils/typing.py @@ -2,14 +2,12 @@ import dataclasses import sys +from collections.abc import Iterable, Mapping, Sequence from typing import ( TYPE_CHECKING, Any, Callable, ClassVar, - Iterable, - Mapping, - Sequence, TypeVar, Union, cast, diff --git a/tests/conftest.py b/tests/conftest.py index 2dda31ab..676bd5db 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,7 @@ import contextlib import pathlib import shutil -from typing import Dict, List, Tuple, Type, Union, cast +from typing import Union, cast import pytest import strawberry @@ -32,7 +32,7 @@ def cleanup_function(): @pytest.fixture(params=["sync", "async", "sync_no_optimizer", "async_no_optimizer"]) def gql_client(request): client, path, with_optimizer = cast( - Dict[str, Tuple[Union[Type[Client], Type[AsyncClient]], str, bool]], + dict[str, tuple[Union[type[Client], type[AsyncClient]], str, bool]], { "sync": (Client, "/graphql/", True), "async": (AsyncClient, "/graphql_async/", True), @@ -166,11 +166,11 @@ def schema(request): @strawberry.type class Query: user: types.User = strawberry_django.field() - users: List[types.User] = strawberry_django.field() + users: list[types.User] = strawberry_django.field() group: types.Group = strawberry_django.field() - groups: List[types.Group] = strawberry_django.field() + groups: list[types.Group] = strawberry_django.field() tag: types.Tag = strawberry_django.field() - tags: List[types.Tag] = strawberry_django.field() + tags: list[types.Tag] = strawberry_django.field() if request.param == "optimizer_enabled": extensions = [DjangoOptimizerExtension()] @@ -183,7 +183,7 @@ class Query: @strawberry.type class GeoQuery(Query): - geofields: List[types.GeoField] = strawberry_django.field() + geofields: list[types.GeoField] = strawberry_django.field() return strawberry.Schema(query=GeoQuery, extensions=extensions) diff --git a/tests/fields/test_attributes.py b/tests/fields/test_attributes.py index db9d1fc0..8309770c 100644 --- a/tests/fields/test_attributes.py +++ b/tests/fields/test_attributes.py @@ -1,5 +1,5 @@ import textwrap -from typing import List, cast +from typing import cast import strawberry from django.db import models @@ -80,7 +80,7 @@ class MyType: @strawberry.type class Query: - my_type: List[MyType] = strawberry_django.field(filters=MyTypeFilter) + my_type: list[MyType] = strawberry_django.field(filters=MyTypeFilter) schema = strawberry.Schema(query=Query) expected = """\ @@ -119,7 +119,7 @@ class MyType(relay.Node): @strawberry.type class Query: - my_type: List[MyType] = strawberry_django.field(filters=MyTypeFilter) + my_type: list[MyType] = strawberry_django.field(filters=MyTypeFilter) schema = strawberry.Schema(query=Query) expected = f'''\ @@ -176,7 +176,7 @@ class MyType(relay.Node): @strawberry.type class Query: - my_type: List[MyType] = strawberry_django.field(filters=MyTypeFilter) + my_type: list[MyType] = strawberry_django.field(filters=MyTypeFilter) schema = strawberry.Schema(query=Query) expected = f'''\ diff --git a/tests/fields/test_get_result.py b/tests/fields/test_get_result.py index caf9a2a4..ef4e580c 100644 --- a/tests/fields/test_get_result.py +++ b/tests/fields/test_get_result.py @@ -1,5 +1,3 @@ -from typing import List - import pytest from django.db.models import QuerySet from strawberry import relay @@ -12,7 +10,7 @@ @pytest.mark.django_db def test_resolve_returns_queryset_with_fetched_results(): - field = StrawberryDjangoField(type_annotation=StrawberryAnnotation(List[FruitType])) + field = StrawberryDjangoField(type_annotation=StrawberryAnnotation(list[FruitType])) result = field.get_result(None, None, [], {}) assert isinstance(result, QuerySet) assert result._result_cache is not None # type: ignore @@ -20,7 +18,7 @@ def test_resolve_returns_queryset_with_fetched_results(): @pytest.mark.django_db async def test_resolve_returns_queryset_with_fetched_results_async(): - field = StrawberryDjangoField(type_annotation=StrawberryAnnotation(List[FruitType])) + field = StrawberryDjangoField(type_annotation=StrawberryAnnotation(list[FruitType])) result = await field.get_result(None, None, [], {}) assert isinstance(result, QuerySet) assert result._result_cache is not None # type: ignore @@ -28,7 +26,7 @@ async def test_resolve_returns_queryset_with_fetched_results_async(): @pytest.mark.django_db def test_resolve_returns_queryset_without_fetching_results_when_disabling_it(): - field = StrawberryDjangoField(type_annotation=StrawberryAnnotation(List[FruitType])) + field = StrawberryDjangoField(type_annotation=StrawberryAnnotation(list[FruitType])) field.disable_fetch_list_results = True result = field.get_result(None, None, [], {}) assert isinstance(result, QuerySet) @@ -37,7 +35,7 @@ def test_resolve_returns_queryset_without_fetching_results_when_disabling_it(): @pytest.mark.django_db async def test_resolve_returns_queryset_without_fetching_results_when_disabling_it_async(): - field = StrawberryDjangoField(type_annotation=StrawberryAnnotation(List[FruitType])) + field = StrawberryDjangoField(type_annotation=StrawberryAnnotation(list[FruitType])) field.disable_fetch_list_results = True result = await field.get_result(None, None, [], {}) assert isinstance(result, QuerySet) diff --git a/tests/fields/test_relations.py b/tests/fields/test_relations.py index 827bfe6d..cd95f314 100644 --- a/tests/fields/test_relations.py +++ b/tests/fields/test_relations.py @@ -1,4 +1,4 @@ -from typing import List, Optional, cast +from typing import Optional, cast import strawberry from django.db import models @@ -37,7 +37,7 @@ class ChildModel(models.Model): class Parent: id: auto name: auto - children: List["Child"] + children: list["Child"] one_to_one: Optional["OneToOne"] @@ -52,7 +52,7 @@ class OneToOne: class Child: id: auto name: auto - parents: List[Parent] + parents: list[Parent] def test_relation(): diff --git a/tests/fields/test_types.py b/tests/fields/test_types.py index d4f25b85..d6a78db8 100644 --- a/tests/fields/test_types.py +++ b/tests/fields/test_types.py @@ -2,7 +2,7 @@ import decimal import enum import uuid -from typing import Any, Dict, List, Optional, Tuple, Union, cast +from typing import Any, Optional, Union, cast import django import pytest @@ -333,7 +333,7 @@ class Input: related_one_to_one: auto related_many_to_many: auto - expected_fields: Dict[str, Tuple[Union[type, StrawberryContainer], bool]] = { + expected_fields: dict[str, tuple[Union[type, StrawberryContainer], bool]] = { "foreign_key": ( strawberry_django.OneToManyInput, True, @@ -412,7 +412,7 @@ class Base: @strawberry_django.type(FieldTypesModel) class Type(Base): # type: ignore - many_to_many: List["Type"] + many_to_many: list["Type"] object_definition = get_object_definition(Type, strict=True) assert [(f.name, f.type) for f in object_definition.fields] == [ @@ -429,7 +429,7 @@ def test_inherit_input(): class Type: # type: ignore char: auto one_to_one: "Type" - many_to_many: List["Type"] + many_to_many: list["Type"] @strawberry_django.input(FieldTypesModel) class Input(Type): diff --git a/tests/filters/test_filters.py b/tests/filters/test_filters.py index 714077fe..cf441a6d 100644 --- a/tests/filters/test_filters.py +++ b/tests/filters/test_filters.py @@ -1,6 +1,6 @@ import textwrap from enum import Enum -from typing import Generic, List, Optional, TypeVar, cast +from typing import Generic, Optional, TypeVar, cast import pytest import strawberry @@ -49,7 +49,7 @@ class EnumFilter: @strawberry.input class FilterInLookup(Generic[_T]): exact: Optional[_T] = strawberry.UNSET - in_list: Optional[List[_T]] = strawberry.UNSET + in_list: Optional[list[_T]] = strawberry.UNSET @strawberry_django.filters.filter(models.Fruit) class EnumLookupFilter: @@ -93,11 +93,11 @@ class Fruit: @strawberry.type class Query: - fruits: List[Fruit] = strawberry_django.field() - field_filter: List[Fruit] = strawberry_django.field(filters=FieldFilter) - type_filter: List[Fruit] = strawberry_django.field(filters=TypeFilter) - enum_filter: List[Fruit] = strawberry_django.field(filters=EnumFilter) - enum_lookup_filter: List[Fruit] = strawberry_django.field( + fruits: list[Fruit] = strawberry_django.field() + field_filter: list[Fruit] = strawberry_django.field(filters=FieldFilter) + type_filter: list[Fruit] = strawberry_django.field(filters=TypeFilter) + enum_filter: list[Fruit] = strawberry_django.field(filters=EnumFilter) + enum_lookup_filter: list[Fruit] = strawberry_django.field( filters=EnumLookupFilter ) @@ -242,9 +242,9 @@ def test_resolver_filter(fruits): @strawberry.type class Query: @strawberry.field - def fruits(self, filters: FruitFilter) -> List[Fruit]: + def fruits(self, filters: FruitFilter) -> list[Fruit]: queryset = models.Fruit.objects.all() - return cast(List[Fruit], strawberry_django.filters.apply(filters, queryset)) + return cast(list[Fruit], strawberry_django.filters.apply(filters, queryset)) query = utils.generate_query(Query) result = query('{ fruits(filters: { name: { exact: "strawberry" } }) { id name } }') @@ -260,9 +260,9 @@ def test_empty_resolver_filter(): @strawberry.type class Query: @strawberry.field - def fruits(self, filters: FruitFilter) -> List[Fruit]: + def fruits(self, filters: FruitFilter) -> list[Fruit]: queryset = models.Fruit.objects.none() - return cast(List[Fruit], strawberry_django.filters.apply(filters, queryset)) + return cast(list[Fruit], strawberry_django.filters.apply(filters, queryset)) query = utils.generate_query(Query) result = query('{ fruits(filters: { name: { exact: "strawberry" } }) { id name } }') @@ -278,11 +278,11 @@ async def test_async_resolver_filter(fruits): @strawberry.type class Query: @strawberry.field - async def fruits(self, filters: FruitFilter) -> List[Fruit]: + async def fruits(self, filters: FruitFilter) -> list[Fruit]: queryset = models.Fruit.objects.all() queryset = strawberry_django.filters.apply(filters, queryset) # cast fixes funny typing issue between list and List - return cast(List[Fruit], [fruit async for fruit in queryset]) + return cast(list[Fruit], [fruit async for fruit in queryset]) query = utils.generate_query(Query) result = await query( # type: ignore @@ -299,10 +299,10 @@ def test_resolver_filter_with_inheritance(vegetables): @strawberry.type class Query: @strawberry.field - def vegetables(self, filters: VegetableFilter) -> List[Vegetable]: + def vegetables(self, filters: VegetableFilter) -> list[Vegetable]: queryset = models.Vegetable.objects.all() return cast( - List[Vegetable], strawberry_django.filters.apply(filters, queryset) + list[Vegetable], strawberry_django.filters.apply(filters, queryset) ) query = utils.generate_query(Query) @@ -352,10 +352,10 @@ def filter_custom_field(self, queryset, info: Info): @strawberry.type class Query: @strawberry.field - def fruits(self, filters: FruitFilterWithInfo, info: Info) -> List[Fruit]: + def fruits(self, filters: FruitFilterWithInfo, info: Info) -> list[Fruit]: queryset = models.Fruit.objects.all() return cast( - List[Fruit], + list[Fruit], strawberry_django.filters.apply(filters, queryset, info=info), ) @@ -384,10 +384,10 @@ def filter(self, queryset, info: Info): @strawberry.type class Query: @strawberry.field - def fruits(self, filters: FruitFilterWithInfo, info: Info) -> List[Fruit]: + def fruits(self, filters: FruitFilterWithInfo, info: Info) -> list[Fruit]: queryset = models.Fruit.objects.all() return cast( - List[Fruit], + list[Fruit], strawberry_django.filters.apply(filters, queryset, info=info), ) @@ -405,9 +405,9 @@ def test_resolver_nonfilter(fruits): @strawberry.type class Query: @strawberry.field - def fruits(self, filters: NonFilter) -> List[Fruit]: + def fruits(self, filters: NonFilter) -> list[Fruit]: queryset = models.Fruit.objects.all() - return cast(List[Fruit], strawberry_django.filters.apply(filters, queryset)) + return cast(list[Fruit], strawberry_django.filters.apply(filters, queryset)) query = utils.generate_query(Query) result = query("{ fruits(filters: { name: strawberry } ) { id name } }") diff --git a/tests/filters/test_filters_v2.py b/tests/filters/test_filters_v2.py index 7f8ea78a..71514908 100644 --- a/tests/filters/test_filters_v2.py +++ b/tests/filters/test_filters_v2.py @@ -1,6 +1,6 @@ # ruff: noqa: TRY002, B904, BLE001, F811, PT012, A001, PLC2701 from enum import Enum -from typing import Any, List, Optional, cast +from typing import Any, Optional, cast import pytest import strawberry @@ -101,8 +101,8 @@ def filter(self, info, queryset: QuerySet, prefix): @strawberry.type class Query: - types: List[FruitType] = strawberry_django.field(filters=FruitTypeFilter) - fruits: List[Fruit] = strawberry_django.field(filters=FruitFilter) + types: list[FruitType] = strawberry_django.field(filters=FruitTypeFilter) + fruits: list[Fruit] = strawberry_django.field(filters=FruitFilter) @pytest.fixture @@ -424,11 +424,11 @@ def test_empty_resolver_filter(): @strawberry.type class Query: @strawberry.field - def fruits(self, filters: FruitFilter) -> List[Fruit]: + def fruits(self, filters: FruitFilter) -> list[Fruit]: queryset = models.Fruit.objects.none() _info: Any = object() return cast( - List[Fruit], strawberry_django.filters.apply(filters, queryset, _info) + list[Fruit], strawberry_django.filters.apply(filters, queryset, _info) ) query = utils.generate_query(Query) @@ -445,12 +445,12 @@ async def test_async_resolver_filter(fruits): @strawberry.type class Query: @strawberry.field - async def fruits(self, filters: FruitFilter) -> List[Fruit]: + async def fruits(self, filters: FruitFilter) -> list[Fruit]: queryset = models.Fruit.objects.all() _info: Any = object() queryset = strawberry_django.filters.apply(filters, queryset, _info) # cast fixes funny typing issue between list and List - return cast(List[Fruit], [fruit async for fruit in queryset]) + return cast(list[Fruit], [fruit async for fruit in queryset]) query = utils.generate_query(Query) result = await query( # type: ignore diff --git a/tests/mutations/conftest.py b/tests/mutations/conftest.py index 398b26d6..16f1f437 100644 --- a/tests/mutations/conftest.py +++ b/tests/mutations/conftest.py @@ -1,4 +1,4 @@ -from typing import List, cast +from typing import cast import pytest import strawberry @@ -35,8 +35,8 @@ class FruitFilter: @strawberry.type class Mutation: create_fruit: Fruit = mutations.create(FruitInput) - create_fruits: List[Fruit] = mutations.create(FruitInput) - update_fruits: List[Fruit] = mutations.update( + create_fruits: list[Fruit] = mutations.create(FruitInput) + update_fruits: list[Fruit] = mutations.update( FruitPartialInput, filters=FruitFilter, key_attr="id" ) create_tomato_with_required_picture: TomatoWithRequiredPictureType = ( @@ -70,17 +70,17 @@ def delete_lazy_fruit(self, info) -> Fruit: ), ) - delete_fruits: List[Fruit] = mutations.delete(filters=FruitFilter) + delete_fruits: list[Fruit] = mutations.delete(filters=FruitFilter) create_color: Color = mutations.create(ColorInput) - create_colors: List[Color] = mutations.create(ColorInput) - update_colors: List[Color] = mutations.update(ColorPartialInput) - delete_colors: List[Color] = mutations.delete() + create_colors: list[Color] = mutations.create(ColorInput) + update_colors: list[Color] = mutations.update(ColorPartialInput) + delete_colors: list[Color] = mutations.delete() create_fruit_type: FruitType = mutations.create(FruitTypeInput) - create_fruit_types: List[FruitType] = mutations.create(FruitTypeInput) - update_fruit_types: List[FruitType] = mutations.update(FruitTypePartialInput) - delete_fruit_types: List[FruitType] = mutations.delete() + create_fruit_types: list[FruitType] = mutations.create(FruitTypeInput) + update_fruit_types: list[FruitType] = mutations.update(FruitTypePartialInput) + delete_fruit_types: list[FruitType] = mutations.delete() @pytest.fixture @@ -91,7 +91,7 @@ def mutation(db): @strawberry.type class GeoMutation(Mutation): create_geo_field: GeoField = mutations.create(GeoFieldInput) - update_geo_fields: List[GeoField] = mutations.update(GeoFieldPartialInput) + update_geo_fields: list[GeoField] = mutations.update(GeoFieldPartialInput) mutation = GeoMutation diff --git a/tests/mutations/test_permission_classes.py b/tests/mutations/test_permission_classes.py index 873cfe99..c1a03d1d 100644 --- a/tests/mutations/test_permission_classes.py +++ b/tests/mutations/test_permission_classes.py @@ -1,5 +1,3 @@ -from typing import List - import pytest import strawberry from strawberry.permission import BasePermission @@ -18,15 +16,15 @@ def has_permission(self, source, info, **kwargs): @strawberry.type class Mutation: - create_fruits: List[Fruit] = mutations.create( + create_fruits: list[Fruit] = mutations.create( FruitInput, permission_classes=[PermissionClass], ) - update_fruits: List[Fruit] = mutations.update( + update_fruits: list[Fruit] = mutations.update( FruitPartialInput, permission_classes=[PermissionClass], ) - delete_fruits: List[Fruit] = mutations.delete(permission_classes=[PermissionClass]) + delete_fruits: list[Fruit] = mutations.delete(permission_classes=[PermissionClass]) @pytest.fixture diff --git a/tests/polymorphism/schema.py b/tests/polymorphism/schema.py index 054a0cbd..43cab9eb 100644 --- a/tests/polymorphism/schema.py +++ b/tests/polymorphism/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -25,7 +23,7 @@ class ResearchProjectType(ProjectType): @strawberry.type class Query: - projects: List[ProjectType] = strawberry_django.field() + projects: list[ProjectType] = strawberry_django.field() schema = strawberry.Schema( diff --git a/tests/projects/faker.py b/tests/projects/faker.py index a4c1ef9c..271d608a 100644 --- a/tests/projects/faker.py +++ b/tests/projects/faker.py @@ -1,4 +1,4 @@ -from typing import Any, ClassVar, Generic, List, Type, TypeVar, cast +from typing import Any, ClassVar, Generic, TypeVar, cast import factory from django.contrib.auth import get_user_model @@ -8,7 +8,7 @@ from .models import Favorite, Issue, Milestone, Project, Tag _T = TypeVar("_T") -User = cast(Type[AbstractUser], get_user_model()) +User = cast(type[AbstractUser], get_user_model()) class _BaseFactory(factory.django.DjangoModelFactory, Generic[_T]): @@ -19,7 +19,7 @@ def create(cls, **kwargs) -> _T: return super().create(**kwargs) @classmethod - def create_batch(cls, size: int, **kwargs) -> List[_T]: + def create_batch(cls, size: int, **kwargs) -> list[_T]: return super().create_batch(size, **kwargs) diff --git a/tests/projects/schema.py b/tests/projects/schema.py index 83097832..bedd5934 100644 --- a/tests/projects/schema.py +++ b/tests/projects/schema.py @@ -1,7 +1,8 @@ import asyncio import datetime import decimal -from typing import Iterable, List, Optional, Type, cast +from collections.abc import Iterable +from typing import Annotated, Optional, cast import strawberry from django.contrib.auth import get_user_model @@ -21,7 +22,6 @@ from django.db.models.query import QuerySet from strawberry import UNSET, relay from strawberry.types.info import Info -from typing_extensions import Annotated import strawberry_django from strawberry_django import mutations @@ -51,7 +51,7 @@ Tag, ) -UserModel = cast(Type[AbstractUser], get_user_model()) +UserModel = cast(type[AbstractUser], get_user_model()) @strawberry_django.interface(NamedModel) @@ -99,7 +99,7 @@ class ProjectFilter: @strawberry_django.type(Project, filters=ProjectFilter, pagination=True) class ProjectType(relay.Node, Named): due_date: strawberry.auto - milestones: List["MilestoneType"] = strawberry_django.field(pagination=True) + milestones: list["MilestoneType"] = strawberry_django.field(pagination=True) milestones_count: int = strawberry_django.field(annotate=Count("milestone")) is_delayed: bool = strawberry_django.field( annotate=ExpressionWrapper( @@ -153,7 +153,7 @@ class IssueOrder: class MilestoneType(relay.Node, Named): due_date: strawberry.auto project: ProjectType - issues: List["IssueType"] = strawberry_django.field( + issues: list["IssueType"] = strawberry_django.field( filters=IssueFilter, order=IssueOrder, pagination=True, @@ -181,7 +181,7 @@ class MilestoneType(relay.Node, Named): ), ], ) - def my_issues(self) -> List["IssueType"]: + def my_issues(self) -> list["IssueType"]: return self._my_issues # type: ignore @strawberry_django.field( @@ -222,9 +222,9 @@ class IssueType(relay.Node, Named): kind: strawberry.auto name_with_priority: strawberry.auto name_with_kind: str = strawberry_django.field(only=["kind", "name"]) - tags: List["TagType"] - issue_assignees: List["AssigneeType"] - staff_assignees: List["StaffType"] = strawberry_django.field(field_name="assignees") + tags: list["TagType"] + issue_assignees: list["AssigneeType"] + staff_assignees: list["StaffType"] = strawberry_django.field(field_name="assignees") favorite_set: ListConnectionWithTotalCount["FavoriteType"] = ( strawberry_django.connection() ) @@ -259,7 +259,7 @@ class TagType(relay.Node, Named): issues: ListConnectionWithTotalCount[IssueType] = strawberry_django.connection() @strawberry_django.field - def issues_with_selected_related_milestone_and_project(self) -> List[IssueType]: + def issues_with_selected_related_milestone_and_project(self) -> list[IssueType]: # here, the `select_related` is on the queryset directly, and not on the field return ( self.issues.all() # type: ignore @@ -285,7 +285,7 @@ class IssueInput: milestone: "MilestoneInputPartial" priority: strawberry.auto kind: strawberry.auto - tags: Optional[List[NodeInput]] + tags: Optional[list[NodeInput]] extra: Optional[str] = strawberry.field(default=UNSET, graphql_type=Optional[int]) @@ -333,14 +333,14 @@ class MilestoneIssueInput: @strawberry_django.partial(Project) class ProjectInputPartial(NodeInputPartial): name: strawberry.auto - milestones: Optional[List["MilestoneInputPartial"]] + milestones: Optional[list["MilestoneInputPartial"]] @strawberry_django.input(Milestone) class MilestoneInput: name: strawberry.auto project: ProjectInputPartial - issues: Optional[List[MilestoneIssueInput]] + issues: Optional[list[MilestoneIssueInput]] @strawberry_django.partial(Milestone) @@ -365,23 +365,23 @@ class Query: Annotated["MilestoneType", strawberry.lazy("tests.projects.schema")] ] = strawberry_django.node() milestone_mandatory: MilestoneType = strawberry_django.node() - milestones: List[MilestoneType] = strawberry_django.node() + milestones: list[MilestoneType] = strawberry_django.node() project: Optional[ProjectType] = strawberry_django.node() project_login_required: Optional[ProjectType] = strawberry_django.node( extensions=[IsAuthenticated()], ) tag: Optional[TagType] = strawberry_django.node() staff: Optional[StaffType] = strawberry_django.node() - staff_list: List[Optional[StaffType]] = strawberry_django.node() + staff_list: list[Optional[StaffType]] = strawberry_django.node() - issue_list: List[IssueType] = strawberry_django.field() - milestone_list: List[MilestoneType] = strawberry_django.field( + issue_list: list[IssueType] = strawberry_django.field() + milestone_list: list[MilestoneType] = strawberry_django.field( order=MilestoneOrder, filters=MilestoneFilter, pagination=True, ) - project_list: List[ProjectType] = strawberry_django.field() - tag_list: List[TagType] = strawberry_django.field() + project_list: list[ProjectType] = strawberry_django.field() + tag_list: list[TagType] = strawberry_django.field() favorite_conn: ListConnectionWithTotalCount[FavoriteType] = ( strawberry_django.connection() @@ -426,7 +426,7 @@ class Query: issue_perm_required_optional: Optional[IssueType] = strawberry_django.node( extensions=[HasPerm(perms=["projects.view_issue"])], ) - issue_list_perm_required: List[IssueType] = strawberry_django.field( + issue_list_perm_required: list[IssueType] = strawberry_django.field( extensions=[HasPerm(perms=["projects.view_issue"])], ) issue_conn_perm_required: ListConnectionWithTotalCount[IssueType] = ( @@ -441,10 +441,10 @@ class Query: issue_obj_perm_required_optional: Optional[IssueType] = strawberry_django.node( extensions=[HasRetvalPerm(perms=["projects.view_issue"])], ) - issue_list_obj_perm_required: List[IssueType] = strawberry_django.field( + issue_list_obj_perm_required: list[IssueType] = strawberry_django.field( extensions=[HasRetvalPerm(perms=["projects.view_issue"])], ) - issue_list_obj_perm_required_paginated: List[IssueType] = strawberry_django.field( + issue_list_obj_perm_required_paginated: list[IssueType] = strawberry_django.field( extensions=[HasRetvalPerm(perms=["projects.view_issue"])], pagination=True ) issue_conn_obj_perm_required: ListConnectionWithTotalCount[IssueType] = ( diff --git a/tests/queries/test_fields.py b/tests/queries/test_fields.py index e8275852..0edb19d7 100644 --- a/tests/queries/test_fields.py +++ b/tests/queries/test_fields.py @@ -1,5 +1,5 @@ import textwrap -from typing import List, Optional, cast +from typing import Optional, cast import pytest import strawberry @@ -13,7 +13,7 @@ def generate_query(user_type): @strawberry.type class Query: - users: List[user_type] = strawberry_django.field() # type: ignore + users: list[user_type] = strawberry_django.field() # type: ignore return utils.generate_query(Query) @@ -53,7 +53,7 @@ class MyUser: @strawberry.type class Query: - users: List[MyUser] = strawberry_django.field() + users: list[MyUser] = strawberry_django.field() schema = strawberry.Schema(query=Query) @@ -82,7 +82,7 @@ class MyUser: @strawberry.type class Query: - users: List[MyUser] = strawberry_django.field() + users: list[MyUser] = strawberry_django.field() schema = strawberry.Schema(query=Query) diff --git a/tests/queries/test_files.py b/tests/queries/test_files.py index eb4a91a1..fb923a7a 100644 --- a/tests/queries/test_files.py +++ b/tests/queries/test_files.py @@ -1,5 +1,3 @@ -from typing import List - import pytest import strawberry from django.db import models @@ -22,7 +20,7 @@ class File: @strawberry.type class Query: - files: List[File] = strawberry_django.field() + files: list[File] = strawberry_django.field() @pytest.fixture diff --git a/tests/queries/test_m2m_through.py b/tests/queries/test_m2m_through.py index 4becb97c..323a676b 100644 --- a/tests/queries/test_m2m_through.py +++ b/tests/queries/test_m2m_through.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Optional import strawberry from django.db import models @@ -24,7 +24,7 @@ class MembershipModel(models.Model): @strawberry_django.type(ProjectModel) class Project: name: auto - membership: List["Membership"] = strawberry_django.field( + membership: list["Membership"] = strawberry_django.field( field_name="membershipmodel_set", ) @@ -32,7 +32,7 @@ class Project: @strawberry_django.type(MemberModel) class Member: name: auto - membership: List["Membership"] = strawberry_django.field( + membership: list["Membership"] = strawberry_django.field( field_name="membershipmodel_set", ) @@ -45,7 +45,7 @@ class Membership: @strawberry.type class Query: - projects: Optional[List[Project]] = strawberry_django.field() + projects: Optional[list[Project]] = strawberry_django.field() schema = strawberry.Schema(query=Query) diff --git a/tests/relay/lazy/a.py b/tests/relay/lazy/a.py index 05297ea6..1c2d2bbd 100644 --- a/tests/relay/lazy/a.py +++ b/tests/relay/lazy/a.py @@ -1,8 +1,8 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Annotated import strawberry from strawberry import relay -from typing_extensions import Annotated, TypeAlias +from typing_extensions import TypeAlias import strawberry_django from strawberry_django.relay import ListConnectionWithTotalCount diff --git a/tests/relay/lazy/b.py b/tests/relay/lazy/b.py index c94d0a20..a4dd365a 100644 --- a/tests/relay/lazy/b.py +++ b/tests/relay/lazy/b.py @@ -1,8 +1,8 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Annotated import strawberry from strawberry import relay -from typing_extensions import Annotated, TypeAlias +from typing_extensions import TypeAlias import strawberry_django from strawberry_django.relay import ListConnectionWithTotalCount diff --git a/tests/relay/mptt/a.py b/tests/relay/mptt/a.py index 85cb37c3..19560af9 100644 --- a/tests/relay/mptt/a.py +++ b/tests/relay/mptt/a.py @@ -1,8 +1,8 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Annotated import strawberry from strawberry import relay -from typing_extensions import Annotated, TypeAlias +from typing_extensions import TypeAlias import strawberry_django from strawberry_django.relay import ListConnectionWithTotalCount diff --git a/tests/relay/mptt/b.py b/tests/relay/mptt/b.py index 7e617c18..5a257786 100644 --- a/tests/relay/mptt/b.py +++ b/tests/relay/mptt/b.py @@ -1,8 +1,8 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Annotated import strawberry from strawberry import relay -from typing_extensions import Annotated, TypeAlias +from typing_extensions import TypeAlias import strawberry_django from strawberry_django.relay import ListConnectionWithTotalCount diff --git a/tests/relay/schema.py b/tests/relay/schema.py index f51c54bd..c18daf11 100644 --- a/tests/relay/schema.py +++ b/tests/relay/schema.py @@ -1,8 +1,8 @@ +from collections.abc import Iterable from typing import ( + Annotated, Any, ClassVar, - Iterable, - List, Optional, ) @@ -11,7 +11,6 @@ from strawberry import relay from strawberry.permission import BasePermission from strawberry.types import Info -from typing_extensions import Annotated import strawberry_django from strawberry_django.relay import ListConnectionWithTotalCount @@ -19,7 +18,7 @@ class FruitModel(models.Model): class Meta: # type: ignore - ordering: ClassVar[List[str]] = ["id"] + ordering: ClassVar[list[str]] = ["id"] name = models.CharField(max_length=255) color = models.CharField(max_length=255) @@ -56,9 +55,9 @@ class Query: node_with_async_permissions: relay.Node = strawberry_django.node( permission_classes=[DummyPermission], ) - nodes: List[relay.Node] = strawberry_django.node() + nodes: list[relay.Node] = strawberry_django.node() node_optional: Optional[relay.Node] = strawberry_django.node() - nodes_optional: List[Optional[relay.Node]] = strawberry_django.node() + nodes_optional: list[Optional[relay.Node]] = strawberry_django.node() fruits: ListConnectionWithTotalCount[Fruit] = strawberry_django.connection() fruits_lazy: ListConnectionWithTotalCount[ Annotated["Fruit", strawberry.lazy("tests.relay.schema")] diff --git a/tests/test_commands.py b/tests/test_commands.py index 13dff45c..dd47e379 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -36,8 +36,11 @@ def test_django_export_schema_exception_handle(): "strawberry_django.management.commands.export_schema.import_module_symbol", return_value=_FakeSchema(), ) - with mock_import_module, pytest.raises( - CommandError, - match="The `schema` must be an instance of strawberry.Schema", + with ( + mock_import_module, + pytest.raises( + CommandError, + match="The `schema` must be an instance of strawberry.Schema", + ), ): call_command("export_schema", "tests.schema") diff --git a/tests/test_optimizer.py b/tests/test_optimizer.py index 9e456e9d..a2046170 100644 --- a/tests/test_optimizer.py +++ b/tests/test_optimizer.py @@ -1,5 +1,5 @@ import datetime -from typing import Any, List, cast +from typing import Any, cast import pytest import strawberry @@ -130,7 +130,7 @@ def test_interface_query(db, gql_client: GraphQLTestClient): assert isinstance(res.data, dict) assert isinstance(res.data["node"], dict) assert { - frozenset(d.items()) for d in cast(List, res.data["node"].pop("tags")) + frozenset(d.items()) for d in cast(list, res.data["node"].pop("tags")) } == frozenset( { frozenset( @@ -925,7 +925,7 @@ class MilestoneTypeWithNestedPrefetch: @strawberry.type class Query: - milestones: List[MilestoneTypeWithNestedPrefetch] = strawberry_django.field() + milestones: list[MilestoneTypeWithNestedPrefetch] = strawberry_django.field() query = utils.generate_query(Query, enable_optimizer=True) query_str = """ @@ -1105,7 +1105,7 @@ class ProjectTypeWithPrefetch: def name(self, info) -> str: return self.name - milestones: List[MilestoneTypeWithNestedPrefetch] + milestones: list[MilestoneTypeWithNestedPrefetch] milestone1 = MilestoneFactory.create() project = milestone1.project @@ -1113,7 +1113,7 @@ def name(self, info) -> str: @strawberry.type class Query: - projects: List[ProjectTypeWithPrefetch] = strawberry_django.field() + projects: list[ProjectTypeWithPrefetch] = strawberry_django.field() query1 = utils.generate_query(Query, enable_optimizer=False) query_str = """ @@ -1388,7 +1388,7 @@ class MilestoneType: ), ], ) - def issues(self) -> List[IssueType]: + def issues(self) -> list[IssueType]: return self._my_issues # type: ignore @strawberry.type diff --git a/tests/test_ordering.py b/tests/test_ordering.py index e1dc96c2..f4587caf 100644 --- a/tests/test_ordering.py +++ b/tests/test_ordering.py @@ -1,5 +1,5 @@ # ruff: noqa: TRY002, B904, BLE001, F811, PT012 -from typing import Any, List, Optional, cast +from typing import Any, Optional, cast from unittest import mock import pytest @@ -67,7 +67,7 @@ class FruitWithOrder: @strawberry.type class Query: - fruits: List[Fruit] = strawberry_django.field(order=FruitOrder) + fruits: list[Fruit] = strawberry_django.field(order=FruitOrder) @pytest.fixture diff --git a/tests/test_pagination.py b/tests/test_pagination.py index 892744e7..18c60198 100644 --- a/tests/test_pagination.py +++ b/tests/test_pagination.py @@ -1,5 +1,5 @@ import sys -from typing import List, cast +from typing import cast import pytest import strawberry @@ -33,8 +33,8 @@ def get_queryset(cls, queryset, info, **kwargs): @strawberry.type class Query: - fruits: List[Fruit] = strawberry_django.field() - berries: List[BerryFruit] = strawberry_django.field() + fruits: list[Fruit] = strawberry_django.field() + berries: list[BerryFruit] = strawberry_django.field() @pytest.fixture @@ -89,9 +89,9 @@ def test_resolver_pagination(fruits): @strawberry.type class Query: @strawberry.field - def fruits(self, pagination: OffsetPaginationInput) -> List[Fruit]: + def fruits(self, pagination: OffsetPaginationInput) -> list[Fruit]: queryset = models.Fruit.objects.all() - return cast(List[Fruit], apply(pagination, queryset)) + return cast(list[Fruit], apply(pagination, queryset)) query = utils.generate_query(Query) result = query("{ fruits(pagination: { limit: 1 }) { id name } }") diff --git a/tests/test_permissions.py b/tests/test_permissions.py index 78f69d62..c1c492ee 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -1,5 +1,3 @@ -from typing import List - import pytest from django.contrib.auth.models import Permission from guardian.shortcuts import assign_perm @@ -18,7 +16,7 @@ from .utils import GraphQLTestClient PermKind: TypeAlias = Literal["user", "group", "superuser"] -perm_kinds: List[PermKind] = ["user", "group", "superuser"] +perm_kinds: list[PermKind] = ["user", "group", "superuser"] @pytest.mark.django_db(transaction=True) diff --git a/tests/test_queries.py b/tests/test_queries.py index b2bf1162..ffcb2b16 100644 --- a/tests/test_queries.py +++ b/tests/test_queries.py @@ -1,6 +1,6 @@ import io import textwrap -from typing import List, Optional, cast +from typing import Optional, cast from unittest import mock import pytest @@ -35,7 +35,7 @@ class User: class Group: id: auto name: auto - users: List[User] + users: list[User] @strawberry_django.type(models.Fruit) @@ -73,12 +73,12 @@ def get_queryset(cls, queryset, info, **kwargs): @strawberry.type class Query: user: User = strawberry_django.field() - users: List[User] = strawberry_django.field() + users: list[User] = strawberry_django.field() group: Group = strawberry_django.field() - groups: List[Group] = strawberry_django.field() + groups: list[Group] = strawberry_django.field() fruit: Fruit = strawberry_django.field() - berries: List[BerryFruit] = strawberry_django.field() - bananas: List[BananaFruit] = strawberry_django.field() + berries: list[BerryFruit] = strawberry_django.field() + bananas: list[BananaFruit] = strawberry_django.field() @pytest.fixture diff --git a/tests/types.py b/tests/types.py index dc5a8453..a48d466e 100644 --- a/tests/types.py +++ b/tests/types.py @@ -1,7 +1,5 @@ from __future__ import annotations -from typing import List - from django.conf import settings from strawberry import auto # noqa: TCH002 @@ -15,7 +13,7 @@ class Fruit: id: auto name: auto color: Color | None - types: List[FruitType] # noqa: UP006 + types: list[FruitType] picture: auto @@ -23,14 +21,14 @@ class Fruit: class Color: id: auto name: auto - fruits: List[Fruit] # noqa: UP006 + fruits: list[Fruit] @strawberry_django.type(models.FruitType) class FruitType: id: auto name: auto - fruits: List[Fruit] # noqa: UP006 + fruits: list[Fruit] @strawberry_django.type(models.TomatoWithRequiredPicture, fields="__all__") @@ -61,7 +59,7 @@ class GeoFieldPartialInput(GeoField): @strawberry_django.input(models.Fruit) class FruitInput(Fruit): - types: List[FruitTypeInput] | None # type: ignore # noqa: UP006 + types: list[FruitTypeInput] | None # type: ignore @strawberry_django.input(models.TomatoWithRequiredPicture) @@ -82,7 +80,7 @@ class FruitTypeInput(FruitType): @strawberry_django.input(models.Fruit, partial=True) class FruitPartialInput(FruitInput): - types: List[FruitTypePartialInput] | None # type: ignore # noqa: UP006 + types: list[FruitTypePartialInput] | None # type: ignore @strawberry_django.partial(models.TomatoWithRequiredPicture, fields="__all__") @@ -112,13 +110,13 @@ class User: class Group: id: auto name: auto - tags: List[Tag] # noqa: UP006 - users: List[User] # noqa: UP006 + tags: list[Tag] + users: list[User] @strawberry_django.type(models.Tag) class Tag: id: auto name: auto - groups: List[Group] # noqa: UP006 + groups: list[Group] user: User diff --git a/tests/types2/test_type.py b/tests/types2/test_type.py index df49040a..7dbb89f2 100644 --- a/tests/types2/test_type.py +++ b/tests/types2/test_type.py @@ -1,4 +1,4 @@ -from typing import Dict, Tuple, Union +from typing import Union import strawberry from django.db import models @@ -101,7 +101,7 @@ class Base: class Type(Base): pass - expected_fields: Dict[str, Tuple[Union[type, StrawberryContainer], bool]] = { + expected_fields: dict[str, tuple[Union[type, StrawberryContainer], bool]] = { "foreign_key": (strawberry_django.DjangoModelType, False), "related_foreign_key": ( StrawberryList(strawberry_django.DjangoModelType), diff --git a/tests/utils.py b/tests/utils.py index 9275e512..2efe8f25 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -4,7 +4,7 @@ import dataclasses import inspect import warnings -from typing import Any, Dict, Optional, Union +from typing import Any, Optional, Union import strawberry from django.db import DEFAULT_DB_ALIAS, connections @@ -134,11 +134,11 @@ def __exit__(self, *args, **kwargs): def request( self, - body: Dict[str, object], - headers: Optional[Dict[str, object]] = None, - files: Optional[Dict[str, object]] = None, + body: dict[str, object], + headers: Optional[dict[str, object]] = None, + files: Optional[dict[str, object]] = None, ): - kwargs: Dict[str, object] = {"data": body} + kwargs: dict[str, object] = {"data": body} if files: # pragma:nocover kwargs["format"] = "multipart" else: @@ -153,10 +153,10 @@ def request( def query( self, query: str, - variables: Optional[Dict[str, Any]] = None, - headers: Optional[Dict[str, object]] = None, + variables: Optional[dict[str, Any]] = None, + headers: Optional[dict[str, object]] = None, asserts_errors: Optional[bool] = None, - files: Optional[Dict[str, object]] = None, + files: Optional[dict[str, object]] = None, assert_no_errors: Optional[bool] = True, ) -> Response: body = self._build_body(query, variables, files)