@@ -58,15 +58,26 @@ class Binding(NamedTuple):
58
58
expr_field : FieldReference
59
59
variable_alias : Optional [str ] = None
60
60
61
- def __and__ (self , other : 'Binding' ) -> 'BindComb' :
62
- return BindComb (pvector ([self , other ]))
61
+ def __and__ (self , other : Union ['Binding' , 'BindComb' ]) -> 'BindComb' :
62
+ if isinstance (other , BindComb ):
63
+ return BindComb (pvector ([self ]).extend (other .bindings ))
64
+ elif isinstance (other , Binding ):
65
+ return BindComb (pvector ([self , other ]))
66
+ raise NotImplementedError ('Binding???' )
63
67
64
68
65
69
class BindComb (NamedTuple ):
66
70
""" Binding combinator
67
71
"""
68
72
bindings : PVector [Binding ] = pvector ()
69
73
74
+ def __and__ (self , other : Union ['Binding' , 'BindComb' ]) -> 'BindComb' :
75
+ if isinstance (other , BindComb ):
76
+ return self ._replace (bindings = self .bindings .extend (other .bindings ))
77
+ elif isinstance (other , Binding ):
78
+ return self ._replace (bindings = self .bindings .append (other ))
79
+ raise NotImplementedError ('BindComb???' )
80
+
70
81
71
82
class Unit (NamedTuple ):
72
83
pass
@@ -121,7 +132,16 @@ def prepare_bindings(self, expr: Expr) -> Mapping[str, Iterable[ResolvedBinding]
121
132
rv = defaultdict (list )
122
133
for binding in expr .bindings :
123
134
resolved_input = self .resolve_binding (expr .input , binding .input_field , binding .variable_alias )
124
- resolved_expr = self .resolve_binding (expr .query , binding .expr_field , binding .variable_alias )
135
+ try :
136
+ resolved_expr = self .resolve_binding (expr .query , binding .expr_field , binding .variable_alias )
137
+ except AttrNotFound :
138
+ for typ in self .typer .memo .keys ():
139
+ try :
140
+ resolved_expr = self .resolve_binding (typ , binding .expr_field , binding .variable_alias )
141
+ except (AttributeError , TypeError , AttrNotFound ):
142
+ continue
143
+ else :
144
+ break
125
145
rv [resolved_expr .attr_name ].append (resolved_input )
126
146
return rv
127
147
@@ -134,7 +154,7 @@ def resolve_binding(self, typ: Type[Any], field: FieldReference, alias: Optional
134
154
variable_python_type = field_type
135
155
break
136
156
else :
137
- raise TypeError (f"Couldn't find a field of alias \" { alias } \" in { typ } " )
157
+ raise AttrNotFound (f"Couldn't find a field of alias \" { alias } \" in { typ } " )
138
158
139
159
elif isinstance (field , tuple ):
140
160
# dataclass
@@ -147,7 +167,10 @@ def resolve_binding(self, typ: Type[Any], field: FieldReference, alias: Optional
147
167
overrider = get_global_name_overrider (self .typer .overrides )
148
168
attr_name = overrider (name )
149
169
is_optional = type (None ) in inner_type_boundaries (variable_python_type )
150
- type_name = GQL_SCALARS .get (variable_python_type , variable_python_type .__name__ )
170
+ try :
171
+ type_name = GQL_SCALARS .get (variable_python_type , variable_python_type .__name__ )
172
+ except AttributeError :
173
+ type_name = ''
151
174
return ResolvedBinding (attr_name = overrider (name ),
152
175
input_attr_name = alias if alias else attr_name ,
153
176
type_name = type_name ,
@@ -200,3 +223,7 @@ def AS(a: Binding, b: str) -> Binding:
200
223
201
224
202
225
GQL = GraphQLQueryConstructor ()
226
+
227
+
228
+ class AttrNotFound (TypeError ):
229
+ pass
0 commit comments