strawberry-graphql 0.183.2__py3-none-any.whl → 0.183.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -504,7 +504,9 @@ class QueryCodegen:
504
504
  selected_field = self.schema.get_field_for_type(
505
505
  selection.name.value, parent_type.name
506
506
  )
507
- assert selected_field
507
+ assert (
508
+ selected_field
509
+ ), f"Couldn't find {parent_type.name}.{selection.name.value}"
508
510
 
509
511
  selected_field_type, wrapper = self._unwrap_type(selected_field.type)
510
512
  name = capitalize_first(to_camel_case(selection.name.value))
@@ -638,14 +640,13 @@ class QueryCodegen:
638
640
 
639
641
  for fragment in fragments:
640
642
  fragment_class_name = class_name + fragment.type_condition.name.value
641
- current_type = GraphQLObjectType(fragment_class_name, [])
643
+
644
+ current_type = GraphQLObjectType(fragment_class_name, list(common_fields))
642
645
 
643
646
  for sub_selection in fragment.selection_set.selections:
644
647
  # TODO: recurse, use existing method ?
645
648
  assert isinstance(sub_selection, FieldNode)
646
649
 
647
- current_type.fields = list(common_fields)
648
-
649
650
  parent_type = cast(
650
651
  TypeDefinition,
651
652
  self.schema.get_type_by_name(fragment.type_condition.name.value),
@@ -1,5 +1,4 @@
1
1
  import ast
2
- import re
3
2
  import sys
4
3
  import typing
5
4
  from functools import lru_cache
@@ -12,6 +11,7 @@ from typing import ( # type: ignore
12
11
  Dict,
13
12
  ForwardRef,
14
13
  Generic,
14
+ List,
15
15
  Optional,
16
16
  Tuple,
17
17
  Type,
@@ -222,9 +222,66 @@ def _ast_replace_union_operation(
222
222
  return expr
223
223
 
224
224
 
225
- _annotated_re = re.compile(
226
- r"(Annotated\[)(?P<type>\w*),(?P<args>.*)(\])",
227
- )
225
+ def _get_namespace_from_ast(
226
+ expr: Union[ast.Expr, ast.expr],
227
+ globalns: Optional[Dict] = None,
228
+ localns: Optional[Dict] = None,
229
+ ) -> Dict[str, Type]:
230
+ from strawberry.lazy_type import StrawberryLazyReference
231
+
232
+ extra = {}
233
+
234
+ if isinstance(expr, ast.Expr) and isinstance(
235
+ expr.value, (ast.BinOp, ast.Subscript)
236
+ ):
237
+ extra.update(_get_namespace_from_ast(expr.value, globalns, localns))
238
+ elif isinstance(expr, ast.BinOp):
239
+ for elt in (expr.left, expr.right):
240
+ extra.update(_get_namespace_from_ast(elt, globalns, localns))
241
+ elif (
242
+ isinstance(expr, ast.Subscript)
243
+ and isinstance(expr.value, ast.Name)
244
+ and expr.value.id == "Union"
245
+ ):
246
+ if hasattr(ast, "Index") and isinstance(expr.slice, ast.Index):
247
+ # The cast is required for mypy on python 3.7 and 3.8
248
+ expr_slice = cast(Any, expr.slice).value
249
+ else:
250
+ expr_slice = expr.slice
251
+
252
+ for elt in cast(ast.Tuple, expr_slice).elts:
253
+ extra.update(_get_namespace_from_ast(elt, globalns, localns))
254
+ elif (
255
+ isinstance(expr, ast.Subscript)
256
+ and isinstance(expr.value, ast.Name)
257
+ and expr.value.id == "Annotated"
258
+ ):
259
+ assert ast_unparse
260
+
261
+ if hasattr(ast, "Index") and isinstance(expr.slice, ast.Index):
262
+ # The cast is required for mypy on python 3.7 and 3.8
263
+ expr_slice = cast(Any, expr.slice).value
264
+ else:
265
+ expr_slice = expr.slice
266
+
267
+ args: List[str] = []
268
+ for elt in cast(ast.Tuple, expr_slice).elts:
269
+ extra.update(_get_namespace_from_ast(elt, globalns, localns))
270
+ args.append(ast_unparse(elt))
271
+
272
+ # When using forward refs, the whole
273
+ # Annotated[SomeType, strawberry.lazy("type.module")] is a forward ref,
274
+ # and trying to _eval_type on it will fail. Take a different approach
275
+ # here to resolve lazy types by execing the annotated args, resolving the
276
+ # type directly and then adding it to extra namespace, so that _eval_type
277
+ # can properly resolve it later
278
+ type_name = args[0]
279
+ for arg in args[1:]:
280
+ evaled_arg = eval(arg, globalns, localns) # noqa: PGH001
281
+ if isinstance(evaled_arg, StrawberryLazyReference):
282
+ extra[type_name] = evaled_arg.resolve_forward_ref(ForwardRef(type_name))
283
+
284
+ return extra
228
285
 
229
286
 
230
287
  def eval_type(
@@ -240,51 +297,22 @@ def eval_type(
240
297
  globalns = globalns or {}
241
298
  # If this is not a string, maybe its args are (e.g. List["Foo"])
242
299
  if isinstance(type_, ForwardRef):
300
+ ast_obj = cast(ast.Expr, ast.parse(type_.__forward_arg__).body[0])
301
+
243
302
  # For Python 3.10+, we can use the built-in _eval_type function directly.
244
303
  # It will handle "|" notations properly
245
304
  if sys.version_info < (3, 10):
246
- parsed = _ast_replace_union_operation(
247
- cast(ast.Expr, ast.parse(type_.__forward_arg__).body[0])
248
- )
305
+ ast_obj = _ast_replace_union_operation(ast_obj)
249
306
 
250
307
  # We replaced "a | b" with "Union[a, b], so make sure Union can be resolved
251
308
  # at globalns because it may not be there
252
309
  if "Union" not in globalns:
253
310
  globalns["Union"] = Union
254
311
 
255
- assert ast_unparse
256
- type_ = ForwardRef(ast_unparse(parsed))
257
-
258
- # When using forward refs, the whole
259
- # Annotated[SomeType, strabwerry.lazy("type.module")] is a forward ref,
260
- # and trying to _eval_type on it will fail. Take a different approach
261
- # here to resolve lazy types by execing the annotated args and resolving
262
- # the type directly.
263
- annotated_match = _annotated_re.search(type_.__forward_arg__)
264
- if annotated_match:
265
- gdict = annotated_match.groupdict()
266
- # FIXME: Eval the remaining annotated args to get their real values
267
- # We might want to refactor how we import lazy modules to avoid having
268
- # to eval the code in here
269
- args = eval(f'({gdict["args"]}, )', globalns, localns) # noqa: PGH001
270
- lazy_ref = next(
271
- (arg for arg in args if isinstance(arg, StrawberryLazyReference)),
272
- None,
273
- )
274
- if lazy_ref is not None:
275
- remaining = [
276
- a for a in args if not isinstance(a, StrawberryLazyReference)
277
- ]
278
- type_ = lazy_ref.resolve_forward_ref(ForwardRef(gdict["type"]))
279
- # If we only had a StrawberryLazyReference, we can return the type
280
- # directly. It already did its job!
281
- if not remaining:
282
- return type_
312
+ globalns.update(_get_namespace_from_ast(ast_obj, globalns, localns))
283
313
 
284
- # Otherwise return the type annotated with the remaining annotations
285
- return Annotated.__class_getitem__( # type: ignore
286
- (type_, *remaining),
287
- )
314
+ assert ast_unparse
315
+ type_ = ForwardRef(ast_unparse(ast_obj))
288
316
 
289
317
  return _eval_type(type_, globalns, localns)
290
318
 
@@ -302,7 +330,12 @@ def eval_type(
302
330
  for a in args[1:]
303
331
  if not isinstance(arg, StrawberryLazyReference)
304
332
  ]
305
- args = (arg.resolve_forward_ref(args[0]), *remaining_args)
333
+ type_arg = (
334
+ arg.resolve_forward_ref(args[0])
335
+ if isinstance(args[0], ForwardRef)
336
+ else args[0]
337
+ )
338
+ args = (type_arg, *remaining_args)
306
339
  break
307
340
  if isinstance(arg, StrawberryAuto):
308
341
  remaining_args = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strawberry-graphql
3
- Version: 0.183.2
3
+ Version: 0.183.4
4
4
  Summary: A library for creating GraphQL APIs
5
5
  Home-page: https://strawberry.rocks/
6
6
  License: MIT
@@ -41,7 +41,7 @@ strawberry/codegen/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
41
41
  strawberry/codegen/plugins/print_operation.py,sha256=9ZKkYabiHj1qofIjim38Oa6Z8rHDAT2Wm4Lspq2Ka0Q,6423
42
42
  strawberry/codegen/plugins/python.py,sha256=qRLC73DRbWLEd_nPUjyVJR9LwoCeUMh8_S6ZfZzmi0U,4980
43
43
  strawberry/codegen/plugins/typescript.py,sha256=QhabDXIlgbGcb3U7Jr0HHRYcsFxPT86IH0MDIpe-6SQ,3610
44
- strawberry/codegen/query_codegen.py,sha256=oexvvXI8yCRXSgXAsEIirn0lGSbcpYjMGS4hlNTIm28,22178
44
+ strawberry/codegen/query_codegen.py,sha256=dykbL-XAC1V6SCrzvjrcVfUkIjRqAy9Ac9wbChuUM2Q,22221
45
45
  strawberry/codegen/types.py,sha256=VgN5rVnP4RQ7xmEaU8SpiSlAWClEcc_ouKQh9e4NG6w,2916
46
46
  strawberry/custom_scalar.py,sha256=GCmiItYvLYL5nOHhij3e7AMGYz0aIiOkqQjHeZMZoyc,5671
47
47
  strawberry/dataloader.py,sha256=HO8pnK9kQEJfvpFaMHnpSESvkef2c6AZHCQSp_aZJno,7697
@@ -222,9 +222,9 @@ strawberry/utils/inspect.py,sha256=wax9UsOwBrVX0KZad61VOiqsyKgBrODWTAldxE_5woM,3
222
222
  strawberry/utils/logging.py,sha256=pz1pRJtx5xX2ejGKNN-fG8zPA4SJjnq1HK9xaQpjd4s,1106
223
223
  strawberry/utils/operation.py,sha256=Um-tBCPl3_bVFN2Ph7o1mnrxfxBes4HFCj6T0x4kZxE,1135
224
224
  strawberry/utils/str_converters.py,sha256=VdOnzaxhwJnmQl1Lon0VOjl72uXhM8tLfGxoGwn3arI,657
225
- strawberry/utils/typing.py,sha256=4xa5qGt8TVeknAmLZIcDekom-rh--0GU3qBMGRQhhVM,11697
226
- strawberry_graphql-0.183.2.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
227
- strawberry_graphql-0.183.2.dist-info/METADATA,sha256=oGt7jTJlya1NzIF_O9RsSnzraj-cuVB1IIGjvMTuri8,7644
228
- strawberry_graphql-0.183.2.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
229
- strawberry_graphql-0.183.2.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
230
- strawberry_graphql-0.183.2.dist-info/RECORD,,
225
+ strawberry/utils/typing.py,sha256=MpKjtblkpDBCbjS-yeNSxnOo594_2FLHBOdXiYlAjLM,12716
226
+ strawberry_graphql-0.183.4.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
227
+ strawberry_graphql-0.183.4.dist-info/METADATA,sha256=wKAsyfxwdo9U3murKB1PeRmNJRIhWkdqjjHNGF-TM9c,7644
228
+ strawberry_graphql-0.183.4.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
229
+ strawberry_graphql-0.183.4.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
230
+ strawberry_graphql-0.183.4.dist-info/RECORD,,