strawberry-graphql 0.183.3__py3-none-any.whl → 0.183.5__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.
strawberry/types/types.py CHANGED
@@ -16,7 +16,6 @@ from typing import (
16
16
  from typing_extensions import Self
17
17
 
18
18
  from strawberry.type import StrawberryType, StrawberryTypeVar
19
- from strawberry.utils.inspect import get_specialized_type_var_map
20
19
  from strawberry.utils.typing import is_generic as is_type_generic
21
20
 
22
21
  if TYPE_CHECKING:
@@ -116,13 +115,7 @@ class TypeDefinition(StrawberryType):
116
115
 
117
116
  @property
118
117
  def is_specialized_generic(self) -> bool:
119
- if not self.is_generic:
120
- return False
121
-
122
- type_var_map = get_specialized_type_var_map(self.origin, include_type_vars=True)
123
- return type_var_map is None or not any(
124
- isinstance(arg, TypeVar) for arg in type_var_map.values()
125
- )
118
+ return self.is_generic and not getattr(self.origin, "__parameters__", None)
126
119
 
127
120
  @property
128
121
  def type_params(self) -> List[TypeVar]:
@@ -1,8 +1,15 @@
1
1
  import asyncio
2
2
  import inspect
3
3
  from functools import lru_cache
4
- from typing import Any, Callable, Dict, List, Optional, TypeVar, Union, overload
5
- from typing_extensions import Literal, get_args
4
+ from typing import (
5
+ Any,
6
+ Callable,
7
+ Dict,
8
+ List,
9
+ Optional,
10
+ TypeVar,
11
+ )
12
+ from typing_extensions import get_args
6
13
 
7
14
 
8
15
  def in_async_context() -> bool:
@@ -29,36 +36,7 @@ def get_func_args(func: Callable[[Any], Any]) -> List[str]:
29
36
  ]
30
37
 
31
38
 
