|
1 | 1 | import pickle
|
| 2 | +import sys |
2 | 3 | from enum import Enum
|
3 | 4 | from math import isnan, nan
|
4 |
| -from typing import Dict |
| 5 | +from typing import Any, Callable, Dict, List |
| 6 | + |
| 7 | +try: |
| 8 | + from typing import TypedDict |
| 9 | +except ImportError: # Python < 3.8 |
| 10 | + from typing_extensions import TypedDict |
5 | 11 |
|
6 | 12 | import pytest
|
7 | 13 | from graphql.error import GraphQLError
|
8 | 14 | from graphql.language import (
|
9 | 15 | EnumTypeDefinitionNode,
|
10 | 16 | EnumTypeExtensionNode,
|
11 | 17 | EnumValueNode,
|
| 18 | + FieldNode, |
| 19 | + FragmentDefinitionNode, |
12 | 20 | InputObjectTypeDefinitionNode,
|
13 | 21 | InputObjectTypeExtensionNode,
|
14 | 22 | InputValueDefinitionNode,
|
15 | 23 | InterfaceTypeDefinitionNode,
|
16 | 24 | InterfaceTypeExtensionNode,
|
17 | 25 | ObjectTypeDefinitionNode,
|
18 | 26 | ObjectTypeExtensionNode,
|
| 27 | + OperationDefinitionNode, |
19 | 28 | ScalarTypeDefinitionNode,
|
20 | 29 | ScalarTypeExtensionNode,
|
21 | 30 | StringValueNode,
|
|
24 | 33 | ValueNode,
|
25 | 34 | parse_value,
|
26 | 35 | )
|
27 |
| -from graphql.pyutils import Undefined |
| 36 | +from graphql.pyutils import Path, Undefined, is_awaitable |
28 | 37 | from graphql.type import (
|
29 | 38 | GraphQLArgument,
|
30 | 39 | GraphQLEnumType,
|
|
37 | 46 | GraphQLList,
|
38 | 47 | GraphQLNonNull,
|
39 | 48 | GraphQLObjectType,
|
| 49 | + GraphQLOutputType, |
| 50 | + GraphQLResolveInfo, |
40 | 51 | GraphQLScalarType,
|
| 52 | + GraphQLSchema, |
41 | 53 | GraphQLString,
|
42 | 54 | GraphQLUnionType,
|
43 | 55 | introspection_types,
|
@@ -1301,3 +1313,56 @@ def cannot_redefine_introspection_types():
|
1301 | 1313 | TypeError, match=f"Redefinition of reserved type '{name}'"
|
1302 | 1314 | ):
|
1303 | 1315 | introspection_type.__class__(**introspection_type.to_kwargs())
|
| 1316 | + |
| 1317 | + |
| 1318 | +def describe_resolve_info(): |
| 1319 | + class InfoArgs(TypedDict): |
| 1320 | + """Arguments for GraphQLResolveInfo""" |
| 1321 | + |
| 1322 | + field_name: str |
| 1323 | + field_nodes: List[FieldNode] |
| 1324 | + return_type: GraphQLOutputType |
| 1325 | + parent_type: GraphQLObjectType |
| 1326 | + path: Path |
| 1327 | + schema: GraphQLSchema |
| 1328 | + fragments: Dict[str, FragmentDefinitionNode] |
| 1329 | + root_value: Any |
| 1330 | + operation: OperationDefinitionNode |
| 1331 | + variable_values: Dict[str, Any] |
| 1332 | + is_awaitable: Callable[[Any], bool] |
| 1333 | + |
| 1334 | + info_args: InfoArgs = { |
| 1335 | + "field_name": "foo", |
| 1336 | + "field_nodes": [], |
| 1337 | + "return_type": GraphQLString, |
| 1338 | + "parent_type": GraphQLObjectType("Foo", {}), |
| 1339 | + "path": Path(None, "foo", None), |
| 1340 | + "schema": GraphQLSchema(), |
| 1341 | + "fragments": {}, |
| 1342 | + "root_value": None, |
| 1343 | + "operation": OperationDefinitionNode(), |
| 1344 | + "variable_values": {}, |
| 1345 | + "is_awaitable": is_awaitable, |
| 1346 | + } |
| 1347 | + |
| 1348 | + def resolve_info_with_unspecified_context_type_can_use_any_type(): |
| 1349 | + info_int = GraphQLResolveInfo(**info_args, context=42) |
| 1350 | + assert info_int.context == 42 |
| 1351 | + info_str = GraphQLResolveInfo(**info_args, context="foo") |
| 1352 | + assert info_str.context == "foo" |
| 1353 | + |
| 1354 | + def resolve_info_with_unspecified_context_type_remembers_type(): |
| 1355 | + info = GraphQLResolveInfo(**info_args, context=42) |
| 1356 | + assert info.context == 42 |
| 1357 | + info = GraphQLResolveInfo(**info_args, context="foo") # type: ignore |
| 1358 | + assert info.context == "foo" |
| 1359 | + |
| 1360 | + @pytest.mark.skipif( |
| 1361 | + sys.version_info < (3, 9), reason="this needs at least Python 3.9" |
| 1362 | + ) |
| 1363 | + def resolve_info_with_specified_context_type_checks_type(): |
| 1364 | + info_int = GraphQLResolveInfo[int](**info_args, context=42) |
| 1365 | + assert isinstance(info_int.context, int) |
| 1366 | + # this should not pass type checking now: |
| 1367 | + info_str = GraphQLResolveInfo[int](**info_args, context="foo") # type: ignore |
| 1368 | + assert isinstance(info_str.context, str) |
0 commit comments