@@ -1177,11 +1177,10 @@ async def complete_async_iterator_value(
11771177 """
11781178 errors = async_payload_record .errors if async_payload_record else self .errors
11791179 stream = self .get_stream_values (field_nodes , path )
1180- is_awaitable = self .is_awaitable
1180+ complete_list_item_value = self .complete_list_item_value
11811181 awaitable_indices : List [int ] = []
11821182 append_awaitable = awaitable_indices .append
11831183 completed_results : List [Any ] = []
1184- append_result = completed_results .append
11851184 index = 0
11861185 while True :
11871186 if (
@@ -1213,46 +1212,23 @@ async def complete_async_iterator_value(
12131212 value = await anext (iterator )
12141213 except StopAsyncIteration :
12151214 break
1216- try :
1217- completed_item = self .complete_value (
1218- item_type ,
1219- field_nodes ,
1220- info ,
1221- item_path ,
1222- value ,
1223- async_payload_record ,
1224- )
1225- if is_awaitable (completed_item ):
1226- # noinspection PyShadowingNames
1227- async def catch_error (
1228- completed_item : Awaitable [Any ], item_path : Path
1229- ) -> Any :
1230- try :
1231- return await completed_item
1232- except Exception as raw_error :
1233- error = located_error (
1234- raw_error , field_nodes , item_path .as_list ()
1235- )
1236- self .filter_subsequent_payloads (
1237- item_path , async_payload_record
1238- )
1239- handle_field_error (error , item_type , errors )
1240- return None
1241-
1242- append_result (catch_error (completed_item , item_path ))
1243- append_awaitable (index )
1244- else :
1245- append_result (completed_item )
1246- except Exception as raw_error :
1247- append_result (None )
1248- error = located_error (raw_error , field_nodes , item_path .as_list ())
1249- self .filter_subsequent_payloads (item_path , async_payload_record )
1250- handle_field_error (error , item_type , errors )
12511215 except Exception as raw_error :
1252- append_result (None )
12531216 error = located_error (raw_error , field_nodes , item_path .as_list ())
12541217 handle_field_error (error , item_type , errors )
1218+ completed_results .append (None )
12551219 break
1220+ if complete_list_item_value (
1221+ value ,
1222+ completed_results ,
1223+ errors ,
1224+ item_type ,
1225+ field_nodes ,
1226+ info ,
1227+ item_path ,
1228+ async_payload_record ,
1229+ ):
1230+ append_awaitable (index )
1231+
12561232 index += 1
12571233
12581234 if not awaitable_indices :
@@ -1307,12 +1283,11 @@ def complete_list_value(
13071283 # This is specified as a simple map, however we're optimizing the path where
13081284 # the list contains no coroutine objects by avoiding creating another coroutine
13091285 # object.
1310- is_awaitable = self .is_awaitable
1286+ complete_list_item_value = self .complete_list_item_value
13111287 awaitable_indices : List [int ] = []
13121288 append_awaitable = awaitable_indices .append
13131289 previous_async_payload_record = async_payload_record
13141290 completed_results : List [Any ] = []
1315- append_result = completed_results .append
13161291 for index , item in enumerate (result ):
13171292 # No need to modify the info object containing the path, since from here on
13181293 # it is not ever accessed by resolver functions.
@@ -1335,67 +1310,17 @@ def complete_list_value(
13351310 )
13361311 continue
13371312
1338- completed_item : AwaitableOrValue [Any ]
1339-
1340- if is_awaitable (item ):
1341- # noinspection PyShadowingNames
1342- async def await_completed (item : Any , item_path : Path ) -> Any :
1343- try :
1344- completed = self .complete_value (
1345- item_type ,
1346- field_nodes ,
1347- info ,
1348- item_path ,
1349- await item ,
1350- async_payload_record ,
1351- )
1352- if is_awaitable (completed ):
1353- return await completed
1354- except Exception as raw_error :
1355- error = located_error (
1356- raw_error , field_nodes , item_path .as_list ()
1357- )
1358- handle_field_error (error , item_type , errors )
1359- self .filter_subsequent_payloads (item_path , async_payload_record )
1360- return None
1361- return completed
1362-
1363- completed_item = await_completed (item , item_path )
1364- else :
1365- try :
1366- completed_item = self .complete_value (
1367- item_type ,
1368- field_nodes ,
1369- info ,
1370- item_path ,
1371- item ,
1372- async_payload_record ,
1373- )
1374- if is_awaitable (completed_item ):
1375- # noinspection PyShadowingNames
1376- async def await_completed (item : Any , item_path : Path ) -> Any :
1377- try :
1378- return await item
1379- except Exception as raw_error :
1380- error = located_error (
1381- raw_error , field_nodes , item_path .as_list ()
1382- )
1383- handle_field_error (error , item_type , errors )
1384- self .filter_subsequent_payloads (
1385- item_path , async_payload_record
1386- )
1387- return None
1388-
1389- completed_item = await_completed (completed_item , item_path )
1390- except Exception as raw_error :
1391- error = located_error (raw_error , field_nodes , item_path .as_list ())
1392- handle_field_error (error , item_type , errors )
1393- self .filter_subsequent_payloads (item_path , async_payload_record )
1394- completed_item = None
1395-
1396- if is_awaitable (completed_item ):
1313+ if complete_list_item_value (
1314+ item ,
1315+ completed_results ,
1316+ errors ,
1317+ item_type ,
1318+ field_nodes ,
1319+ info ,
1320+ item_path ,
1321+ async_payload_record ,
1322+ ):
13971323 append_awaitable (index )
1398- append_result (completed_item )
13991324
14001325 if not awaitable_indices :
14011326 return completed_results
@@ -1418,6 +1343,74 @@ async def get_completed_results() -> List[Any]:
14181343
14191344 return get_completed_results ()
14201345
1346+ def complete_list_item_value (
1347+ self ,
1348+ item : Any ,
1349+ complete_results : List [Any ],
1350+ errors : List [GraphQLError ],
1351+ item_type : GraphQLOutputType ,
1352+ field_nodes : List [FieldNode ],
1353+ info : GraphQLResolveInfo ,
1354+ item_path : Path ,
1355+ async_payload_record : Optional [AsyncPayloadRecord ],
1356+ ) -> bool :
1357+ """Complete a list item value by adding it to the completed results.
1358+
1359+ Returns True if the value is awaitable.
1360+ """
1361+ is_awaitable = self .is_awaitable
1362+ try :
1363+ if is_awaitable (item ):
1364+ completed_item : Any
1365+
1366+ async def await_completed () -> Any :
1367+ completed = self .complete_value (
1368+ item_type ,
1369+ field_nodes ,
1370+ info ,
1371+ item_path ,
1372+ await item ,
1373+ async_payload_record ,
1374+ )
1375+ return await completed if is_awaitable (completed ) else completed
1376+
1377+ completed_item = await_completed ()
1378+ else :
1379+ completed_item = self .complete_value (
1380+ item_type ,
1381+ field_nodes ,
1382+ info ,
1383+ item_path ,
1384+ item ,
1385+ async_payload_record ,
1386+ )
1387+
1388+ if is_awaitable (completed_item ):
1389+ # noinspection PyShadowingNames
1390+ async def catch_error () -> Any :
1391+ try :
1392+ return await completed_item
1393+ except Exception as raw_error :
1394+ error = located_error (
1395+ raw_error , field_nodes , item_path .as_list ()
1396+ )
1397+ handle_field_error (error , item_type , errors )
1398+ self .filter_subsequent_payloads (item_path , async_payload_record )
1399+ return None
1400+
1401+ complete_results .append (catch_error ())
1402+ return True
1403+
1404+ complete_results .append (completed_item )
1405+
1406+ except Exception as raw_error :
1407+ error = located_error (raw_error , field_nodes , item_path .as_list ())
1408+ handle_field_error (error , item_type , errors )
1409+ self .filter_subsequent_payloads (item_path , async_payload_record )
1410+ complete_results .append (None )
1411+
1412+ return False
1413+
14211414 @staticmethod
14221415 def complete_leaf_value (return_type : GraphQLLeafType , result : Any ) -> Any :
14231416 """Complete a leaf value.
0 commit comments