diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 0015e30..2f67a24 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 3.1.2 +current_version = 3.2.0 commit = False tag = False diff --git a/.pyup.yml b/.pyup.yml deleted file mode 100644 index a438176..0000000 --- a/.pyup.yml +++ /dev/null @@ -1 +0,0 @@ -branch: main \ No newline at end of file diff --git a/README.md b/README.md index e736b18..a313d25 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,6 @@ For older versions of Python, you can use version 2 of these libraries. [![PyPI version](https://badge.fury.io/py/graphql-relay.svg)](https://badge.fury.io/py/graphql-relay) ![Test Status](https://github.com/graphql-python/graphql-relay-py/actions/workflows/test.yml/badge.svg) ![Lint Status](https://github.com/graphql-python/graphql-relay-py/actions/workflows/lint.yml/badge.svg) -[![Dependency Updates](https://pyup.io/repos/github/graphql-python/graphql-relay-py/shield.svg)](https://pyup.io/repos/github/graphql-python/graphql-relay-py/) -[![Python 3 Status](https://pyup.io/repos/github/graphql-python/graphql-relay-py/python-3-shield.svg)](https://pyup.io/repos/github/graphql-python/graphql-relay-py/) [![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) ## Getting Started @@ -52,54 +50,64 @@ pip install graphql-relay ``` When building a schema for [GraphQL](https://github.com/graphql-python/graphql-core), -the provided library functions can be used to simplify the creation of Relay -patterns. +the provided library functions can be used to simplify the creation of Relay patterns. + +All the functions that are explained in the following sections must be +imported from the top level of the `graphql_relay` package, like this: +```python +from graphql_relay import connection_definitions +``` ### Connections Helper functions are provided for both building the GraphQL types -for connections and for implementing the `resolver` method for fields +for connections and for implementing the `resolve` method for fields returning those types. - `connection_args` returns the arguments that fields should provide when -they return a connection type. +they return a connection type that supports bidirectional pagination. + - `forward_connection_args` returns the arguments that fields should provide when +they return a connection type that only supports forward pagination. + - `backward_connection_args` returns the arguments that fields should provide when +they return a connection type that only supports backward pagination. - `connection_definitions` returns a `connection_type` and its associated `edgeType`, given a name and a node type. - `connection_from_array` is a helper method that takes an array and the arguments from `connection_args`, does pagination and filtering, and returns -an object in the shape expected by a `connection_type`'s `resolver` function. - +an object in the shape expected by a `connection_type`'s `resolve` function. - `cursor_for_object_in_connection` is a helper method that takes an array and a member object, and returns a cursor for use in the mutation payload. + - `offset_to_cursor` takes the index of a member object in an array + and returns an opaque cursor for use in the mutation payload. + - `cursor_to_offset` takes an opaque cursor (created with `offset_to_cursor`) +and returns the corresponding array index. -An example usage of these methods from the [test schema](tests/starwars/schema.py): +An example usage of these methods from the [test schema](tests/star_wars_schema.py): ```python -ship_edge, ship_connection = connection_definitions('Ship', shipType) +ship_edge, ship_connection = connection_definitions(ship_type, "Ship") -factionType = GraphQLObjectType( - name='Faction', - description='A faction in the Star Wars saga', +faction_type = GraphQLObjectType( + name="Faction", + description="A faction in the Star Wars saga", fields=lambda: { - 'id': global_id_field('Faction'), - 'name': GraphQLField( - GraphQLString, - description='The name of the faction.', - ), - 'ships': GraphQLField( + "id": global_id_field("Faction"), + "name": GraphQLField(GraphQLString, description="The name of the faction."), + "ships": GraphQLField( ship_connection, - description='The ships used by the faction.', + description="The ships used by the faction.", args=connection_args, resolve=lambda faction, _info, **args: connection_from_array( - [getShip(ship) for ship in faction.ships], args), - ) + [get_ship(ship) for ship in faction.ships], args + ), + ), }, - interfaces=[node_interface] + interfaces=[node_interface], ) ``` This shows adding a `ships` field to the `Faction` object that is a connection. -It uses `connection_definitions('Ship', shipType)` to create the connection +It uses `connection_definitions(ship_type, "Ship")` to create the connection type, adds `connection_args` as arguments on this function, and then implements the resolver function by passing the array of ships and the arguments to `connection_from_array`. @@ -122,45 +130,54 @@ for nodes and for implementing global IDs around local IDs. non-ID identifiers (like a username) and maps then to their corresponding objects. -An example usage of these methods from the [test schema](tests/starwars/schema.py): +An example usage of these methods from the [test schema](tests/star_wars_schema.py): ```python def get_node(global_id, _info): type_, id_ = from_global_id(global_id) - if type_ == 'Faction': - return getFaction(id_) - elif type_ == 'Ship': - return getShip(id_) - else: - return None + if type_ == "Faction": + return get_faction(id_) + if type_ == "Ship": + return get_ship(id_) + return None # pragma: no cover def get_node_type(obj, _info, _type): if isinstance(obj, Faction): - return factionType - else: - return shipType + return faction_type.name + return ship_type.name -node_interface, node_field = node_definitions(get_node, get_node_type) +node_interface, node_field = node_definitions(get_node, get_node_type)[:2] -factionType = GraphQLObjectType( - name= 'Faction', - description= 'A faction in the Star Wars saga', - fields= lambda: { - 'id': global_id_field('Faction'), +faction_type = GraphQLObjectType( + name="Faction", + description="A faction in the Star Wars saga", + fields=lambda: { + "id": global_id_field("Faction"), + "name": GraphQLField(GraphQLString, description="The name of the faction."), + "ships": GraphQLField( + ship_connection, + description="The ships used by the faction.", + args=connection_args, + resolve=lambda faction, _info, **args: connection_from_array( + [get_ship(ship) for ship in faction.ships], args + ), + ), }, - interfaces= [node_interface] + interfaces=[node_interface], ) -queryType = GraphQLObjectType( - name= 'Query', - fields= lambda: { - 'node': node_field - } +query_type = GraphQLObjectType( + name="Query", + fields=lambda: { + "rebels": GraphQLField(faction_type, resolve=lambda _obj, _info: get_rebels()), + "empire": GraphQLField(faction_type, resolve=lambda _obj, _info: get_empire()), + "node": node_field, + }, ) ``` This uses `node_definitions` to construct the `Node` interface and the `node` -field; it uses `from_global_id` to resolve the IDs passed in in the implementation +field; it uses `from_global_id` to resolve the IDs passed in the implementation of the function mapping ID to object. It then uses the `global_id_field` method to create the `id` field on `Faction`, which also ensures implements the `node_interface`. Finally, it adds the `node` field to the query type, using the @@ -176,47 +193,39 @@ and a mutation method to map from the input fields to the output fields, performing the mutation along the way. It then creates and returns a field configuration that can be used as a top-level field on the mutation type. -An example usage of these methods from the [test schema](tests/starwars/schema.py): +An example usage of these methods from the [test schema](tests/star_wars_schema.py): ```python class IntroduceShipMutation: + def __init__(self, shipId, factionId, clientMutationId=None): self.shipId = shipId self.factionId = factionId self.clientMutationId = clientMutationId -def mutate_and_get_payload(_info, shipName, factionId): - newShip = createShip(shipName, factionId) - return IntroduceShipMutation(shipId=newShip.id, factionId=factionId) +def mutate_and_get_payload(_info, shipName, factionId, **_input): + new_ship = create_ship(shipName, factionId) + return IntroduceShipMutation(shipId=new_ship.id, factionId=factionId) -shipMutation = mutation_with_client_mutation_id( - 'IntroduceShip', +ship_mutation = mutation_with_client_mutation_id( + "IntroduceShip", input_fields={ - 'shipName': GraphQLInputField( - GraphQLNonNull(GraphQLString) - ), - 'factionId': GraphQLInputField( - GraphQLNonNull(GraphQLID) - ) + "shipName": GraphQLInputField(GraphQLNonNull(GraphQLString)), + "factionId": GraphQLInputField(GraphQLNonNull(GraphQLID)), }, output_fields={ - 'ship': GraphQLField( - shipType, - resolve=lambda payload, _info: getShip(payload.shipId) + "ship": GraphQLField( + ship_type, resolve=lambda payload, _info: get_ship(payload.shipId) + ), + "faction": GraphQLField( + faction_type, resolve=lambda payload, _info: get_faction(payload.factionId) ), - 'faction': GraphQLField( - factionType, - resolve=lambda payload, _info: getFaction(payload.factionId) - ) }, - mutate_and_get_payload=mutate_and_get_payload + mutate_and_get_payload=mutate_and_get_payload, ) -mutationType = GraphQLObjectType( - 'Mutation', - fields=lambda: { - 'introduceShip': shipMutation - } +mutation_type = GraphQLObjectType( + "Mutation", fields=lambda: {"introduceShip": ship_mutation} ) ``` @@ -264,5 +273,5 @@ Python versions and perform all additional source code checks. You can also restrict tox to an individual environment, like this: ```sh -poetry run tox -e py37 +poetry run tox -e py39 ``` diff --git a/poetry.lock b/poetry.lock index 15bf289..5070bcf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -53,30 +53,26 @@ d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] [[package]] name = "black" -version = "21.12b0" +version = "22.3.0" description = "The uncompromising code formatter." category = "dev" optional = false python-versions = ">=3.6.2" [package.dependencies] -click = ">=7.1.2" +click = ">=8.0.0" dataclasses = {version = ">=0.6", markers = "python_version < \"3.7\""} mypy-extensions = ">=0.4.3" -pathspec = ">=0.9.0,<1" +pathspec = ">=0.9.0" platformdirs = ">=2" -tomli = ">=0.2.6,<2.0.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} -typing-extensions = [ - {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}, - {version = "!=3.10.0.1", markers = "python_version >= \"3.10\""}, -] +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] colorama = ["colorama (>=0.4.3)"] d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -python2 = ["typed-ast (>=1.4.3)"] uvloop = ["uvloop (>=0.15.2)"] [[package]] @@ -108,28 +104,9 @@ category = "dev" optional = false python-versions = ">=3.5" -[[package]] -name = "certifi" -version = "2021.10.8" -description = "Python package for providing Mozilla's CA Bundle." -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "charset-normalizer" -version = "2.0.10" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "dev" -optional = false -python-versions = ">=3.5.0" - -[package.extras] -unicode_backport = ["unicodedata2"] - [[package]] name = "check-manifest" -version = "0.47" +version = "0.48" description = "Check MANIFEST.in in a Python source package for completeness" category = "dev" optional = false @@ -137,14 +114,14 @@ python-versions = ">=3.6" [package.dependencies] build = ">=0.1" -toml = "*" +tomli = "*" [package.extras] test = ["mock (>=3.0.0)", "pytest"] [[package]] name = "click" -version = "8.0.3" +version = "8.0.4" description = "Composable command line interface toolkit" category = "dev" optional = false @@ -154,18 +131,6 @@ python-versions = ">=3.6" colorama = {version = "*", markers = "platform_system == \"Windows\""} importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -[[package]] -name = "codecov" -version = "2.1.12" -description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.dependencies] -coverage = "*" -requests = ">=2.7.9" - [[package]] name = "colorama" version = "0.4.4" @@ -232,20 +197,12 @@ pyflakes = ">=2.4.0,<2.5.0" [[package]] name = "graphql-core" -version = "3.1.7" +version = "3.2.1" description = "GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL." category = "main" optional = false python-versions = ">=3.6,<4" -[[package]] -name = "idna" -version = "3.3" -description = "Internationalized Domain Names in Applications (IDNA)" -category = "dev" -optional = false -python-versions = ">=3.5" - [[package]] name = "importlib-metadata" version = "4.2.0" @@ -295,7 +252,7 @@ python-versions = "*" [[package]] name = "mypy" -version = "0.931" +version = "0.942" description = "Optional static typing for Python" category = "dev" optional = false @@ -310,6 +267,7 @@ typing-extensions = ">=3.10" [package.extras] dmypy = ["psutil (>=4.0)"] python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] [[package]] name = "mypy-extensions" @@ -404,7 +362,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyparsing" -version = "3.0.6" +version = "3.0.7" description = "Python parsing module" category = "dev" optional = false @@ -451,7 +409,7 @@ testing = ["coverage", "hypothesis (>=5.7.1)"] [[package]] name = "pytest-asyncio" -version = "0.17.2" +version = "0.18.3" description = "Pytest support for asyncio" category = "dev" optional = false @@ -459,10 +417,10 @@ python-versions = ">=3.7" [package.dependencies] pytest = ">=6.1.0" -typing-extensions = {version = ">=4.0", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=3.7.2", markers = "python_version < \"3.8\""} [package.extras] -testing = ["coverage (==6.2)", "hypothesis (>=5.7.1)", "flaky (>=3.5.0)", "mypy (==0.931)"] +testing = ["coverage (==6.2)", "hypothesis (>=5.7.1)", "flaky (>=3.5.0)", "mypy (==0.931)", "pytest-trio (>=0.7.0)"] [[package]] name = "pytest-cov" @@ -492,29 +450,11 @@ pytest = ">=4.0.0" [[package]] name = "regex" -version = "2022.1.18" +version = "2022.3.15" description = "Alternative regular expression module, to replace re." category = "dev" optional = false -python-versions = "*" - -[[package]] -name = "requests" -version = "2.27.1" -description = "Python HTTP for Humans." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} -idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} -urllib3 = ">=1.21.1,<1.27" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] +python-versions = ">=3.6" [[package]] name = "six" @@ -542,7 +482,7 @@ python-versions = ">=3.6" [[package]] name = "tox" -version = "3.24.5" +version = "3.25.0" description = "tox is a generic virtualenv management and test command line tool" category = "dev" optional = false @@ -565,7 +505,7 @@ testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pytest (>=4.0.0)", "pytes [[package]] name = "typed-ast" -version = "1.5.1" +version = "1.5.2" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "dev" optional = false @@ -573,28 +513,15 @@ python-versions = ">=3.6" [[package]] name = "typing-extensions" -version = "4.0.1" +version = "4.1.1" description = "Backported and Experimental Type Hints for Python 3.6+" category = "main" optional = false python-versions = ">=3.6" -[[package]] -name = "urllib3" -version = "1.26.8" -description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" - -[package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] - [[package]] name = "virtualenv" -version = "20.13.0" +version = "20.14.1" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -627,7 +554,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = "^3.6" -content-hash = "3a44fb854a0f2ffa13136a97450a0fa93afe83ae2e932bdf5831d7ae8f10e3d6" +content-hash = "a697c403fc34533863e70972dfabd69751fc6a8acece291d4b40d9d631312cc0" [metadata.files] appdirs = [ @@ -644,8 +571,29 @@ attrs = [ ] black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, - {file = "black-21.12b0-py3-none-any.whl", hash = "sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"}, - {file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"}, + {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, + {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, + {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"}, + {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"}, + {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"}, + {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"}, + {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"}, + {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"}, + {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"}, + {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"}, + {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"}, + {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"}, + {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"}, + {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"}, + {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"}, + {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"}, + {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"}, + {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, + {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, ] build = [ {file = "build-0.7.0-py3-none-any.whl", hash = "sha256:21b7ebbd1b22499c4dac536abc7606696ea4d909fd755e00f09f3c0f2c05e3c8"}, @@ -655,26 +603,13 @@ bump2version = [ {file = "bump2version-1.0.1-py2.py3-none-any.whl", hash = "sha256:37f927ea17cde7ae2d7baf832f8e80ce3777624554a653006c9144f8017fe410"}, {file = "bump2version-1.0.1.tar.gz", hash = "sha256:762cb2bfad61f4ec8e2bdf452c7c267416f8c70dd9ecb1653fd0bbb01fa936e6"}, ] -certifi = [ - {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, - {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, -] -charset-normalizer = [ - {file = "charset-normalizer-2.0.10.tar.gz", hash = "sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd"}, - {file = "charset_normalizer-2.0.10-py3-none-any.whl", hash = "sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455"}, -] check-manifest = [ - {file = "check-manifest-0.47.tar.gz", hash = "sha256:56dadd260a9c7d550b159796d2894b6d0bcc176a94cbc426d9bb93e5e48d12ce"}, - {file = "check_manifest-0.47-py3-none-any.whl", hash = "sha256:365c94d65de4c927d9d8b505371d08ee19f9f369c86b9ac3db97c2754c827c95"}, + {file = "check-manifest-0.48.tar.gz", hash = "sha256:3b575f1dade7beb3078ef4bf33a94519834457c7281dbc726b15c5466b55c657"}, + {file = "check_manifest-0.48-py3-none-any.whl", hash = "sha256:b1923685f98c1c2468601a1a7bed655db549a25d43c583caded3860ad8308f8c"}, ] click = [ - {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, - {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, -] -codecov = [ - {file = "codecov-2.1.12-py2.py3-none-any.whl", hash = "sha256:585dc217dc3d8185198ceb402f85d5cb5dbfa0c5f350a5abcdf9e347776a5b47"}, - {file = "codecov-2.1.12-py3.8.egg", hash = "sha256:782a8e5352f22593cbc5427a35320b99490eb24d9dcfa2155fd99d2b75cfb635"}, - {file = "codecov-2.1.12.tar.gz", hash = "sha256:a0da46bb5025426da895af90938def8ee12d37fcbcbbbc15b6dc64cf7ebc51c1"}, + {file = "click-8.0.4-py3-none-any.whl", hash = "sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1"}, + {file = "click-8.0.4.tar.gz", hash = "sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb"}, ] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, @@ -746,12 +681,8 @@ flake8 = [ {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, ] graphql-core = [ - {file = "graphql-core-3.1.7.tar.gz", hash = "sha256:62ec192150ccecd9a18cfb79e3e72eb7d1fd68fb594ef19c40099b6deec8ef0c"}, - {file = "graphql_core-3.1.7-py3-none-any.whl", hash = "sha256:9b460f60320be01c7f3b1766cf3e406933003008055079b9d983b8f3988f4400"}, -] -idna = [ - {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, - {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, + {file = "graphql-core-3.2.1.tar.gz", hash = "sha256:9d1bf141427b7d54be944587c8349df791ce60ade2e3cccaf9c56368c133c201"}, + {file = "graphql_core-3.2.1-py3-none-any.whl", hash = "sha256:f83c658e4968998eed1923a2e3e3eddd347e005ac0315fbb7ca4d70ea9156323"}, ] importlib-metadata = [ {file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"}, @@ -770,26 +701,29 @@ mccabe = [ {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] mypy = [ - {file = "mypy-0.931-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c5b42d0815e15518b1f0990cff7a705805961613e701db60387e6fb663fe78a"}, - {file = "mypy-0.931-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c89702cac5b302f0c5d33b172d2b55b5df2bede3344a2fbed99ff96bddb2cf00"}, - {file = "mypy-0.931-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:300717a07ad09525401a508ef5d105e6b56646f7942eb92715a1c8d610149714"}, - {file = "mypy-0.931-cp310-cp310-win_amd64.whl", hash = "sha256:7b3f6f557ba4afc7f2ce6d3215d5db279bcf120b3cfd0add20a5d4f4abdae5bc"}, - {file = "mypy-0.931-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1bf752559797c897cdd2c65f7b60c2b6969ffe458417b8d947b8340cc9cec08d"}, - {file = "mypy-0.931-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4365c60266b95a3f216a3047f1d8e3f895da6c7402e9e1ddfab96393122cc58d"}, - {file = "mypy-0.931-cp36-cp36m-win_amd64.whl", hash = "sha256:1b65714dc296a7991000b6ee59a35b3f550e0073411ac9d3202f6516621ba66c"}, - {file = "mypy-0.931-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e839191b8da5b4e5d805f940537efcaa13ea5dd98418f06dc585d2891d228cf0"}, - {file = "mypy-0.931-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:50c7346a46dc76a4ed88f3277d4959de8a2bd0a0fa47fa87a4cde36fe247ac05"}, - {file = "mypy-0.931-cp37-cp37m-win_amd64.whl", hash = "sha256:d8f1ff62f7a879c9fe5917b3f9eb93a79b78aad47b533911b853a757223f72e7"}, - {file = "mypy-0.931-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f9fe20d0872b26c4bba1c1be02c5340de1019530302cf2dcc85c7f9fc3252ae0"}, - {file = "mypy-0.931-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1b06268df7eb53a8feea99cbfff77a6e2b205e70bf31743e786678ef87ee8069"}, - {file = "mypy-0.931-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8c11003aaeaf7cc2d0f1bc101c1cc9454ec4cc9cb825aef3cafff8a5fdf4c799"}, - {file = "mypy-0.931-cp38-cp38-win_amd64.whl", hash = "sha256:d9d2b84b2007cea426e327d2483238f040c49405a6bf4074f605f0156c91a47a"}, - {file = "mypy-0.931-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ff3bf387c14c805ab1388185dd22d6b210824e164d4bb324b195ff34e322d166"}, - {file = "mypy-0.931-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b56154f8c09427bae082b32275a21f500b24d93c88d69a5e82f3978018a0266"}, - {file = "mypy-0.931-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8ca7f8c4b1584d63c9a0f827c37ba7a47226c19a23a753d52e5b5eddb201afcd"}, - {file = "mypy-0.931-cp39-cp39-win_amd64.whl", hash = "sha256:74f7eccbfd436abe9c352ad9fb65872cc0f1f0a868e9d9c44db0893440f0c697"}, - {file = "mypy-0.931-py3-none-any.whl", hash = "sha256:1171f2e0859cfff2d366da2c7092b06130f232c636a3f7301e3feb8b41f6377d"}, - {file = "mypy-0.931.tar.gz", hash = "sha256:0038b21890867793581e4cb0d810829f5fd4441aa75796b53033af3aa30430ce"}, + {file = "mypy-0.942-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d"}, + {file = "mypy-0.942-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46"}, + {file = "mypy-0.942-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6776e5fa22381cc761df53e7496a805801c1a751b27b99a9ff2f0ca848c7eca0"}, + {file = "mypy-0.942-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee"}, + {file = "mypy-0.942-cp310-cp310-win_amd64.whl", hash = "sha256:64235137edc16bee6f095aba73be5334677d6f6bdb7fa03cfab90164fa294a17"}, + {file = "mypy-0.942-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b840cfe89c4ab6386c40300689cd8645fc8d2d5f20101c7f8bd23d15fca14904"}, + {file = "mypy-0.942-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b184db8c618c43c3a31b32ff00cd28195d39e9c24e7c3b401f3db7f6e5767f5"}, + {file = "mypy-0.942-cp36-cp36m-win_amd64.whl", hash = "sha256:1a0459c333f00e6a11cbf6b468b870c2b99a906cb72d6eadf3d1d95d38c9352c"}, + {file = "mypy-0.942-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c3e497588afccfa4334a9986b56f703e75793133c4be3a02d06a3df16b67a58"}, + {file = "mypy-0.942-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f6ad963172152e112b87cc7ec103ba0f2db2f1cd8997237827c052a3903eaa6"}, + {file = "mypy-0.942-cp37-cp37m-win_amd64.whl", hash = "sha256:0e2dd88410937423fba18e57147dd07cd8381291b93d5b1984626f173a26543e"}, + {file = "mypy-0.942-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:246e1aa127d5b78488a4a0594bd95f6d6fb9d63cf08a66dafbff8595d8891f67"}, + {file = "mypy-0.942-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8d3ba77e56b84cd47a8ee45b62c84b6d80d32383928fe2548c9a124ea0a725c"}, + {file = "mypy-0.942-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2bc249409a7168d37c658e062e1ab5173300984a2dada2589638568ddc1db02b"}, + {file = "mypy-0.942-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9521c1265ccaaa1791d2c13582f06facf815f426cd8b07c3a485f486a8ffc1f3"}, + {file = "mypy-0.942-cp38-cp38-win_amd64.whl", hash = "sha256:e865fec858d75b78b4d63266c9aff770ecb6a39dfb6d6b56c47f7f8aba6baba8"}, + {file = "mypy-0.942-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6ce34a118d1a898f47def970a2042b8af6bdcc01546454726c7dd2171aa6dfca"}, + {file = "mypy-0.942-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:10daab80bc40f84e3f087d896cdb53dc811a9f04eae4b3f95779c26edee89d16"}, + {file = "mypy-0.942-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3841b5433ff936bff2f4dc8d54cf2cdbfea5d8e88cedfac45c161368e5770ba6"}, + {file = "mypy-0.942-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f7106cbf9cc2f403693bf50ed7c9fa5bb3dfa9007b240db3c910929abe2a322"}, + {file = "mypy-0.942-cp39-cp39-win_amd64.whl", hash = "sha256:7742d2c4e46bb5017b51c810283a6a389296cda03df805a4f7869a6f41246534"}, + {file = "mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db"}, + {file = "mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, @@ -828,8 +762,8 @@ pyflakes = [ {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, ] pyparsing = [ - {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, - {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, + {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, + {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, ] pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, @@ -838,8 +772,9 @@ pytest = [ pytest-asyncio = [ {file = "pytest-asyncio-0.16.0.tar.gz", hash = "sha256:7496c5977ce88c34379df64a66459fe395cd05543f0a2f837016e7144391fcfb"}, {file = "pytest_asyncio-0.16.0-py3-none-any.whl", hash = "sha256:5f2a21273c47b331ae6aa5b36087047b4899e40f03f18397c0e65fa5cca54e9b"}, - {file = "pytest-asyncio-0.17.2.tar.gz", hash = "sha256:6d895b02432c028e6957d25fc936494e78c6305736e785d9fee408b1efbc7ff4"}, - {file = "pytest_asyncio-0.17.2-py3-none-any.whl", hash = "sha256:e0fe5dbea40516b661ef1bcfe0bd9461c2847c4ef4bb40012324f2454fb7d56d"}, + {file = "pytest-asyncio-0.18.3.tar.gz", hash = "sha256:7659bdb0a9eb9c6e3ef992eef11a2b3e69697800ad02fb06374a210d85b29f91"}, + {file = "pytest_asyncio-0.18.3-1-py3-none-any.whl", hash = "sha256:16cf40bdf2b4fb7fc8e4b82bd05ce3fbcd454cbf7b92afc445fe299dabb88213"}, + {file = "pytest_asyncio-0.18.3-py3-none-any.whl", hash = "sha256:8fafa6c52161addfd41ee7ab35f11836c5a16ec208f93ee388f752bea3493a84"}, ] pytest-cov = [ {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, @@ -850,84 +785,80 @@ pytest-describe = [ {file = "pytest_describe-2.0.1-py3-none-any.whl", hash = "sha256:ea347838bdf774b498ee7cb4a0b802a40be89e667a399fb63d860e3223bf4183"}, ] regex = [ - {file = "regex-2022.1.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:34316bf693b1d2d29c087ee7e4bb10cdfa39da5f9c50fa15b07489b4ab93a1b5"}, - {file = "regex-2022.1.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a0b9f6a1a15d494b35f25ed07abda03209fa76c33564c09c9e81d34f4b919d7"}, - {file = "regex-2022.1.18-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f99112aed4fb7cee00c7f77e8b964a9b10f69488cdff626ffd797d02e2e4484f"}, - {file = "regex-2022.1.18-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a2bf98ac92f58777c0fafc772bf0493e67fcf677302e0c0a630ee517a43b949"}, - {file = "regex-2022.1.18-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8618d9213a863c468a865e9d2ec50221015f7abf52221bc927152ef26c484b4c"}, - {file = "regex-2022.1.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b52cc45e71657bc4743a5606d9023459de929b2a198d545868e11898ba1c3f59"}, - {file = "regex-2022.1.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e12949e5071c20ec49ef00c75121ed2b076972132fc1913ddf5f76cae8d10b4"}, - {file = "regex-2022.1.18-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b02e3e72665cd02afafb933453b0c9f6c59ff6e3708bd28d0d8580450e7e88af"}, - {file = "regex-2022.1.18-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:abfcb0ef78df0ee9df4ea81f03beea41849340ce33a4c4bd4dbb99e23ec781b6"}, - {file = "regex-2022.1.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6213713ac743b190ecbf3f316d6e41d099e774812d470422b3a0f137ea635832"}, - {file = "regex-2022.1.18-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:61ebbcd208d78658b09e19c78920f1ad38936a0aa0f9c459c46c197d11c580a0"}, - {file = "regex-2022.1.18-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:b013f759cd69cb0a62de954d6d2096d648bc210034b79b1881406b07ed0a83f9"}, - {file = "regex-2022.1.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9187500d83fd0cef4669385cbb0961e227a41c0c9bc39219044e35810793edf7"}, - {file = "regex-2022.1.18-cp310-cp310-win32.whl", hash = "sha256:94c623c331a48a5ccc7d25271399aff29729fa202c737ae3b4b28b89d2b0976d"}, - {file = "regex-2022.1.18-cp310-cp310-win_amd64.whl", hash = "sha256:1a171eaac36a08964d023eeff740b18a415f79aeb212169080c170ec42dd5184"}, - {file = "regex-2022.1.18-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:49810f907dfe6de8da5da7d2b238d343e6add62f01a15d03e2195afc180059ed"}, - {file = "regex-2022.1.18-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d2f5c3f7057530afd7b739ed42eb04f1011203bc5e4663e1e1d01bb50f813e3"}, - {file = "regex-2022.1.18-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:85ffd6b1cb0dfb037ede50ff3bef80d9bf7fa60515d192403af6745524524f3b"}, - {file = "regex-2022.1.18-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ba37f11e1d020969e8a779c06b4af866ffb6b854d7229db63c5fdddfceaa917f"}, - {file = "regex-2022.1.18-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e27ea1ebe4a561db75a880ac659ff439dec7f55588212e71700bb1ddd5af9"}, - {file = "regex-2022.1.18-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37978254d9d00cda01acc1997513f786b6b971e57b778fbe7c20e30ae81a97f3"}, - {file = "regex-2022.1.18-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e54a1eb9fd38f2779e973d2f8958fd575b532fe26013405d1afb9ee2374e7ab8"}, - {file = "regex-2022.1.18-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:768632fd8172ae03852e3245f11c8a425d95f65ff444ce46b3e673ae5b057b74"}, - {file = "regex-2022.1.18-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:de2923886b5d3214be951bc2ce3f6b8ac0d6dfd4a0d0e2a4d2e5523d8046fdfb"}, - {file = "regex-2022.1.18-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:1333b3ce73269f986b1fa4d5d395643810074dc2de5b9d262eb258daf37dc98f"}, - {file = "regex-2022.1.18-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:d19a34f8a3429bd536996ad53597b805c10352a8561d8382e05830df389d2b43"}, - {file = "regex-2022.1.18-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d2f355a951f60f0843f2368b39970e4667517e54e86b1508e76f92b44811a8a"}, - {file = "regex-2022.1.18-cp36-cp36m-win32.whl", hash = "sha256:2245441445099411b528379dee83e56eadf449db924648e5feb9b747473f42e3"}, - {file = "regex-2022.1.18-cp36-cp36m-win_amd64.whl", hash = "sha256:25716aa70a0d153cd844fe861d4f3315a6ccafce22b39d8aadbf7fcadff2b633"}, - {file = "regex-2022.1.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7e070d3aef50ac3856f2ef5ec7214798453da878bb5e5a16c16a61edf1817cc3"}, - {file = "regex-2022.1.18-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22709d701e7037e64dae2a04855021b62efd64a66c3ceed99dfd684bfef09e38"}, - {file = "regex-2022.1.18-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9099bf89078675c372339011ccfc9ec310310bf6c292b413c013eb90ffdcafc"}, - {file = "regex-2022.1.18-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04611cc0f627fc4a50bc4a9a2e6178a974c6a6a4aa9c1cca921635d2c47b9c87"}, - {file = "regex-2022.1.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:552a39987ac6655dad4bf6f17dd2b55c7b0c6e949d933b8846d2e312ee80005a"}, - {file = "regex-2022.1.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e031899cb2bc92c0cf4d45389eff5b078d1936860a1be3aa8c94fa25fb46ed8"}, - {file = "regex-2022.1.18-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2dacb3dae6b8cc579637a7b72f008bff50a94cde5e36e432352f4ca57b9e54c4"}, - {file = "regex-2022.1.18-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:e5c31d70a478b0ca22a9d2d76d520ae996214019d39ed7dd93af872c7f301e52"}, - {file = "regex-2022.1.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bb804c7d0bfbd7e3f33924ff49757de9106c44e27979e2492819c16972ec0da2"}, - {file = "regex-2022.1.18-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:36b2d700a27e168fa96272b42d28c7ac3ff72030c67b32f37c05616ebd22a202"}, - {file = "regex-2022.1.18-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:16f81025bb3556eccb0681d7946e2b35ff254f9f888cff7d2120e8826330315c"}, - {file = "regex-2022.1.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:da80047524eac2acf7c04c18ac7a7da05a9136241f642dd2ed94269ef0d0a45a"}, - {file = "regex-2022.1.18-cp37-cp37m-win32.whl", hash = "sha256:6ca45359d7a21644793de0e29de497ef7f1ae7268e346c4faf87b421fea364e6"}, - {file = "regex-2022.1.18-cp37-cp37m-win_amd64.whl", hash = "sha256:38289f1690a7e27aacd049e420769b996826f3728756859420eeee21cc857118"}, - {file = "regex-2022.1.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6014038f52b4b2ac1fa41a58d439a8a00f015b5c0735a0cd4b09afe344c94899"}, - {file = "regex-2022.1.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0b5d6f9aed3153487252d00a18e53f19b7f52a1651bc1d0c4b5844bc286dfa52"}, - {file = "regex-2022.1.18-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9d24b03daf7415f78abc2d25a208f234e2c585e5e6f92f0204d2ab7b9ab48e3"}, - {file = "regex-2022.1.18-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf594cc7cc9d528338d66674c10a5b25e3cde7dd75c3e96784df8f371d77a298"}, - {file = "regex-2022.1.18-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd914db437ec25bfa410f8aa0aa2f3ba87cdfc04d9919d608d02330947afaeab"}, - {file = "regex-2022.1.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90b6840b6448203228a9d8464a7a0d99aa8fa9f027ef95fe230579abaf8a6ee1"}, - {file = "regex-2022.1.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11772be1eb1748e0e197a40ffb82fb8fd0d6914cd147d841d9703e2bef24d288"}, - {file = "regex-2022.1.18-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a602bdc8607c99eb5b391592d58c92618dcd1537fdd87df1813f03fed49957a6"}, - {file = "regex-2022.1.18-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7e26eac9e52e8ce86f915fd33380f1b6896a2b51994e40bb094841e5003429b4"}, - {file = "regex-2022.1.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:519c0b3a6fbb68afaa0febf0d28f6c4b0a1074aefc484802ecb9709faf181607"}, - {file = "regex-2022.1.18-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3c7ea86b9ca83e30fa4d4cd0eaf01db3ebcc7b2726a25990966627e39577d729"}, - {file = "regex-2022.1.18-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:51f02ca184518702975b56affde6c573ebad4e411599005ce4468b1014b4786c"}, - {file = "regex-2022.1.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:385ccf6d011b97768a640e9d4de25412204fbe8d6b9ae39ff115d4ff03f6fe5d"}, - {file = "regex-2022.1.18-cp38-cp38-win32.whl", hash = "sha256:1f8c0ae0a0de4e19fddaaff036f508db175f6f03db318c80bbc239a1def62d02"}, - {file = "regex-2022.1.18-cp38-cp38-win_amd64.whl", hash = "sha256:760c54ad1b8a9b81951030a7e8e7c3ec0964c1cb9fee585a03ff53d9e531bb8e"}, - {file = "regex-2022.1.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:93c20777a72cae8620203ac11c4010365706062aa13aaedd1a21bb07adbb9d5d"}, - {file = "regex-2022.1.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6aa427c55a0abec450bca10b64446331b5ca8f79b648531138f357569705bc4a"}, - {file = "regex-2022.1.18-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c38baee6bdb7fe1b110b6b3aaa555e6e872d322206b7245aa39572d3fc991ee4"}, - {file = "regex-2022.1.18-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:752e7ddfb743344d447367baa85bccd3629c2c3940f70506eb5f01abce98ee68"}, - {file = "regex-2022.1.18-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8acef4d8a4353f6678fd1035422a937c2170de58a2b29f7da045d5249e934101"}, - {file = "regex-2022.1.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c73d2166e4b210b73d1429c4f1ca97cea9cc090e5302df2a7a0a96ce55373f1c"}, - {file = "regex-2022.1.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24c89346734a4e4d60ecf9b27cac4c1fee3431a413f7aa00be7c4d7bbacc2c4d"}, - {file = "regex-2022.1.18-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:596f5ae2eeddb79b595583c2e0285312b2783b0ec759930c272dbf02f851ff75"}, - {file = "regex-2022.1.18-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ecfe51abf7f045e0b9cdde71ca9e153d11238679ef7b5da6c82093874adf3338"}, - {file = "regex-2022.1.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1d6301f5288e9bdca65fab3de6b7de17362c5016d6bf8ee4ba4cbe833b2eda0f"}, - {file = "regex-2022.1.18-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:93cce7d422a0093cfb3606beae38a8e47a25232eea0f292c878af580a9dc7605"}, - {file = "regex-2022.1.18-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cf0db26a1f76aa6b3aa314a74b8facd586b7a5457d05b64f8082a62c9c49582a"}, - {file = "regex-2022.1.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:defa0652696ff0ba48c8aff5a1fac1eef1ca6ac9c660b047fc8e7623c4eb5093"}, - {file = "regex-2022.1.18-cp39-cp39-win32.whl", hash = "sha256:6db1b52c6f2c04fafc8da17ea506608e6be7086715dab498570c3e55e4f8fbd1"}, - {file = "regex-2022.1.18-cp39-cp39-win_amd64.whl", hash = "sha256:ebaeb93f90c0903233b11ce913a7cb8f6ee069158406e056f884854c737d2442"}, - {file = "regex-2022.1.18.tar.gz", hash = "sha256:97f32dc03a8054a4c4a5ab5d761ed4861e828b2c200febd4e46857069a483916"}, -] -requests = [ - {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, - {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, + {file = "regex-2022.3.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:42eb13b93765c6698a5ab3bcd318d8c39bb42e5fa8a7fcf7d8d98923f3babdb1"}, + {file = "regex-2022.3.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9beb03ff6fe509d6455971c2489dceb31687b38781206bcec8e68bdfcf5f1db2"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0a5a1fdc9f148a8827d55b05425801acebeeefc9e86065c7ac8b8cc740a91ff"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb374a2a4dba7c4be0b19dc7b1adc50e6c2c26c3369ac629f50f3c198f3743a4"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c33ce0c665dd325200209340a88438ba7a470bd5f09f7424e520e1a3ff835b52"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04c09b9651fa814eeeb38e029dc1ae83149203e4eeb94e52bb868fadf64852bc"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab5d89cfaf71807da93c131bb7a19c3e19eaefd613d14f3bce4e97de830b15df"}, + {file = "regex-2022.3.15-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e2630ae470d6a9f8e4967388c1eda4762706f5750ecf387785e0df63a4cc5af"}, + {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:df037c01d68d1958dad3463e2881d3638a0d6693483f58ad41001aa53a83fcea"}, + {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:940570c1a305bac10e8b2bc934b85a7709c649317dd16520471e85660275083a"}, + {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7f63877c87552992894ea1444378b9c3a1d80819880ae226bb30b04789c0828c"}, + {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:3e265b388cc80c7c9c01bb4f26c9e536c40b2c05b7231fbb347381a2e1c8bf43"}, + {file = "regex-2022.3.15-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:058054c7a54428d5c3e3739ac1e363dc9347d15e64833817797dc4f01fb94bb8"}, + {file = "regex-2022.3.15-cp310-cp310-win32.whl", hash = "sha256:76435a92e444e5b8f346aed76801db1c1e5176c4c7e17daba074fbb46cb8d783"}, + {file = "regex-2022.3.15-cp310-cp310-win_amd64.whl", hash = "sha256:174d964bc683b1e8b0970e1325f75e6242786a92a22cedb2a6ec3e4ae25358bd"}, + {file = "regex-2022.3.15-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6e1d8ed9e61f37881c8db383a124829a6e8114a69bd3377a25aecaeb9b3538f8"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b52771f05cff7517f7067fef19ffe545b1f05959e440d42247a17cd9bddae11b"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:673f5a393d603c34477dbad70db30025ccd23996a2d0916e942aac91cc42b31a"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8923e1c5231549fee78ff9b2914fad25f2e3517572bb34bfaa3aea682a758683"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:764e66a0e382829f6ad3bbce0987153080a511c19eb3d2f8ead3f766d14433ac"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd00859291658fe1fda48a99559fb34da891c50385b0bfb35b808f98956ef1e7"}, + {file = "regex-2022.3.15-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aa2ce79f3889720b46e0aaba338148a1069aea55fda2c29e0626b4db20d9fcb7"}, + {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:34bb30c095342797608727baf5c8aa122406aa5edfa12107b8e08eb432d4c5d7"}, + {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:25ecb1dffc5e409ca42f01a2b2437f93024ff1612c1e7983bad9ee191a5e8828"}, + {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:aa5eedfc2461c16a092a2fabc5895f159915f25731740c9152a1b00f4bcf629a"}, + {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:7d1a6e403ac8f1d91d8f51c441c3f99367488ed822bda2b40836690d5d0059f5"}, + {file = "regex-2022.3.15-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:3e4d710ff6539026e49f15a3797c6b1053573c2b65210373ef0eec24480b900b"}, + {file = "regex-2022.3.15-cp36-cp36m-win32.whl", hash = "sha256:0100f0ded953b6b17f18207907159ba9be3159649ad2d9b15535a74de70359d3"}, + {file = "regex-2022.3.15-cp36-cp36m-win_amd64.whl", hash = "sha256:f320c070dea3f20c11213e56dbbd7294c05743417cde01392148964b7bc2d31a"}, + {file = "regex-2022.3.15-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fc8c7958d14e8270171b3d72792b609c057ec0fa17d507729835b5cff6b7f69a"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ca6dcd17f537e9f3793cdde20ac6076af51b2bd8ad5fe69fa54373b17b48d3c"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0214ff6dff1b5a4b4740cfe6e47f2c4c92ba2938fca7abbea1359036305c132f"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a98ae493e4e80b3ded6503ff087a8492db058e9c68de371ac3df78e88360b374"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b1cc70e31aacc152a12b39245974c8fccf313187eead559ee5966d50e1b5817"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4829db3737480a9d5bfb1c0320c4ee13736f555f53a056aacc874f140e98f64"}, + {file = "regex-2022.3.15-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:303b15a3d32bf5fe5a73288c316bac5807587f193ceee4eb6d96ee38663789fa"}, + {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:dc7b7c16a519d924c50876fb152af661a20749dcbf653c8759e715c1a7a95b18"}, + {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ce3057777a14a9a1399b81eca6a6bfc9612047811234398b84c54aeff6d536ea"}, + {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:48081b6bff550fe10bcc20c01cf6c83dbca2ccf74eeacbfac240264775fd7ecf"}, + {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dcbb7665a9db9f8d7642171152c45da60e16c4f706191d66a1dc47ec9f820aed"}, + {file = "regex-2022.3.15-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c155a1a80c5e7a8fa1d9bb1bf3c8a953532b53ab1196092749bafb9d3a7cbb60"}, + {file = "regex-2022.3.15-cp37-cp37m-win32.whl", hash = "sha256:04b5ee2b6d29b4a99d38a6469aa1db65bb79d283186e8460542c517da195a8f6"}, + {file = "regex-2022.3.15-cp37-cp37m-win_amd64.whl", hash = "sha256:797437e6024dc1589163675ae82f303103063a0a580c6fd8d0b9a0a6708da29e"}, + {file = "regex-2022.3.15-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8afcd1c2297bc989dceaa0379ba15a6df16da69493635e53431d2d0c30356086"}, + {file = "regex-2022.3.15-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0066a6631c92774391f2ea0f90268f0d82fffe39cb946f0f9c6b382a1c61a5e5"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8248f19a878c72d8c0a785a2cd45d69432e443c9f10ab924c29adda77b324ae"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d1f3ea0d1924feb4cf6afb2699259f658a08ac6f8f3a4a806661c2dfcd66db1"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:794a6bc66c43db8ed06698fc32aaeaac5c4812d9f825e9589e56f311da7becd9"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d1445824944e642ffa54c4f512da17a953699c563a356d8b8cbdad26d3b7598"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f553a1190ae6cd26e553a79f6b6cfba7b8f304da2071052fa33469da075ea625"}, + {file = "regex-2022.3.15-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:75a5e6ce18982f0713c4bac0704bf3f65eed9b277edd3fb9d2b0ff1815943327"}, + {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f16cf7e4e1bf88fecf7f41da4061f181a6170e179d956420f84e700fb8a3fd6b"}, + {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dad3991f0678facca1a0831ec1ddece2eb4d1dd0f5150acb9440f73a3b863907"}, + {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:491fc754428514750ab21c2d294486223ce7385446f2c2f5df87ddbed32979ae"}, + {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:6504c22c173bb74075d7479852356bb7ca80e28c8e548d4d630a104f231e04fb"}, + {file = "regex-2022.3.15-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:01c913cf573d1da0b34c9001a94977273b5ee2fe4cb222a5d5b320f3a9d1a835"}, + {file = "regex-2022.3.15-cp38-cp38-win32.whl", hash = "sha256:029e9e7e0d4d7c3446aa92474cbb07dafb0b2ef1d5ca8365f059998c010600e6"}, + {file = "regex-2022.3.15-cp38-cp38-win_amd64.whl", hash = "sha256:947a8525c0a95ba8dc873191f9017d1b1e3024d4dc757f694e0af3026e34044a"}, + {file = "regex-2022.3.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:591d4fba554f24bfa0421ba040cd199210a24301f923ed4b628e1e15a1001ff4"}, + {file = "regex-2022.3.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9809404528a999cf02a400ee5677c81959bc5cb938fdc696b62eb40214e3632"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f08a7e4d62ea2a45557f561eea87c907222575ca2134180b6974f8ac81e24f06"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a86cac984da35377ca9ac5e2e0589bd11b3aebb61801204bd99c41fac516f0d"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:286908cbe86b1a0240a867aecfe26a439b16a1f585d2de133540549831f8e774"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b7494df3fdcc95a1f76cf134d00b54962dd83189520fd35b8fcd474c0aa616d"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b1ceede92400b3acfebc1425937454aaf2c62cd5261a3fabd560c61e74f6da3"}, + {file = "regex-2022.3.15-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0317eb6331146c524751354ebef76a7a531853d7207a4d760dfb5f553137a2a4"}, + {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9c144405220c5ad3f5deab4c77f3e80d52e83804a6b48b6bed3d81a9a0238e4c"}, + {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:5b2e24f3ae03af3d8e8e6d824c891fea0ca9035c5d06ac194a2700373861a15c"}, + {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f2c53f3af011393ab5ed9ab640fa0876757498aac188f782a0c620e33faa2a3d"}, + {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:060f9066d2177905203516c62c8ea0066c16c7342971d54204d4e51b13dfbe2e"}, + {file = "regex-2022.3.15-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:530a3a16e57bd3ea0dff5ec2695c09632c9d6c549f5869d6cf639f5f7153fb9c"}, + {file = "regex-2022.3.15-cp39-cp39-win32.whl", hash = "sha256:78ce90c50d0ec970bd0002462430e00d1ecfd1255218d52d08b3a143fe4bde18"}, + {file = "regex-2022.3.15-cp39-cp39-win_amd64.whl", hash = "sha256:c5adc854764732dbd95a713f2e6c3e914e17f2ccdc331b9ecb777484c31f73b6"}, + {file = "regex-2022.3.15.tar.gz", hash = "sha256:0a7b75cc7bb4cc0334380053e4671c560e31272c9d2d5a6c4b8e9ae2c9bd0f82"}, ] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, @@ -942,41 +873,42 @@ tomli = [ {file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"}, ] tox = [ - {file = "tox-3.24.5-py2.py3-none-any.whl", hash = "sha256:be3362472a33094bce26727f5f771ca0facf6dafa217f65875314e9a6600c95c"}, - {file = "tox-3.24.5.tar.gz", hash = "sha256:67e0e32c90e278251fea45b696d0fef3879089ccbe979b0c556d35d5a70e2993"}, + {file = "tox-3.25.0-py2.py3-none-any.whl", hash = "sha256:0805727eb4d6b049de304977dfc9ce315a1938e6619c3ab9f38682bb04662a5a"}, + {file = "tox-3.25.0.tar.gz", hash = "sha256:37888f3092aa4e9f835fc8cc6dadbaaa0782651c41ef359e3a5743fcb0308160"}, ] typed-ast = [ - {file = "typed_ast-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d8314c92414ce7481eee7ad42b353943679cf6f30237b5ecbf7d835519e1212"}, - {file = "typed_ast-1.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b53ae5de5500529c76225d18eeb060efbcec90ad5e030713fe8dab0fb4531631"}, - {file = "typed_ast-1.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:24058827d8f5d633f97223f5148a7d22628099a3d2efe06654ce872f46f07cdb"}, - {file = "typed_ast-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:a6d495c1ef572519a7bac9534dbf6d94c40e5b6a608ef41136133377bba4aa08"}, - {file = "typed_ast-1.5.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:de4ecae89c7d8b56169473e08f6bfd2df7f95015591f43126e4ea7865928677e"}, - {file = "typed_ast-1.5.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:256115a5bc7ea9e665c6314ed6671ee2c08ca380f9d5f130bd4d2c1f5848d695"}, - {file = "typed_ast-1.5.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7c42707ab981b6cf4b73490c16e9d17fcd5227039720ca14abe415d39a173a30"}, - {file = "typed_ast-1.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:71dcda943a471d826ea930dd449ac7e76db7be778fcd722deb63642bab32ea3f"}, - {file = "typed_ast-1.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4f30a2bcd8e68adbb791ce1567fdb897357506f7ea6716f6bbdd3053ac4d9471"}, - {file = "typed_ast-1.5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ca9e8300d8ba0b66d140820cf463438c8e7b4cdc6fd710c059bfcfb1531d03fb"}, - {file = "typed_ast-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9caaf2b440efb39ecbc45e2fabde809cbe56272719131a6318fd9bf08b58e2cb"}, - {file = "typed_ast-1.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c9bcad65d66d594bffab8575f39420fe0ee96f66e23c4d927ebb4e24354ec1af"}, - {file = "typed_ast-1.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:591bc04e507595887160ed7aa8d6785867fb86c5793911be79ccede61ae96f4d"}, - {file = "typed_ast-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:a80d84f535642420dd17e16ae25bb46c7f4c16ee231105e7f3eb43976a89670a"}, - {file = "typed_ast-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:38cf5c642fa808300bae1281460d4f9b7617cf864d4e383054a5ef336e344d32"}, - {file = "typed_ast-1.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b6ab14c56bc9c7e3c30228a0a0b54b915b1579613f6e463ba6f4eb1382e7fd4"}, - {file = "typed_ast-1.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2b8d7007f6280e36fa42652df47087ac7b0a7d7f09f9468f07792ba646aac2d"}, - {file = "typed_ast-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:b6d17f37f6edd879141e64a5db17b67488cfeffeedad8c5cec0392305e9bc775"}, - {file = "typed_ast-1.5.1.tar.gz", hash = "sha256:484137cab8ecf47e137260daa20bafbba5f4e3ec7fda1c1e69ab299b75fa81c5"}, + {file = "typed_ast-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:183b183b7771a508395d2cbffd6db67d6ad52958a5fdc99f450d954003900266"}, + {file = "typed_ast-1.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:676d051b1da67a852c0447621fdd11c4e104827417bf216092ec3e286f7da596"}, + {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc2542e83ac8399752bc16e0b35e038bdb659ba237f4222616b4e83fb9654985"}, + {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74cac86cc586db8dfda0ce65d8bcd2bf17b58668dfcc3652762f3ef0e6677e76"}, + {file = "typed_ast-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:18fe320f354d6f9ad3147859b6e16649a0781425268c4dde596093177660e71a"}, + {file = "typed_ast-1.5.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:31d8c6b2df19a777bc8826770b872a45a1f30cfefcfd729491baa5237faae837"}, + {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:963a0ccc9a4188524e6e6d39b12c9ca24cc2d45a71cfdd04a26d883c922b4b78"}, + {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0eb77764ea470f14fcbb89d51bc6bbf5e7623446ac4ed06cbd9ca9495b62e36e"}, + {file = "typed_ast-1.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:294a6903a4d087db805a7656989f613371915fc45c8cc0ddc5c5a0a8ad9bea4d"}, + {file = "typed_ast-1.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:26a432dc219c6b6f38be20a958cbe1abffcc5492821d7e27f08606ef99e0dffd"}, + {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7407cfcad702f0b6c0e0f3e7ab876cd1d2c13b14ce770e412c0c4b9728a0f88"}, + {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f30ddd110634c2d7534b2d4e0e22967e88366b0d356b24de87419cc4410c41b7"}, + {file = "typed_ast-1.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:8c08d6625bb258179b6e512f55ad20f9dfef019bbfbe3095247401e053a3ea30"}, + {file = "typed_ast-1.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:90904d889ab8e81a956f2c0935a523cc4e077c7847a836abee832f868d5c26a4"}, + {file = "typed_ast-1.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bbebc31bf11762b63bf61aaae232becb41c5bf6b3461b80a4df7e791fabb3aca"}, + {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29dd9a3a9d259c9fa19d19738d021632d673f6ed9b35a739f48e5f807f264fb"}, + {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:58ae097a325e9bb7a684572d20eb3e1809802c5c9ec7108e85da1eb6c1a3331b"}, + {file = "typed_ast-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:da0a98d458010bf4fe535f2d1e367a2e2060e105978873c04c04212fb20543f7"}, + {file = "typed_ast-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:33b4a19ddc9fc551ebabca9765d54d04600c4a50eda13893dadf67ed81d9a098"}, + {file = "typed_ast-1.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1098df9a0592dd4c8c0ccfc2e98931278a6c6c53cb3a3e2cf7e9ee3b06153344"}, + {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42c47c3b43fe3a39ddf8de1d40dbbfca60ac8530a36c9b198ea5b9efac75c09e"}, + {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f290617f74a610849bd8f5514e34ae3d09eafd521dceaa6cf68b3f4414266d4e"}, + {file = "typed_ast-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:df05aa5b241e2e8045f5f4367a9f6187b09c4cdf8578bb219861c4e27c443db5"}, + {file = "typed_ast-1.5.2.tar.gz", hash = "sha256:525a2d4088e70a9f75b08b3f87a51acc9cde640e19cc523c7e41aa355564ae27"}, ] typing-extensions = [ - {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, - {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, -] -urllib3 = [ - {file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"}, - {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, + {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, + {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, ] virtualenv = [ - {file = "virtualenv-20.13.0-py2.py3-none-any.whl", hash = "sha256:339f16c4a86b44240ba7223d0f93a7887c3ca04b5f9c8129da7958447d079b09"}, - {file = "virtualenv-20.13.0.tar.gz", hash = "sha256:d8458cf8d59d0ea495ad9b34c2599487f8a7772d796f9910858376d1600dd2dd"}, + {file = "virtualenv-20.14.1-py2.py3-none-any.whl", hash = "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a"}, + {file = "virtualenv-20.14.1.tar.gz", hash = "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"}, ] zipp = [ {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, diff --git a/pyproject.toml b/pyproject.toml index 27ed559..d573d19 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "graphql-relay" -version = "3.1.2" +version = "3.2.0" description = """ Relay library for graphql-core""" license="MIT" @@ -42,24 +42,24 @@ packages = [ [tool.poetry.dependencies] python = "^3.6" -graphql-core = "~3.1" -typing-extensions = { version = "^4.0", python = "<3.8" } +graphql-core = "~3.2" +typing-extensions = { version = "^4.1", python = "<3.8" } [tool.poetry.dev-dependencies] pytest = "^6.2" pytest-asyncio = [ - {version=">=0.17,<1", python = ">=3.7" }, + {version=">=0.18,<1", python = ">=3.7" }, {version=">=0.16,<0.17", python = "<3.7" }, ] pytest-cov = "^3.0" pytest-describe = "^2.0" black = [ - {version = "21.12b0", python = ">=3.6.2"}, + {version = "22.3.0", python = ">=3.6.2"}, {version = "20.8b1", python = "<3.6.2"} ] flake8 = "^4.0" -mypy = "0.931" -check-manifest = ">=0.47,<1" +mypy = "0.942" +check-manifest = ">=0.48,<1" bump2version = ">=1.0,<2" tox = "^3.24" diff --git a/setup.cfg b/setup.cfg index 47cbe3a..7a9470a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,10 +4,6 @@ python-tag = py3 [aliases] test = pytest -[check-manifest] -ignore = - .pyup.yml - [tool:pytest] # Deactivate default name pattern for test classes (we use pytest_describe). python_classes = PyTest* diff --git a/setup.py b/setup.py index f01e962..2fc5171 100644 --- a/setup.py +++ b/setup.py @@ -32,8 +32,8 @@ "Programming Language :: Python :: Implementation :: PyPy", ], install_requires=[ - "graphql-core>=3.1,<3.2", - "typing-extensions>=4,<5; python_version < '3.8'", + "graphql-core>=3.2,<3.3", + "typing-extensions>=4.1,<5; python_version < '3.8'", ], python_requires=">=3.6,<4", packages=find_packages("src"), diff --git a/src/graphql_relay/__init__.py b/src/graphql_relay/__init__.py index 8236d44..bab0672 100644 --- a/src/graphql_relay/__init__.py +++ b/src/graphql_relay/__init__.py @@ -9,12 +9,19 @@ connection_args, connection_definitions, forward_connection_args, + page_info_type, Connection, ConnectionArguments, + ConnectionConstructor, ConnectionCursor, + ConnectionType, Edge, + EdgeConstructor, + EdgeType, GraphQLConnectionDefinitions, PageInfo, + PageInfoConstructor, + PageInfoType, ) # Helpers for creating connections from arrays @@ -25,26 +32,25 @@ cursor_to_offset, get_offset_with_default, offset_to_cursor, + SizedSliceable, ) # Helper for creating mutations with client mutation IDs -from .mutation.mutation import mutation_with_client_mutation_id +from .mutation.mutation import ( + mutation_with_client_mutation_id, + MutationFn, + MutationFnWithoutArgs, + NullResult, +) # Helper for creating node definitions -from .node.node import node_definitions +from .node.node import node_definitions, GraphQLNodeDefinitions # Helper for creating plural identifying root fields from .node.plural import plural_identifying_root_field # Utilities for creating global IDs in systems that don't have them -from .node.node import from_global_id, global_id_field, to_global_id - -# Deprecated functions from older graphql-relay-py versions -# noinspection PyProtectedMember,PyUnresolvedReferences,PyDeprecation -from .connection.array_connection import ( # noqa: F401 - connection_from_list, - connection_from_list_slice, -) +from .node.node import from_global_id, global_id_field, to_global_id, ResolvedGlobalId __version__ = version __version_info__ = version_info @@ -52,30 +58,43 @@ __version_info_js__ = version_info_js __all__ = [ - "version", - "version_info", - "version_js", - "version_info_js", + "backward_connection_args", "Connection", "ConnectionArguments", + "ConnectionConstructor", "ConnectionCursor", - "Edge", - "PageInfo", - "backward_connection_args", + "ConnectionType", "connection_args", - "connection_definitions", - "forward_connection_args", - "GraphQLConnectionDefinitions", "connection_from_array", "connection_from_array_slice", + "connection_definitions", "cursor_for_object_in_connection", "cursor_to_offset", + "Edge", + "EdgeConstructor", + "EdgeType", + "forward_connection_args", + "from_global_id", "get_offset_with_default", - "offset_to_cursor", + "global_id_field", + "GraphQLConnectionDefinitions", + "GraphQLNodeDefinitions", + "MutationFn", + "MutationFnWithoutArgs", "mutation_with_client_mutation_id", "node_definitions", + "NullResult", + "offset_to_cursor", + "PageInfo", + "PageInfoConstructor", + "PageInfoType", + "page_info_type", "plural_identifying_root_field", - "from_global_id", - "global_id_field", + "ResolvedGlobalId", + "SizedSliceable", "to_global_id", + "version", + "version_info", + "version_js", + "version_info_js", ] diff --git a/src/graphql_relay/connection/array_connection.py b/src/graphql_relay/connection/array_connection.py index 5963ba0..f25cdce 100644 --- a/src/graphql_relay/connection/array_connection.py +++ b/src/graphql_relay/connection/array_connection.py @@ -1,4 +1,3 @@ -import warnings from typing import Any, Iterator, Optional, Sequence try: @@ -26,6 +25,7 @@ "cursor_to_offset", "get_offset_with_default", "offset_to_cursor", + "SizedSliceable", ] @@ -70,33 +70,6 @@ def connection_from_array( ) -def connection_from_list( - data: Sequence, - args: Optional[ConnectionArguments] = None, - connection_type: ConnectionConstructor = Connection, - edge_type: EdgeConstructor = Edge, - pageinfo_type: PageInfoConstructor = PageInfo, -) -> ConnectionType: - """Deprecated alias for connection_from_array. - - We're now using the JavaScript terminology in Python as well, since list - is too narrow a type and there is no other really appropriate type name. - """ - warnings.warn( - "connection_from_list() has been deprecated." - " Please use connection_from_array() instead.", - DeprecationWarning, - stacklevel=2, - ) - return connection_from_array_slice( - data, - args, - connection_type=connection_type, - edge_type=edge_type, - page_info_type=pageinfo_type, - ) - - def connection_from_array_slice( array_slice: SizedSliceable, args: Optional[ConnectionArguments] = None, @@ -182,39 +155,6 @@ def connection_from_array_slice( ) -def connection_from_list_slice( - list_slice: Sequence, - args: Optional[ConnectionArguments] = None, - connection_type: ConnectionConstructor = Connection, - edge_type: EdgeConstructor = Edge, - pageinfo_type: PageInfoConstructor = PageInfo, - slice_start: int = 0, - list_length: int = 0, - list_slice_length: Optional[int] = None, -) -> ConnectionType: - """Deprecated alias for connection_from_array_slice. - - We're now using the JavaScript terminology in Python as well, since list - is too narrow a type and there is no other really appropriate type name. - """ - warnings.warn( - "connection_from_list_slice() has been deprecated." - " Please use connection_from_array_slice() instead.", - DeprecationWarning, - stacklevel=2, - ) - return connection_from_array_slice( - list_slice, - args, - slice_start=slice_start, - array_length=list_length, - array_slice_length=list_slice_length, - connection_type=connection_type, - edge_type=edge_type, - page_info_type=pageinfo_type, - ) - - PREFIX = "arrayconnection:" diff --git a/src/graphql_relay/connection/arrayconnection.py b/src/graphql_relay/connection/arrayconnection.py new file mode 100644 index 0000000..efae32e --- /dev/null +++ b/src/graphql_relay/connection/arrayconnection.py @@ -0,0 +1,29 @@ +import warnings + +# noinspection PyDeprecation +from .array_connection import ( + connection_from_array, + connection_from_array_slice, + cursor_for_object_in_connection, + cursor_to_offset, + get_offset_with_default, + offset_to_cursor, + SizedSliceable, +) + +warnings.warn( + "The 'arrayconnection' module is deprecated. " + "Functions should be imported from the top-level package instead.", + DeprecationWarning, + stacklevel=2, +) + +__all__ = [ + "connection_from_array", + "connection_from_array_slice", + "cursor_for_object_in_connection", + "cursor_to_offset", + "get_offset_with_default", + "offset_to_cursor", + "SizedSliceable", +] diff --git a/src/graphql_relay/connection/connection.py b/src/graphql_relay/connection/connection.py index 2aec931..2058baa 100644 --- a/src/graphql_relay/connection/connection.py +++ b/src/graphql_relay/connection/connection.py @@ -2,37 +2,45 @@ from graphql import ( get_named_type, + resolve_thunk, GraphQLArgument, GraphQLArgumentMap, GraphQLBoolean, GraphQLField, - GraphQLFieldMap, GraphQLFieldResolver, GraphQLInt, GraphQLList, - GraphQLNamedOutputType, GraphQLNonNull, GraphQLObjectType, GraphQLString, - Thunk, + ThunkMapping, ) +from graphql import GraphQLNamedOutputType + try: from typing import Protocol except ImportError: # Python < 3.8 from typing_extensions import Protocol # type: ignore __all__ = [ - "connection_definitions", - "forward_connection_args", "backward_connection_args", "connection_args", + "connection_definitions", + "forward_connection_args", + "page_info_type", "Connection", "ConnectionArguments", + "ConnectionConstructor", "ConnectionCursor", + "ConnectionType", "Edge", + "EdgeConstructor", + "EdgeType", "GraphQLConnectionDefinitions", "PageInfo", + "PageInfoConstructor", + "PageInfoType", ] @@ -73,10 +81,6 @@ class GraphQLConnectionDefinitions(NamedTuple): connection_type: GraphQLObjectType -def resolve_maybe_thunk(thing_or_thunk: Thunk) -> Any: - return thing_or_thunk() if callable(thing_or_thunk) else thing_or_thunk - - """A type alias for cursors in this implementation.""" ConnectionCursor = str @@ -98,8 +102,8 @@ def connection_definitions( name: Optional[str] = None, resolve_node: Optional[GraphQLFieldResolver] = None, resolve_cursor: Optional[GraphQLFieldResolver] = None, - edge_fields: Optional[Thunk[GraphQLFieldMap]] = None, - connection_fields: Optional[Thunk[GraphQLFieldMap]] = None, + edge_fields: Optional[ThunkMapping[GraphQLField]] = None, + connection_fields: Optional[ThunkMapping[GraphQLField]] = None, ) -> GraphQLConnectionDefinitions: """Return GraphQLObjectTypes for a connection with the given name. @@ -121,7 +125,7 @@ def connection_definitions( resolve=resolve_cursor, description="A cursor for use in pagination", ), - **resolve_maybe_thunk(edge_fields or {}), + **resolve_thunk(edge_fields or {}), }, ) @@ -136,7 +140,7 @@ def connection_definitions( "edges": GraphQLField( GraphQLList(edge_type), description="A list of edges." ), - **resolve_maybe_thunk(connection_fields or {}), + **resolve_thunk(connection_fields or {}), }, ) diff --git a/src/graphql_relay/mutation/mutation.py b/src/graphql_relay/mutation/mutation.py index 615d7c0..f927bec 100644 --- a/src/graphql_relay/mutation/mutation.py +++ b/src/graphql_relay/mutation/mutation.py @@ -3,6 +3,7 @@ from typing import Any, Callable, Dict, Optional from graphql import ( + resolve_thunk, GraphQLArgument, GraphQLField, GraphQLFieldMap, @@ -13,10 +14,17 @@ GraphQLObjectType, GraphQLResolveInfo, GraphQLString, - Thunk, + ThunkMapping, ) from graphql.pyutils import AwaitableOrValue +__all__ = [ + "mutation_with_client_mutation_id", + "MutationFn", + "MutationFnWithoutArgs", + "NullResult", +] + # Note: Contrary to the Javascript implementation of MutationFn, # the context is passed as part of the GraphQLResolveInfo and any arguments # are passed individually as keyword arguments. @@ -26,10 +34,6 @@ MutationFn = Callable[..., AwaitableOrValue[Any]] -def resolve_maybe_thunk(thing_or_thunk: Thunk) -> Any: - return thing_or_thunk() if callable(thing_or_thunk) else thing_or_thunk - - class NullResult: def __init__(self, clientMutationId: Optional[str] = None) -> None: self.clientMutationId = clientMutationId @@ -37,8 +41,8 @@ def __init__(self, clientMutationId: Optional[str] = None) -> None: def mutation_with_client_mutation_id( name: str, - input_fields: Thunk[GraphQLInputFieldMap], - output_fields: Thunk[GraphQLFieldMap], + input_fields: ThunkMapping[GraphQLInputField], + output_fields: ThunkMapping[GraphQLField], mutate_and_get_payload: MutationFn, description: Optional[str] = None, deprecation_reason: Optional[str] = None, @@ -61,13 +65,13 @@ def mutation_with_client_mutation_id( def augmented_input_fields() -> GraphQLInputFieldMap: return dict( - resolve_maybe_thunk(input_fields), + resolve_thunk(input_fields), clientMutationId=GraphQLInputField(GraphQLString), ) def augmented_output_fields() -> GraphQLFieldMap: return dict( - resolve_maybe_thunk(output_fields), + resolve_thunk(output_fields), clientMutationId=GraphQLField(GraphQLString), ) diff --git a/src/graphql_relay/node/node.py b/src/graphql_relay/node/node.py index 408ca05..ad062a5 100644 --- a/src/graphql_relay/node/node.py +++ b/src/graphql_relay/node/node.py @@ -13,6 +13,15 @@ GraphQLTypeResolver, ) +__all__ = [ + "from_global_id", + "global_id_field", + "node_definitions", + "to_global_id", + "GraphQLNodeDefinitions", + "ResolvedGlobalId", +] + class GraphQLNodeDefinitions(NamedTuple): @@ -92,7 +101,10 @@ def from_global_id(global_id: str) -> ResolvedGlobalId: Takes the "global ID" created by to_global_id, and returns the type name and ID used to create it. """ - return ResolvedGlobalId(*unbase64(global_id).split(":", 1)) + global_id = unbase64(global_id) + if ":" not in global_id: + return ResolvedGlobalId("", global_id) + return ResolvedGlobalId(*global_id.split(":", 1)) def global_id_field( diff --git a/src/graphql_relay/node/plural.py b/src/graphql_relay/node/plural.py index 9b66243..870c37f 100644 --- a/src/graphql_relay/node/plural.py +++ b/src/graphql_relay/node/plural.py @@ -11,6 +11,8 @@ get_nullable_type, ) +__all__ = ["plural_identifying_root_field"] + def plural_identifying_root_field( arg_name: str, diff --git a/src/graphql_relay/version.py b/src/graphql_relay/version.py index 88e5068..1d53baa 100644 --- a/src/graphql_relay/version.py +++ b/src/graphql_relay/version.py @@ -3,9 +3,9 @@ __all__ = ["version", "version_info", "version_js", "version_info_js"] -version = "3.1.2" +version = "3.2.0" -version_js = "0.8.0" +version_js = "0.10.0" _re_version = re.compile(r"(\d+)\.(\d+)\.(\d+)(\D*)(\d*)") diff --git a/tests/connection/test_array_connection.py b/tests/connection/test_array_connection.py index 64683ff..33c89ee 100644 --- a/tests/connection/test_array_connection.py +++ b/tests/connection/test_array_connection.py @@ -12,10 +12,6 @@ PageInfo, ) -# noinspection PyProtectedMember -from graphql_relay import connection_from_list, connection_from_list_slice - - array_abcde = ["A", "B", "C", "D", "E"] cursor_a = "YXJyYXljb25uZWN0aW9uOjA=" @@ -32,6 +28,17 @@ def describe_connection_from_array(): + def warns_for_deprecated_import(): + from importlib import reload + + with deprecated_call(): + from graphql_relay.connection import arrayconnection as deprecated + + # noinspection PyDeprecation + reload(deprecated) + # noinspection PyDeprecation + assert deprecated.connection_from_array is connection_from_array + def describe_basic_slicing(): def returns_all_elements_without_filters(): c = connection_from_array(array_abcde, {}) @@ -251,10 +258,18 @@ def throws_an_error_if_last_smaller_than_zero(): ) def returns_all_elements_if_cursors_are_invalid(): - c = connection_from_array( - array_abcde, dict(before="invalid", after="invalid") + c1 = connection_from_array( + array_abcde, dict(before="InvalidBase64", after="InvalidBase64") ) - assert c == Connection( + + invalid_unicode_in_base64 = "9JCAgA==" # U+110000 + c2 = connection_from_array( + array_abcde, + dict(before=invalid_unicode_in_base64, after=invalid_unicode_in_base64), + ) + + assert c1 == c2 + assert c1 == Connection( edges=[edge_a, edge_b, edge_c, edge_d, edge_e], pageInfo=PageInfo( startCursor=cursor_a, @@ -443,28 +458,19 @@ def __init__( assert page_info.hasPreviousPage is False assert page_info.hasNextPage is False - def provides_deprecated_connection_from_list(): - with deprecated_call(): - # noinspection PyDeprecation - c = connection_from_list( - array_abcde[:1], - args={}, - connection_type=Connection, - edge_type=Edge, - pageinfo_type=PageInfo, - ) - assert c == Connection( - edges=[edge_a], - pageInfo=PageInfo( - startCursor=cursor_a, - endCursor=cursor_a, - hasPreviousPage=False, - hasNextPage=False, - ), - ) - def describe_connection_from_array_slice(): + def warns_for_deprecated_import(): + from importlib import reload + + with deprecated_call(): + from graphql_relay.connection import arrayconnection as deprecated + + # noinspection PyDeprecation + reload(deprecated) + # noinspection PyDeprecation + assert deprecated.connection_from_array_slice is connection_from_array_slice + def works_with_a_just_right_array_slice(): c = connection_from_array_slice( array_abcde[1:3], @@ -763,26 +769,3 @@ def __init__( assert page_info.endCursor == cursor_a assert page_info.hasPreviousPage is False assert page_info.hasNextPage is False - - def provides_deprecated_connection_from_list_slice(): - with deprecated_call(): - # noinspection PyDeprecation - c = connection_from_list_slice( - array_abcde[:1], - args={}, - connection_type=Connection, - edge_type=Edge, - pageinfo_type=PageInfo, - slice_start=0, - list_length=1, - list_slice_length=1, - ) - assert c == Connection( - edges=[edge_a], - pageInfo=PageInfo( - startCursor=cursor_a, - endCursor=cursor_a, - hasPreviousPage=False, - hasNextPage=False, - ), - ) diff --git a/tests/connection/test_connection.py b/tests/connection/test_connection.py index 13f4596..025cb2d 100644 --- a/tests/connection/test_connection.py +++ b/tests/connection/test_connection.py @@ -181,7 +181,7 @@ def works_with_backward_connection_args(): ) def generates_correct_types(): - assert print_schema(schema).rstrip() == dedent( + assert print_schema(schema) == dedent( ''' type Query { user: User diff --git a/tests/mutation/test_mutation.py b/tests/mutation/test_mutation.py index 0118a21..41792cb 100644 --- a/tests/mutation/test_mutation.py +++ b/tests/mutation/test_mutation.py @@ -4,6 +4,7 @@ graphql, graphql_sync, print_schema, + print_type, GraphQLField, GraphQLFieldMap, GraphQLInputField, @@ -131,7 +132,7 @@ async def supports_async_mutations(): ) def can_access_root_value(): - some_mutation = mutation_with_client_mutation_id( + some_mutation = mutation_with_client_mutation_id( # pragma: no cover "SomeMutation", {}, {"result": GraphQLField(GraphQLInt)}, @@ -139,18 +140,14 @@ def can_access_root_value(): info.root_value, clientMutationId ), ) - schema = wrap_in_schema({"someMutation": some_mutation}) - source = """ - mutation { - someMutation(input: {clientMutationId: "abc"}) { - result - clientMutationId - } + + wrapper_type = GraphQLObjectType("WrapperType", {"someMutation": some_mutation}) + assert print_type(wrapper_type) == dedent( + """ + type WrapperType { + someMutation(input: SomeMutationInput!): SomeMutationPayload } """ - assert graphql_sync(schema, source, root_value=1) == ( - {"someMutation": {"result": 1, "clientMutationId": "abc"}}, - None, ) def supports_mutations_returning_null(): @@ -301,7 +298,7 @@ def generates_correct_types(): schema = wrap_in_schema({"someMutation": some_mutation}) - assert print_schema(schema).rstrip() == dedent( + assert print_schema(schema) == dedent( ''' type Query { dummy: Int diff --git a/tests/node/test_global.py b/tests/node/test_global.py index 8c86359..bbf6b3a 100644 --- a/tests/node/test_global.py +++ b/tests/node/test_global.py @@ -68,14 +68,14 @@ def get_node(global_id: str, info: GraphQLResolveInfo) -> Any: def get_node_type( obj: Any, info: GraphQLResolveInfo, _type: Any - ) -> Optional[GraphQLObjectType]: + ) -> Optional[str]: assert info.schema is schema if "name" in obj: - return user_type + return user_type.name if "photo_id" in obj: - return photo_type + return photo_type.name if "text" in obj: - return post_type + return post_type.name return None # pragma: no cover else: @@ -93,14 +93,14 @@ def get_node(global_id: str, info: GraphQLResolveInfo) -> Any: def get_node_type( obj: Any, info: GraphQLResolveInfo, _type: Any - ) -> Optional[GraphQLObjectType]: + ) -> Optional[str]: assert info.schema is schema if isinstance(obj, User): - return user_type + return user_type.name if isinstance(obj, Photo): - return photo_type + return photo_type.name if isinstance(obj, Post): - return post_type + return post_type.name return None # pragma: no cover node_interface, node_field = node_definitions(get_node, get_node_type)[:2] @@ -202,3 +202,15 @@ def allows_to_refetch_the_ids(schema): }, None, ) + + def handles_valid_global_ids(): + assert from_global_id("Zm9v") == ("", "foo") + assert from_global_id(b"Zm9v") == ("", "foo") # type: ignore + assert from_global_id("Zm9vOmJhcg==") == ("foo", "bar") + assert from_global_id(b"Zm9vOmJhcg==") == ("foo", "bar") # type: ignore + + def handles_invalid_global_ids(): + assert from_global_id("") == ("", "") + assert from_global_id("Og==") == ("", "") + assert from_global_id("bad!") == ("", "") + assert from_global_id("invalid") == ("", "") diff --git a/tests/node/test_node.py b/tests/node/test_node.py index a481ec4..bec195f 100644 --- a/tests/node/test_node.py +++ b/tests/node/test_node.py @@ -47,12 +47,12 @@ def get_node(id_: str, info: GraphQLResolveInfo) -> Optional[Union[User, Photo]] def get_node_type( obj: Union[User, Photo], info: GraphQLResolveInfo, _type: Any -) -> Optional[GraphQLObjectType]: +) -> Optional[str]: assert info.schema is schema if obj in user_data: - return user_type + return user_type.name if obj in photo_data: - return photo_type + return photo_type.name return None # pragma: no cover @@ -193,7 +193,7 @@ def returns_nulls_for_bad_ids(): ) def generates_correct_types(): - assert print_schema(schema).rstrip() == dedent( + assert print_schema(schema) == dedent( ''' """An object with an ID""" interface Node { diff --git a/tests/node/test_node_async.py b/tests/node/test_node_async.py index 7f14ff0..5c5c571 100644 --- a/tests/node/test_node_async.py +++ b/tests/node/test_node_async.py @@ -26,7 +26,7 @@ class User(NamedTuple): node_interface, node_field = node_definitions( lambda id_, _info: next(filter(lambda obj: obj.id == id_, user_data), None), - lambda _obj, _info, _type: user_type, + lambda _obj, _info, _type: user_type.name, )[:2] diff --git a/tests/node/test_plural.py b/tests/node/test_plural.py index 1336321..f16c098 100644 --- a/tests/node/test_plural.py +++ b/tests/node/test_plural.py @@ -87,7 +87,7 @@ def allows_fetching(): ) def generates_correct_types(): - assert print_schema(schema).rstrip() == dedent( + assert print_schema(schema) == dedent( ''' type Query { """Map from a username to the user""" diff --git a/tests/star_wars_schema.py b/tests/star_wars_schema.py index 2de454a..73b9aaa 100644 --- a/tests/star_wars_schema.py +++ b/tests/star_wars_schema.py @@ -110,8 +110,8 @@ def get_node(global_id, _info): def get_node_type(obj, _info, _type): if isinstance(obj, Faction): - return factionType - return shipType + return faction_type.name + return ship_type.name node_interface, node_field = node_definitions(get_node, get_node_type)[:2] @@ -124,7 +124,7 @@ def get_node_type(obj, _info, _type): # id: String! # name: String # } -shipType = GraphQLObjectType( +ship_type = GraphQLObjectType( name="Ship", description="A ship in the Star Wars saga", fields=lambda: { @@ -148,7 +148,7 @@ def get_node_type(obj, _info, _type): # cursor: String! # node: Ship # } -ship_edge, ship_connection = connection_definitions(shipType, "Ship") +ship_edge, ship_connection = connection_definitions(ship_type, "Ship") # We define our faction type, which implements the node interface. # @@ -158,7 +158,7 @@ def get_node_type(obj, _info, _type): # name: String # ships: ShipConnection # } -factionType = GraphQLObjectType( +faction_type = GraphQLObjectType( name="Faction", description="A faction in the Star Wars saga", fields=lambda: { @@ -185,11 +185,11 @@ def get_node_type(obj, _info, _type): # empire: Faction # node(id: String!): Node # } -queryType = GraphQLObjectType( +query_type = GraphQLObjectType( name="Query", fields=lambda: { - "rebels": GraphQLField(factionType, resolve=lambda _obj, _info: get_rebels()), - "empire": GraphQLField(factionType, resolve=lambda _obj, _info: get_empire()), + "rebels": GraphQLField(faction_type, resolve=lambda _obj, _info: get_rebels()), + "empire": GraphQLField(faction_type, resolve=lambda _obj, _info: get_empire()), "node": node_field, }, ) @@ -226,7 +226,7 @@ def mutate_and_get_payload(_info, shipName, factionId, **_input): return IntroduceShipMutation(shipId=new_ship.id, factionId=factionId) -shipMutation = mutation_with_client_mutation_id( +ship_mutation = mutation_with_client_mutation_id( "IntroduceShip", input_fields={ "shipName": GraphQLInputField(GraphQLNonNull(GraphQLString)), @@ -234,10 +234,10 @@ def mutate_and_get_payload(_info, shipName, factionId, **_input): }, output_fields={ "ship": GraphQLField( - shipType, resolve=lambda payload, _info: get_ship(payload.shipId) + ship_type, resolve=lambda payload, _info: get_ship(payload.shipId) ), "faction": GraphQLField( - factionType, resolve=lambda payload, _info: get_faction(payload.factionId) + faction_type, resolve=lambda payload, _info: get_faction(payload.factionId) ), }, mutate_and_get_payload=mutate_and_get_payload, @@ -250,10 +250,10 @@ def mutate_and_get_payload(_info, shipName, factionId, **_input): # type Mutation { # introduceShip(input IntroduceShipInput!): IntroduceShipPayload # } -mutationType = GraphQLObjectType( - "Mutation", fields=lambda: {"introduceShip": shipMutation} +mutation_type = GraphQLObjectType( + "Mutation", fields=lambda: {"introduceShip": ship_mutation} ) # Finally, we construct our schema (whose starting query type is the query # type we defined above) and export it. -StarWarsSchema = GraphQLSchema(query=queryType, mutation=mutationType) +star_wars_schema = GraphQLSchema(query=query_type, mutation=mutation_type) diff --git a/tests/test_star_wars_connections.py b/tests/test_star_wars_connections.py index 6510c8c..f4dd855 100644 --- a/tests/test_star_wars_connections.py +++ b/tests/test_star_wars_connections.py @@ -1,6 +1,6 @@ from graphql import graphql_sync -from .star_wars_schema import StarWarsSchema as schema +from .star_wars_schema import star_wars_schema as schema def describe_star_wars_connections(): diff --git a/tests/test_star_wars_mutations.py b/tests/test_star_wars_mutations.py index cc00ea2..46daec3 100644 --- a/tests/test_star_wars_mutations.py +++ b/tests/test_star_wars_mutations.py @@ -1,6 +1,6 @@ from graphql import graphql_sync -from .star_wars_schema import StarWarsSchema as schema +from .star_wars_schema import star_wars_schema as schema def describe_star_wars_mutations(): diff --git a/tests/test_star_wars_object_identification.py b/tests/test_star_wars_object_identification.py index 5fabeda..9aa5e8d 100644 --- a/tests/test_star_wars_object_identification.py +++ b/tests/test_star_wars_object_identification.py @@ -1,6 +1,6 @@ from graphql import graphql_sync -from .star_wars_schema import StarWarsSchema as schema +from .star_wars_schema import star_wars_schema as schema def describe_star_wars_object_identification(): diff --git a/tox.ini b/tox.ini index 8f63b4e..07d445a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py3{6,7,8,9,10}, black, flake8, mypy, manifest +envlist = py3{6,7,8,9,10}, black, flake8, mypy, manifest, core320 isolated_build = true [gh-actions] @@ -12,7 +12,7 @@ python = [testenv:black] basepython = python3.9 -deps = black==21.12b0 +deps = black==22.3.0 commands = black src tests setup.py -t py39 --check @@ -25,23 +25,33 @@ commands = [testenv:mypy] basepython = python3.9 deps = - mypy==0.931 + mypy==0.942 pytest>=6.2,<7 commands = mypy src tests [testenv:manifest] basepython = python3.9 -deps = check-manifest>=0.47,<1 +deps = check-manifest>=0.48,<1 commands = check-manifest -v +[testenv:core320] +basepython = python3.9 +deps = + graphql-core==3.2.0 + pytest>=6.2,<7 + pytest-asyncio>=0.16,<1 + pytest-describe>=2,<3 +commands = + pytest tests {posargs} + [testenv] deps = pytest>=6.2,<7 pytest-asyncio>=0.16,<1 pytest-cov>=3,<4 pytest-describe>=2,<3 - py36,py37: typing-extensions>=4,<5 + py36,py37: typing-extensions>=4.1,<5 commands = pytest tests {posargs: --cov-report=term-missing --cov=graphql_relay --cov=tests --cov-fail-under=100}