Skip to content

Commit b6bd31c

Browse files
authored
Create v2 that is compatible with Core v2 (#21)
* Create v2 that is compatible with Core v2 * Bump version to 2.0 * Support GraphQL-core >= 2.0, < 3 (use the newer signature for resolvers) * Drop support for Python 3.3 * Drop redundant README.rst * Clean-up and PEP-8 * Use .flake8 instead of setup.cfg * Use "setup.py test" for testing, as explained in README * Make this run with pytest 4. This will be changed in v3, where we use pytest 5 and run it directly. * Only check relevant files with flake8 * Minor fixes in the README
1 parent 08c5995 commit b6bd31c

27 files changed

+349
-630
lines changed

Diff for: .flake8

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[flake8]
2+
ignore = E203,W503,E704
3+
exclude = .git,.mypy_cache,.pytest_cache,.tox,.venv,__pycache__,build,dist,docs
4+
max-line-length = 88

Diff for: .gitignore

+20-19
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
1-
# Created by https://www.gitignore.io
2-
3-
### Python ###
4-
# Byte-compiled / optimized / DLL files
51
__pycache__/
62
*.py[cod]
73

8-
# C extensions
9-
*.so
10-
11-
# Distribution / packaging
124
.Python
13-
env/
145
build/
156
develop-eggs/
167
dist/
@@ -22,40 +13,50 @@ lib64/
2213
parts/
2314
sdist/
2415
var/
16+
wheels/
17+
pip-wheel-metadata/
18+
share/python-wheels/
2519
*.egg-info/
2620
.installed.cfg
2721
*.egg
22+
MANIFEST
2823

29-
# PyInstaller
30-
# Usually these files are written by a python script from a template
31-
# before PyInstaller builds the exe, so as to inject date/other infos into it.
3224
*.manifest
3325
*.spec
3426

35-
# Installer logs
3627
pip-log.txt
3728
pip-delete-this-directory.txt
3829

39-
# Unit test / coverage reports
4030
htmlcov/
4131
.tox/
32+
.nox/
4233
.coverage
4334
.coverage.*
4435
.cache
4536
nosetests.xml
4637
coverage.xml
47-
*,cover
38+
*.cover
39+
.pytest_cache/
4840

49-
# Translations
5041
*.mo
5142
*.pot
5243

53-
# Django stuff:
5444
*.log
5545

56-
# Sphinx documentation
5746
docs/_build/
5847

59-
# PyBuilder
6048
target/
6149

50+
.python-version
51+
52+
.env
53+
.venv
54+
env/
55+
venv/
56+
ENV/
57+
env.bak/
58+
venv.bak/
59+
60+
.mypy_cache/
61+
62+
.idea/

Diff for: .travis.yml

+8-8
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ language: python
22
dist: xenial
33

44
python:
5-
- 2.7
6-
- 3.5
7-
- 3.6
8-
- 3.7
9-
- pypy3
5+
- "2.7"
6+
- "3.5"
7+
- "3.6"
8+
- "3.7"
9+
- "pypy3"
1010
install:
11-
- pip install pytest pytest-cov flake8
1211
- pip install .
12+
- pip install "flake8>=3.7,<4"
1313
script:
14-
- py.test --cov=graphql_relay
15-
# - flake8
14+
- python setup.py test -a "--cov=graphql_relay"
15+
- flake8 setup.py src tests
1616
after_success:
1717
- pip install coveralls
1818
- coveralls

Diff for: README.md

+25-29
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ that documentation and the corresponding tests in this library together.
3636
Install Relay Library for GraphQL Python
3737

3838
```sh
39-
pip install graphql-core --pre # Last version of graphql-core
39+
pip install "graphql-core>=2,<3" # use version 2.x of graphql-core
4040
pip install graphql-relay
4141
```
4242

@@ -54,13 +54,13 @@ returning those types.
5454
they return a connection type.
5555
- `connection_definitions` returns a `connection_type` and its associated
5656
`edgeType`, given a name and a node type.
57-
- `connection_from_list` is a helper method that takes an array and the
57+
- `connection_from_list` is a helper method that takes a list and the
5858
arguments from `connection_args`, does pagination and filtering, and returns
5959
an object in the shape expected by a `connection_type`'s `resolver` function.
6060
- `connection_from_promised_list` is similar to `connection_from_list`, but
6161
it takes a promise that resolves to an array, and returns a promise that
6262
resolves to the expected shape by `connection_type`.
63-
- `cursor_for_object_in_connection` is a helper method that takes an array and a
63+
- `cursor_for_object_in_connection` is a helper method that takes a list and a
6464
member object, and returns a cursor for use in the mutation payload.
6565

6666
An example usage of these methods from the [test schema](tests/starwars/schema.py):
@@ -69,32 +69,31 @@ An example usage of these methods from the [test schema](tests/starwars/schema.p
6969
ship_edge, ship_connection = connection_definitions('Ship', shipType)
7070

7171
factionType = GraphQLObjectType(
72-
name= 'Faction',
73-
description= 'A faction in the Star Wars saga',
72+
name='Faction',
73+
description='A faction in the Star Wars saga',
7474
fields= lambda: {
7575
'id': global_id_field('Faction'),
7676
'name': GraphQLField(
7777
GraphQLString,
7878
description='The name of the faction.',
7979
),
8080
'ships': GraphQLField(
81-
shipConnection,
82-
description= 'The ships used by the faction.',
83-
args= connection_args,
84-
resolver= lambda faction, args, *_: connection_from_list(
85-
map(getShip, faction.ships),
86-
args
81+
ship_connection,
82+
description='The ships used by the faction.',
83+
args=connection_args,
84+
resolver=lambda faction, _info, **args: connection_from_list(
85+
[getShip(ship) for ship in faction.ships], args
8786
),
8887
)
8988
},
90-
interfaces= [node_interface]
89+
interfaces=[node_interface]
9190
)
9291
```
9392

9493
This shows adding a `ships` field to the `Faction` object that is a connection.
9594
It uses `connection_definitions({name: 'Ship', nodeType: shipType})` to create
9695
the connection type, adds `connection_args` as arguments on this function, and
97-
then implements the resolver function by passing the array of ships and the
96+
then implements the resolver function by passing the list of ships and the
9897
arguments to `connection_from_list`.
9998

10099
### Object Identification
@@ -108,7 +107,7 @@ this, it takes a function to resolve an ID to an object, and to determine
108107
the type of a given object.
109108
- `to_global_id` takes a type name and an ID specific to that type name,
110109
and returns a "global ID" that is unique among all types.
111-
- `from_global_id` takes the "global ID" created by `toGlobalID`, and retuns
110+
- `from_global_id` takes the "global ID" created by `to_global_id`, and returns
112111
the type name and ID used to create it.
113112
- `global_id_field` creates the configuration for an `id` field on a node.
114113
- `plural_identifying_root_field` creates a field that accepts a list of
@@ -118,17 +117,16 @@ objects.
118117
An example usage of these methods from the [test schema](tests/starwars/schema.py):
119118

120119
```python
121-
def get_node(global_id, context, info):
122-
resolvedGlobalId = from_global_id(global_id)
123-
_type, _id = resolvedGlobalId.type, resolvedGlobalId.id
124-
if _type == 'Faction':
125-
return getFaction(_id)
126-
elif _type == 'Ship':
127-
return getShip(_id)
120+
def get_node(global_id, _info):
121+
type_, id_ = from_global_id(global_id)
122+
if type_ == 'Faction':
123+
return getFaction(id_)
124+
elif type_ == 'Ship':
125+
return getShip(id_)
128126
else:
129127
return None
130128

131-
def get_node_type(obj, context, info):
129+
def get_node_type(obj, _info):
132130
if isinstance(obj, Faction):
133131
return factionType
134132
else:
@@ -177,11 +175,9 @@ class IntroduceShipMutation(object):
177175
def __init__(self, shipId, factionId, clientMutationId=None):
178176
self.shipId = shipId
179177
self.factionId = factionId
180-
self.clientMutationId = None
178+
self.clientMutationId = clientMutationId
181179

182-
def mutate_and_get_payload(data, *_):
183-
shipName = data.get('shipName')
184-
factionId = data.get('factionId')
180+
def mutate_and_get_payload(_info, shipName, factionId, **_input):
185181
newShip = createShip(shipName, factionId)
186182
return IntroduceShipMutation(
187183
shipId=newShip.id,
@@ -201,19 +197,19 @@ shipMutation = mutation_with_client_mutation_id(
201197
output_fields= {
202198
'ship': GraphQLField(
203199
shipType,
204-
resolver= lambda payload, *_: getShip(payload.shipId)
200+
resolver=lambda payload, _info: getShip(payload.shipId)
205201
),
206202
'faction': GraphQLField(
207203
factionType,
208-
resolver= lambda payload, *_: getFaction(payload.factionId)
204+
resolver=lambda payload, _info: getFaction(payload.factionId)
209205
)
210206
},
211207
mutate_and_get_payload=mutate_and_get_payload
212208
)
213209

214210
mutationType = GraphQLObjectType(
215211
'Mutation',
216-
fields= lambda: {
212+
fields=lambda: {
217213
'introduceShip': shipMutation
218214
}
219215
)

0 commit comments

Comments
 (0)