From afa44e8a5f3d761a932221b15dc7103dcbdb54db Mon Sep 17 00:00:00 2001 From: Thomas Leonard <64223923+tcleonard@users.noreply.github.com> Date: Thu, 22 Apr 2021 22:27:14 -0500 Subject: [PATCH 1/6] Propagate arguments of relay.NodeField to Field (#1036) (#1307) * Propagate name, deprecation_reason arguments of relay.NodeField to Field * Allow custom description in Node.Field and move ID description to ID argument * Add test for Node.Field with custom name * Add tests for description, deprecation_reason arguments of NodeField * Pass all kwargs from NodeField to Field Co-authored-by: Theodore Diamantidis --- graphene/relay/node.py | 6 +++--- graphene/relay/tests/test_node.py | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/graphene/relay/node.py b/graphene/relay/node.py index d9c4c0f6c..4b324a93a 100644 --- a/graphene/relay/node.py +++ b/graphene/relay/node.py @@ -48,7 +48,7 @@ def get_resolver(self, parent_resolver): class NodeField(Field): - def __init__(self, node, type=False, deprecation_reason=None, name=None, **kwargs): + def __init__(self, node, type=False, **kwargs): assert issubclass(node, Node), "NodeField can only operate in Nodes" self.node_type = node self.field_type = type @@ -57,8 +57,8 @@ def __init__(self, node, type=False, deprecation_reason=None, name=None, **kwarg # If we don's specify a type, the field type will be the node # interface type or node, - description="The ID of the object", - id=ID(required=True), + id=ID(required=True, description="The ID of the object"), + **kwargs ) def get_resolver(self, parent_resolver): diff --git a/graphene/relay/tests/test_node.py b/graphene/relay/tests/test_node.py index fbce1d547..a0f406086 100644 --- a/graphene/relay/tests/test_node.py +++ b/graphene/relay/tests/test_node.py @@ -110,6 +110,17 @@ def test_node_field_custom(): assert node_field.node_type == Node +def test_node_field_args(): + field_args = { + "name": "my_custom_name", + "description": "my_custom_description", + "deprecation_reason": "my_custom_deprecation_reason", + } + node_field = Node.Field(**field_args) + for field_arg, value in field_args.items(): + assert getattr(node_field, field_arg) == value + + def test_node_field_only_type(): executed = schema.execute( '{ onlyNode(id:"%s") { __typename, name } } ' % Node.to_global_id("MyNode", 1) From 46bb1202e497b4b5db7e91f2916f45bb22cebb1f Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Fri, 16 Jul 2021 16:56:15 +0100 Subject: [PATCH 2/6] Add github actions to run linting and tests (#1349) --- .github/workflows/deploy.yml | 26 ++++++++++++++++++ .github/workflows/lint.yml | 26 ++++++++++++++++++ .github/workflows/tests.yml | 26 ++++++++++++++++++ .pre-commit-config.yaml | 4 +-- graphene/relay/tests/test_connection_query.py | 6 ++--- graphene/types/mutation.py | 2 +- graphene/types/tests/test_query.py | 2 +- setup.py | 3 +++ tests_asyncio/test_relay_connection.py | 6 ++--- tox.ini | 27 +++++++++++-------- 10 files changed, 107 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/deploy.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 000000000..07c0766f8 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,26 @@ +name: 🚀 Deploy to PyPI + +on: + push: + tags: + - 'v*' + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.9 + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - name: Build wheel and source tarball + run: | + pip install wheel + python setup.py sdist bdist_wheel + - name: Publish a Python distribution to PyPI + uses: pypa/gh-action-pypi-publish@v1.1.0 + with: + user: __token__ + password: ${{ secrets.pypi_password }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 000000000..a137a6177 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,26 @@ +name: Lint + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.9 + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox + - name: Run lint 💅 + run: tox + env: + TOXENV: pre-commit + - name: Run mypy + run: tox + env: + TOXENV: mypy diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..5d2973ced --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,26 @@ +name: Tests + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: ["2.7", "3.6", "3.7", "3.8", "3.9"] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox tox-gh-actions + - name: Test with tox + run: tox + env: + TOXENV: ${{ matrix.toxenv }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 93ab2e6d9..d49badef2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,11 +18,11 @@ repos: hooks: - id: pyupgrade - repo: https://github.com/ambv/black - rev: 18.9b0 + rev: 21.6b0 hooks: - id: black language_version: python3 - repo: https://github.com/PyCQA/flake8 - rev: 3.7.7 + rev: 3.9.2 hooks: - id: flake8 diff --git a/graphene/relay/tests/test_connection_query.py b/graphene/relay/tests/test_connection_query.py index be6ee8c74..2e7a1531e 100644 --- a/graphene/relay/tests/test_connection_query.py +++ b/graphene/relay/tests/test_connection_query.py @@ -54,10 +54,10 @@ def resolve_connection_letters(self, info, **args): def edges(selected_letters): return [ { - "node": {"id": base64("Letter:%s" % l.id), "letter": l.letter}, - "cursor": base64("arrayconnection:%s" % l.id), + "node": {"id": base64("Letter:%s" % letter.id), "letter": letter.letter}, + "cursor": base64("arrayconnection:%s" % letter.id), } - for l in [letters[i] for i in selected_letters] + for letter in [letters[i] for i in selected_letters] ] diff --git a/graphene/types/mutation.py b/graphene/types/mutation.py index c96162e44..31c32284c 100644 --- a/graphene/types/mutation.py +++ b/graphene/types/mutation.py @@ -135,7 +135,7 @@ def __init_subclass_with_meta__( def Field( cls, name=None, description=None, deprecation_reason=None, required=False ): - """ Mount instance of mutation Field. """ + """Mount instance of mutation Field.""" return Field( cls._meta.output, args=cls._meta.arguments, diff --git a/graphene/types/tests/test_query.py b/graphene/types/tests/test_query.py index 8681e4628..0885e22b7 100644 --- a/graphene/types/tests/test_query.py +++ b/graphene/types/tests/test_query.py @@ -399,7 +399,7 @@ def resolve_all_containers(self, info): def test_big_list_of_containers_multiple_fields_custom_resolvers_query_benchmark( - benchmark + benchmark, ): class Container(ObjectType): x = Int() diff --git a/setup.py b/setup.py index 75d92f794..e6e650ea3 100644 --- a/setup.py +++ b/setup.py @@ -49,6 +49,9 @@ def run_tests(self): "pytest-benchmark", "pytest-cov", "pytest-mock", + # pinning fastdiff dep (required by snapshottest) because later versions + # require wasmer 1.0.0 which is not compatible with Python 2.7 + "fastdiff==0.2.0", "snapshottest", "coveralls", "promise", diff --git a/tests_asyncio/test_relay_connection.py b/tests_asyncio/test_relay_connection.py index ec86fef66..edac6fc94 100644 --- a/tests_asyncio/test_relay_connection.py +++ b/tests_asyncio/test_relay_connection.py @@ -56,10 +56,10 @@ def resolve_connection_letters(self, info, **args): def edges(selected_letters): return [ { - "node": {"id": base64("Letter:%s" % l.id), "letter": l.letter}, - "cursor": base64("arrayconnection:%s" % l.id), + "node": {"id": base64("Letter:%s" % letter.id), "letter": letter.letter}, + "cursor": base64("arrayconnection:%s" % letter.id), } - for l in [letters[i] for i in selected_letters] + for letter in [letters[i] for i in selected_letters] ] diff --git a/tox.ini b/tox.ini index a519cb1e7..4e1cc9dc0 100644 --- a/tox.ini +++ b/tox.ini @@ -1,20 +1,27 @@ [tox] -envlist = flake8,py27,py34,py35,py36,py37,pre-commit,pypy,mypy -skipsdist = true +envlist = py{27,36,37,38,39},flake8,pre-commit,mypy + +[gh-actions] +python = + 2.7: py27 + 3.6: py36 + 3.7: py37 + 3.8: py38 + 3.9: py39 [testenv] +passenv = * +usedevelop = True deps = - .[test] - py{35,36,37}: pytest-asyncio + -e.[test] + py{36,37,38,39}: pytest-asyncio setenv = PYTHONPATH = .:{envdir} commands = - py{27,py}: py.test --cov=graphene graphene examples {posargs} - py{35}: py.test --cov=graphene graphene examples tests_asyncio {posargs} - py{36,37}: py.test --cov=graphene graphene examples tests_asyncio tests_py36 {posargs} + py{27}: py.test --cov=graphene graphene examples {posargs} + py{36,37,38,39}: py.test --cov=graphene graphene examples tests_asyncio tests_py36 {posargs} [testenv:pre-commit] -basepython=python3.7 deps = pre-commit>0.12.0 setenv = @@ -23,9 +30,9 @@ commands = pre-commit {posargs:run --all-files} [testenv:mypy] -basepython=python3.7 deps = mypy + types-six commands = mypy graphene @@ -34,5 +41,3 @@ deps = flake8 commands = pip install -e . flake8 graphene - -[pytest] From aba771b2fc5995fa7424949a363712fa10e3f6d6 Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Fri, 16 Jul 2021 16:56:58 +0100 Subject: [PATCH 3/6] Remove CODEOWNERS --- CODEOWNERS | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index 7137418ef..000000000 --- a/CODEOWNERS +++ /dev/null @@ -1,3 +0,0 @@ -* @ekampf @dan98765 @projectcheshire @jkimbo -/docs/ @dvndrsn @phalt @changeling -/examples/ @dvndrsn @phalt @changeling From 0845aa95e47eeb09d61667fecd5f3ab4fdc32014 Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Fri, 16 Jul 2021 21:05:46 +0100 Subject: [PATCH 4/6] Python 3.10 compatibility (#1350) Co-authored-by: Cyrille Pontvieux --- .github/workflows/tests.yml | 2 +- graphene/relay/connection.py | 8 +++++++- graphene/types/field.py | 8 +++++++- graphene/utils/crunch.py | 6 +++++- graphene/utils/deduplicator.py | 7 ++++++- tox.ini | 7 ++++--- 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5d2973ced..f124e60a4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,7 +8,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ["2.7", "3.6", "3.7", "3.8", "3.9"] + python-version: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10-dev"] steps: - uses: actions/checkout@v2 diff --git a/graphene/relay/connection.py b/graphene/relay/connection.py index 047f2b4de..c05160b54 100644 --- a/graphene/relay/connection.py +++ b/graphene/relay/connection.py @@ -1,5 +1,11 @@ import re -from collections import Iterable, OrderedDict +from collections import OrderedDict + +try: + from collections.abc import Iterable +except ImportError: + from collections import Iterable + from functools import partial from graphql_relay import connection_from_list diff --git a/graphene/types/field.py b/graphene/types/field.py index 7f63a8535..39db65e95 100644 --- a/graphene/types/field.py +++ b/graphene/types/field.py @@ -1,5 +1,11 @@ import inspect -from collections import Mapping, OrderedDict +from collections import OrderedDict + +try: + from collections.abc import Mapping +except ImportError: + from collections import Mapping + from functools import partial from .argument import Argument, to_arguments diff --git a/graphene/utils/crunch.py b/graphene/utils/crunch.py index 57fcb77fe..a84a0d312 100644 --- a/graphene/utils/crunch.py +++ b/graphene/utils/crunch.py @@ -1,5 +1,9 @@ import json -from collections import Mapping + +try: + from collections.abc import Mapping +except ImportError: + from collections import Mapping def to_key(value): diff --git a/graphene/utils/deduplicator.py b/graphene/utils/deduplicator.py index 13c1cb163..579807726 100644 --- a/graphene/utils/deduplicator.py +++ b/graphene/utils/deduplicator.py @@ -1,4 +1,9 @@ -from collections import Mapping, OrderedDict +from collections import OrderedDict + +try: + from collections.abc import Mapping +except ImportError: + from collections import Mapping def deflate(node, index=None, path=None): diff --git a/tox.ini b/tox.ini index 4e1cc9dc0..5a555042a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{27,36,37,38,39},flake8,pre-commit,mypy +envlist = py{27,36,37,38,39,310},flake8,pre-commit,mypy [gh-actions] python = @@ -8,18 +8,19 @@ python = 3.7: py37 3.8: py38 3.9: py39 + 3.10-dev: py310 [testenv] passenv = * usedevelop = True deps = -e.[test] - py{36,37,38,39}: pytest-asyncio + py{36,37,38,39,310}: pytest-asyncio setenv = PYTHONPATH = .:{envdir} commands = py{27}: py.test --cov=graphene graphene examples {posargs} - py{36,37,38,39}: py.test --cov=graphene graphene examples tests_asyncio tests_py36 {posargs} + py{36,37,38,39,310}: py.test --cov=graphene graphene examples tests_asyncio tests_py36 {posargs} [testenv:pre-commit] deps = From 7d2af3104e3c01ce4f9a1580faf40d8179079008 Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Fri, 16 Jul 2021 21:08:01 +0100 Subject: [PATCH 5/6] v2.1.9 --- graphene/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphene/__init__.py b/graphene/__init__.py index 9cbbc38f7..a83018c89 100644 --- a/graphene/__init__.py +++ b/graphene/__init__.py @@ -43,7 +43,7 @@ from .utils.module_loading import lazy_import -VERSION = (2, 1, 8, "final", 0) +VERSION = (2, 1, 9, "final", 0) __version__ = get_version(VERSION) From fc582baf406fb5045aaef3f6970ce0aff5498abc Mon Sep 17 00:00:00 2001 From: Kyrylo Khatsko Date: Fri, 2 Sep 2022 14:38:10 +0300 Subject: [PATCH 6/6] Fix documentation typing in schema.py for v2 (#1335) --- graphene/types/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphene/types/schema.py b/graphene/types/schema.py index 07c25763c..738ed7467 100644 --- a/graphene/types/schema.py +++ b/graphene/types/schema.py @@ -34,7 +34,7 @@ class Schema(GraphQLSchema): about the types through introspection. Args: - query (ObjectType): Root query *ObjectType*. Describes entry point for fields to *read* + query (Type[ObjectType]): Root query *ObjectType*. Describes entry point for fields to *read* data in your Schema. mutation (ObjectType, optional): Root mutation *ObjectType*. Describes entry point for fields to *create, update or delete* data in your API.