Skip to content

Commit aa3e89a

Browse files
committed
Update mypy, use new semantic analyzer (#67)
1 parent 07a4cfa commit aa3e89a

27 files changed

+164
-111
lines changed

mypy.ini

-2
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,3 @@ python_version = 3.8
33
check_untyped_defs = True
44
warn_redundant_casts = True
55
warn_unused_ignores = True
6-
# https://github.com/python/mypy/issues/7203
7-
new_semantic_analyzer = False

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pytest-describe = ">=0.12"
4040
pyyaml = "^5.1"
4141
black = ">=19.10b0"
4242
flake8 = "^3.7"
43-
mypy = ">=0.720,<0.730"
43+
mypy = ">=0.750,<0.760"
4444
codecov = "^2"
4545
sphinx = "^2.2"
4646
sphinx_rtd_theme = ">=0.4"

src/graphql/execution/execute.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
FrozenList,
3535
Path,
3636
)
37-
from ..utilities import get_operation_root_type, type_from_ast
37+
from ..utilities.get_operation_root_type import get_operation_root_type
38+
from ..utilities.type_from_ast import type_from_ast
3839
from ..type import (
3940
GraphQLAbstractType,
4041
GraphQLField,

src/graphql/execution/values.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
is_input_type,
2424
is_non_null_type,
2525
)
26-
from ..utilities import coerce_input_value, type_from_ast, value_from_ast
26+
from ..utilities.coerce_input_value import coerce_input_value
27+
from ..utilities.type_from_ast import type_from_ast
28+
from ..utilities.value_from_ast import value_from_ast
2729

2830
__all__ = ["get_variable_values", "get_argument_values", "get_directive_values"]
2931

src/graphql/language/ast.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def __init_subclass__(cls):
239239
keys: List[str] = []
240240
for base in cls.__bases__:
241241
# noinspection PyUnresolvedReferences
242-
keys.extend(base.keys)
242+
keys.extend(base.keys) # type: ignore
243243
keys.extend(cls.__slots__)
244244
cls.keys = keys
245245

src/graphql/language/visitor.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
Callable,
66
List,
77
NamedTuple,
8+
Optional,
89
Sequence,
910
Tuple,
1011
Union,
@@ -157,8 +158,11 @@ def __init_subclass__(cls):
157158
for attr, val in cls.__dict__.items():
158159
if attr.startswith("_"):
159160
continue
160-
attr = attr.split("_", 1)
161-
attr, kind = attr if len(attr) > 1 else (attr[0], None)
161+
attr_kind = attr.split("_", 1)
162+
if len(attr_kind) < 2:
163+
kind: Optional[str] = None
164+
else:
165+
attr, kind = attr_kind
162166
if attr in ("enter", "leave"):
163167
if kind:
164168
name = snake_to_camel(kind) + "Node"

src/graphql/subscription/map_async_iterator.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from asyncio import Event, ensure_future, wait
1+
from asyncio import Event, ensure_future, Future, wait
22
from concurrent.futures import FIRST_COMPLETED
33
from inspect import isasyncgen, isawaitable
4-
from typing import AsyncIterable, Callable
4+
from typing import AsyncIterable, Callable, Set
55

66
__all__ = ["MapAsyncIterator"]
77

@@ -42,7 +42,9 @@ async def __anext__(self):
4242
aclose = ensure_future(self._close_event.wait())
4343
anext = ensure_future(self.iterator.__anext__())
4444

45-
done, pending = await wait([aclose, anext], return_when=FIRST_COMPLETED)
45+
pending: Set[Future] = (
46+
await wait([aclose, anext], return_when=FIRST_COMPLETED)
47+
)[1]
4648
for task in pending:
4749
task.cancel()
4850