32
- @overload
33
- def get_specialized_type_var_map(
34
- cls: type,
35
- *,
36
- include_type_vars: Literal[True],
37
- ) -> Optional[Dict[TypeVar, Union[TypeVar, type]]]:
38
- ...
39
-
40
-
41
- @overload
42
- def get_specialized_type_var_map(
43
- cls: type,
44
- *,
45
- include_type_vars: Literal[False] = ...,
46
- ) -> Optional[Dict[TypeVar, type]]:
47
- ...
48
-
49
-
50
- @overload
51
- def get_specialized_type_var_map(
52
- cls: type,
53
- *,
54
- include_type_vars: bool,
55
- ) -> Optional[
56
- Union[Optional[Dict[TypeVar, type]], Dict[TypeVar, Union[TypeVar, type]]]
57
- ]:
58
- ...
59
-
60
-
61
- def get_specialized_type_var_map(cls: type, *, include_type_vars: bool = False):
39
+ def get_specialized_type_var_map(cls: type) -> Optional[Dict[TypeVar, type]]:
62
40
  """Get a type var map for specialized types.
63
41
 
64
42
  Consider the following:
@@ -85,8 +63,6 @@ def get_specialized_type_var_map(cls: type, *, include_type_vars: bool = False):
85
63
  None
86
64
  >>> get_specialized_type_var_map(Foo)
87
65
  {}
88
- >>> get_specialized_type_var_map(Foo, include_type_vars=True)
89
- {~T: ~T}
90
66
  >>> get_specialized_type_var_map(Bar)
91
67
  {~T: ~T}
92
68
  >>> get_specialized_type_var_map(IntBar)
@@ -104,6 +80,10 @@ def get_specialized_type_var_map(cls: type, *, include_type_vars: bool = False):
104
80
 
105
81
  type_var_map = {}
106
82
 
83
+ # only get type vars for base generics (ie. Generic[T]) and for strawberry types
84
+
85
+ orig_bases = [b for b in orig_bases if hasattr(b, "_type_definition")]
86
+
107
87
  for base in orig_bases:
108
88
  # Recursively get type var map from base classes
109
89
  base_type_var_map = get_specialized_type_var_map(base)
@@ -121,11 +101,7 @@ def get_specialized_type_var_map(cls: type, *, include_type_vars: bool = False):
121
101
  continue
122
102
 
123
103
  type_var_map.update(
124
- {
125
- p: a
126
- for p, a in zip(params, args)
127
- if include_type_vars or not isinstance(a, TypeVar)
128
- }
104
+ {p: a for p, a in zip(params, args) if not isinstance(a, TypeVar)}
129
105
  )
130
106
 
131
107
  return type_var_map
@@ -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.3
3
+ Version: 0.183.5
4
4
  Summary: A library for creating GraphQL APIs
5
5
  Home-page: https://strawberry.rocks/
6
6
  License: MIT
@@ -206,7 +206,7 @@ strawberry/types/graphql.py,sha256=3SWZEsa0Zy1eVW6vy75BnB7t9_lJVi6TBV3_1j3RNBs,6
206
206
  strawberry/types/info.py,sha256=-ZppOgyEWdUYtkRpUVVn9SJGVsMNtR6gaChk8V3DmIg,2754
207
207
  strawberry/types/nodes.py,sha256=2ZVa1HOFgHZ96QTfz3QEr1fufi6Sz9hAzcZxsN7KtGE,5026
208
208
  strawberry/types/type_resolver.py,sha256=bktpUGS8VOF01tx3IwSbmjgXmKR3tREc8qhdIDGaHAA,7306
209
- strawberry/types/types.py,sha256=qy95nwoso5TncX_mo4PXuQzUH2Ej7b3PQ_kpBRrVNIQ,6011
209
+ strawberry/types/types.py,sha256=_9aHLBLZRZLwRMuT6DCFW3KlxO2AjmRU6jrYdkyt8-I,5754
210
210
  strawberry/union.py,sha256=Ne2Q8UHxxdmFC4GgnfSMHh_mEDi9Lq5XcU7hqtCZ2X4,9360
211
211
  strawberry/unset.py,sha256=_180_Wxvw-umn-URMb3CmO-WegBfZHjVZW0L0RXrQrI,1097
212
212
  strawberry/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -218,13 +218,13 @@ strawberry/utils/debug.py,sha256=-MtRqM5e1J-GDNgKQXoVFcBB9f3dHvhEGrTc82uN4LM,137
218
218
  strawberry/utils/graphiql.py,sha256=-l6j5YyFzKMNLeDuNqD_tBl-b2ulvj8ZgMNU1eqEwJE,437
219
219
  strawberry/utils/graphql_lexer.py,sha256=U1mTE5fWy0gcF5fITiZzLWftCpo_C3xOi4BpQxasP3M,1085
220
220
  strawberry/utils/importer.py,sha256=hzTiWCeL9ju6opXTU_kjGpatbUy3UUTW8O1Y5hNA_W8,592
221
- strawberry/utils/inspect.py,sha256=wax9UsOwBrVX0KZad61VOiqsyKgBrODWTAldxE_5woM,3307
221
+ strawberry/utils/inspect.py,sha256=1RyhShhzJ2YuC0tyaTRtpwHx0toiedq1SPWhM1gG9PQ,2775
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.3.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
227
- strawberry_graphql-0.183.3.dist-info/METADATA,sha256=UdEj0XUFi6EmFVp6cPVO2Xgh5IU93bFGSNAtJHBMhhg,7644
228
- strawberry_graphql-0.183.3.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
229
- strawberry_graphql-0.183.3.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
230
- strawberry_graphql-0.183.3.dist-info/RECORD,,
225
+ strawberry/utils/typing.py,sha256=MpKjtblkpDBCbjS-yeNSxnOo594_2FLHBOdXiYlAjLM,12716
226
+ strawberry_graphql-0.183.5.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
227
+ strawberry_graphql-0.183.5.dist-info/METADATA,sha256=1674sEwb-L-qyjJ-OplJbTHwbnfu9GKCogMaz4iOe5w,7644
228
+ strawberry_graphql-0.183.5.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
229
+ strawberry_graphql-0.183.5.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
230
+ strawberry_graphql-0.183.5.dist-info/RECORD,,