From fd1d4a95de7026f8da7d9021986a762c0997191e Mon Sep 17 00:00:00 2001 From: Dixing Xu Date: Thu, 5 Nov 2026 12:43:38 +0000 Subject: [PATCH] perf(execution): reduce field overhead -- introspection 3.9% less time Skip coercion when the field and query node have no arguments. Pass async error-handler state as parameters to avoid closure cells in ordinary field execution. Co-Authored-By: Aiden --- src/graphql/execution/executor.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/graphql/execution/executor.py b/src/graphql/execution/executor.py index 3be7b248..d797b0d9 100644 --- a/src/graphql/execution/executor.py +++ b/src/graphql/execution/executor.py @@ -956,12 +956,16 @@ def execute_field( try: # Build a dictionary of arguments from the field.arguments AST, using the # variables scope to fulfill any variable references. - args = get_argument_values( - field_def, - first_field_node, - self.variable_values, - first_field_details.fragment_variable_values, - self.hide_suggestions, + args = ( + get_argument_values( + field_def, + first_field_node, + self.variable_values, + first_field_details.fragment_variable_values, + self.hide_suggestions, + ) + if field_def.args or first_field_node.arguments + else {} ) # Note that contrary to the JavaScript implementation, we pass the context @@ -988,11 +992,17 @@ def execute_field( ) if self.is_awaitable(completed): - async def await_completed() -> Any: + async def await_completed( + executor: Executor, + completed: Awaitable[Any], + return_type: GraphQLOutputType, + field_details_list: FieldDetailsList, + path: Path, + ) -> Any: try: return await completed except Exception as raw_error: - self.handle_field_error( + executor.handle_field_error( raw_error, return_type, field_details_list, @@ -1000,7 +1010,9 @@ async def await_completed() -> Any: ) return None - return await_completed() + return await_completed( + self, completed, return_type, field_details_list, path + ) except Exception as raw_error: self.handle_field_error(