src/graphql/subscription/subscribe.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ async def subscribe(
6262
if isinstance(result_or_stream, ExecutionResult):
6363
return result_or_stream
6464

65-
async def map_source_to_response(payload):
65+
async def map_source_to_response(payload) -> ExecutionResult:
6666
"""Map source to response.
6767
6868
For each payload yielded from a subscription, map it over the normal GraphQL
@@ -81,7 +81,7 @@ async def map_source_to_response(payload):
8181
operation_name,
8282
field_resolver,
8383
)
84-
return await result if isawaitable(result) else result
84+
return await result if isawaitable(result) else result # type: ignore
8585

8686
return MapAsyncIterator(result_or_stream, map_source_to_response)
8787

src/graphql/type/definition.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -361,11 +361,11 @@ def __init__(
361361
" as a sequence of ScalarTypeExtensionNode instances."
362362
)
363363
if serialize is not None:
364-
self.serialize = serialize
364+
self.serialize = serialize # type: ignore
365365
if parse_value is not None:
366-
self.parse_value = parse_value
366+
self.parse_value = parse_value # type: ignore
367367
if parse_literal is not None:
368-
self.parse_literal = parse_literal
368+
self.parse_literal = parse_literal # type: ignore
369369

370370
def __repr__(self):
371371
return f"<{self.__class__.__name__} {self.name!r}>"
@@ -391,9 +391,7 @@ def parse_value(value: Any) -> Any:
391391
"""
392392
return value
393393

394-
def parse_literal( # type: ignore
395-
self, node: ValueNode, _variables: Dict[str, Any] = None
396-
) -> Any:
394+
def parse_literal(self, node: ValueNode, _variables: Dict[str, Any] = None) -> Any:
397395
"""Parses an externally provided literal value to use as an input.
398396
399397
This default method uses the parse_value method and should be replaced
@@ -1247,7 +1245,7 @@ def __init__(
12471245
)
12481246
self._fields = fields
12491247
if out_type is not None:
1250-
self.out_type = out_type
1248+
self.out_type = out_type # type: ignore
12511249

12521250
@staticmethod
12531251
def out_type(value: Dict[str, Any]) -> Any:

src/graphql/type/validate.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def validate_directives(self):
155155
arg_names: Set[str] = set()
156156
for arg_name, arg in directive.args.items():
157157
# Ensure they are named correctly.
158-
self.validate_name(arg_name, arg)
158+
self.validate_name(arg, arg_name)
159159

160160
# Ensure they are unique per directive.
161161
if arg_name in arg_names:

src/graphql/utilities/coerce_value.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from ..language import Node
55
from ..pyutils import Path, inspect, print_path_list
66
from ..type import GraphQLInputType
7-
from . import coerce_input_value
7+
from .coerce_input_value import coerce_input_value
88

99
__all__ = ["coerce_value", "CoercedValue"]
1010

src/graphql/utilities/extend_schema.py

+22-12
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ def extend_named_type(type_: GraphQLNamedType) -> GraphQLNamedType:
169169

170170
def extend_directive(directive: GraphQLDirective) -> GraphQLDirective:
171171
kwargs = directive.to_kwargs()
172-
return GraphQLDirective( # type: ignore
173-
**{
172+
return GraphQLDirective(
173+
**{ # type: ignore
174174
**kwargs,
175175
"args": {name: extend_arg(arg) for name, arg in kwargs["args"].items()},
176176
}
@@ -188,8 +188,11 @@ def extend_input_object_type(
188188
**kwargs,
189189
"fields": lambda: {
190190
**{
191-
name: GraphQLInputField( # type: ignore
192-
**{**field.to_kwargs(), "type_": replace_type(field.type)}
191+
name: GraphQLInputField(
192+
**{ # type: ignore
193+
**field.to_kwargs(),
194+
"type_": replace_type(field.type),
195+
}
193196
)
194197
for name, field in kwargs["fields"].items()
195198
},
@@ -306,17 +309,20 @@ def extend_union_type(type_: GraphQLUnionType) -> GraphQLUnionType:
306309
)
307310

308311
def extend_field(field: GraphQLField) -> GraphQLField:
309-
return GraphQLField( # type: ignore
310-
**{
312+
return GraphQLField(
313+
**{ # type: ignore
311314
**field.to_kwargs(),
312315
"type_": replace_type(field.type),
313316
"args": {name: extend_arg(arg) for name, arg in field.args.items()},
314317
}
315318
)
316319

317320
def extend_arg(arg: GraphQLArgument) -> GraphQLArgument:
318-
return GraphQLArgument( # type: ignore
319-
**{**arg.to_kwargs(), "type_": replace_type(arg.type)}
321+
return GraphQLArgument(
322+
**{ # type: ignore
323+
**arg.to_kwargs(),
324+
"type_": replace_type(arg.type),
325+
}
320326
)
321327

322328
# noinspection PyShadowingNames
@@ -358,13 +364,17 @@ def resolve_type(type_name: str) -> GraphQLNamedType:
358364
operation_types[operation] = operation_type.type.name.value
359365

360366
# Then produce and return a Schema with these types.
361-
return GraphQLSchema( # type: ignore
367+
return GraphQLSchema(
362368
# Note: While this could make early assertions to get the correctly
363369
# typed values, that would throw immediately while type system
364370
# validation with validateSchema() will produce more actionable results.
365-
query=get_maybe_type_by_name(operation_types[OperationType.QUERY]),
366-
mutation=get_maybe_type_by_name(operation_types[OperationType.MUTATION]),
367-
subscription=get_maybe_type_by_name(
371+
query=get_maybe_type_by_name( # type: ignore
372+
operation_types[OperationType.QUERY]
373+
),
374+
mutation=get_maybe_type_by_name( # type: ignore
375+
operation_types[OperationType.MUTATION]
376+
),
377+
subscription=get_maybe_type_by_name( # type: ignore
368378
operation_types[OperationType.SUBSCRIPTION]
369379
),
370380
types=list(type_map.values()),

src/graphql/utilities/find_breaking_changes.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,11 @@ def find_breaking_changes(
8989
Given two schemas, returns a list containing descriptions of all the types of
9090
breaking changes covered by the other functions down below.
9191
"""
92-
breaking_changes = [
92+
return [
9393
change
9494
for change in find_schema_changes(old_schema, new_schema)
9595
if isinstance(change.type, BreakingChangeType)
9696
]
97-
return cast(List[BreakingChange], breaking_changes)
9897

9998

10099
def find_dangerous_changes(
@@ -105,12 +104,11 @@ def find_dangerous_changes(
105104
Given two schemas, returns a list containing descriptions of all the types of
106105
potentially dangerous changes covered by the other functions down below.
107106
"""
108-
dangerous_changes = [
107+
return [
109108
change
110109
for change in find_schema_changes(old_schema, new_schema)
111110
if isinstance(change.type, DangerousChangeType)
112111
]
113-
return cast(List[DangerousChange], dangerous_changes)
114112

115113

116114
def find_schema_changes(

src/graphql/utilities/separate_operations.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,15 @@ def separate_operations(document_ast: DocumentNode) -> Dict[str, DocumentNode]:
5252
return separated_document_asts
5353

5454

55+
# noinspection PyAttributeOutsideInit
5556
class SeparateOperations(Visitor):
5657
def __init__(self):
5758
super().__init__()
5859
self.operations: List[OperationDefinitionNode] = []
5960
self.fragments: Dict[str, FragmentDefinitionNode] = {}
6061
self.positions: Dict[ExecutableDefinitionNode, int] = {}
6162
self.dep_graph: DepGraph = defaultdict(set)
62-
self.from_name: str = None
63+
self.from_name: str
6364
self.idx = 0
6465

6566
def enter_operation_definition(self, node, *_args):

tests/execution/test_abstract.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,10 @@ def resolve_type_on_union_yields_useful_error():
335335
}
336336

337337
def returning_invalid_value_from_resolve_type_yields_useful_error():
338-
foo_interface = GraphQLInterfaceType( # type: ignore
338+
foo_interface = GraphQLInterfaceType(
339339
"FooInterface",
340340
{"bar": GraphQLField(GraphQLString)},
341-
resolve_type=lambda *_args: [],
341+
resolve_type=lambda *_args: [], # type: ignore
342342
)
343343

344344
foo_object = GraphQLObjectType(

tests/execution/test_executor.py

+15-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import asyncio
2-
from typing import cast
2+
from typing import cast, Awaitable
33

44
from pytest import raises, mark # type: ignore
55

@@ -84,10 +84,10 @@ def pic(self, _info, size=50):
8484
return f"Pic of size: {size}"
8585

8686
def deep(self, _info):
87-
return DeepData() # type: ignore
87+
return DeepData()
8888

8989
def promise(self, _info):
90-
return promise_data() # type: ignore
90+
return promise_data()
9191

9292
# noinspection PyMethodMayBeStatic,PyMethodMayBeStatic
9393
class DeepData:
@@ -134,7 +134,7 @@ async def promise_data():
134134
"a": GraphQLField(GraphQLString),
135135
"b": GraphQLField(GraphQLString),
136136
"c": GraphQLField(GraphQLList(GraphQLString)),
137-
"deeper": GraphQLList(DataType),
137+
"deeper": GraphQLField(GraphQLList(DataType)),
138138
},
139139
)
140140

@@ -170,9 +170,11 @@ async def promise_data():
170170
"""
171171
)
172172

173-
result = await execute(
173+
awaitable_result = execute(
174174
GraphQLSchema(DataType), document, Data(), variable_values={"size": 100}
175175
)
176+
assert isinstance(awaitable_result, Awaitable)
177+
result = await awaitable_result
176178

177179
assert result == (
178180
{
@@ -411,7 +413,9 @@ async def asyncReturnErrorWithExtensions(self, _info):
411413
extensions={"foo": "bar"},
412414
)
413415

414-
result = await execute(schema, document, Data())
416+
awaitable_result = execute(schema, document, Data())
417+
assert isinstance(awaitable_result, Awaitable)
418+
result = await awaitable_result
415419

416420
assert result == (
417421
{
@@ -719,7 +723,9 @@ async def d(self, _info):
719723
def e(self, _info):
720724
return "e"
721725

722-
result = await execute(schema, document, Data())
726+
awaitable_result = execute(schema, document, Data())
727+
assert isinstance(awaitable_result, Awaitable)
728+
result = await awaitable_result
723729

724730
assert result == ({"a": "a", "b": "b", "c": "c", "d": "d", "e": "e"}, None)
725731

@@ -874,13 +880,14 @@ def uses_a_custom_type_resolver():
874880
types=[foo_object],
875881
)
876882

883+
possible_types = None
884+
877885
def type_resolver(_source, info, abstract_type):
878886
# Resolver should be able to figure out all possible types on its own
879887
nonlocal possible_types
880888
possible_types = info.schema.get_possible_types(abstract_type)
881889
return "FooObject"
882890

883-
possible_types = None
884891
root_value = {"foo": {"bar": "bar"}}
885892
result = execute(schema, document, root_value, type_resolver=type_resolver)
886893

0 commit comments

Comments
 (0)