(
    schema: GraphQLSchema,
    visitor_selector: Callable[
        [VisitableSchemaType, str], List["SchemaDirectiveVisitor"]
    ],
)
return schema
Helper function that calls visitor_selector and applies the resulting
    visitors to the given type, with arguments [type, ...args].
Helper function that calls visitor_selector and applies the resulting
    visitors to the given type, with arguments [type, ...args].
Helper function that calls visitor_selector and applies the resulting visitors to the given type with arguments [ type ... args ] .
def visit_schema(
    schema: GraphQLSchema,
    visitor_selector: Callable[
        [VisitableSchemaType, str], List["SchemaDirectiveVisitor"]
    ],
) -> GraphQLSchema:
    """
    Helper function that calls visitor_selector and applies the resulting
    visitors to the given type, with arguments [type, ...args].
    """

    def call_method(
        method_name: str, type_: VisitableSchemaType, *args: Any
    ) -> Union[VisitableSchemaType, Literal[False]]:
        for visitor in visitor_selector(type_, method_name):

            new_type = getattr(visitor, method_name)(type_, *args)
            if new_type is None:
                # Keep going without modifying type.
                continue

            if method_name == "visit_schema" or isinstance(type_, GraphQLSchema):
                raise ValueError(
                    f"Method {method_name} cannot replace schema with {new_type}"
                )

            if new_type is False:
                # Stop the loop and return False form call_method, which will cause
                # the type to be removed from the schema.
                del type_
                return False

            # Update type to the new type returned by the visitor method, so that
            # later directives will see the new type, and call_method will return
            # the final type.
            type_ = new_type

        # If there were no directives for this type object, or if all visitor
        # methods returned nothing, type will be returned unmodified.
        return type_

    def visit(  # pylint: disable=too-many-return-statements
        type_: VisitableSchemaType,
    ) -> Union[VisitableSchemaType, Literal[False]]:
        """
        Recursive helper function that calls any appropriate visitor methods for
        each object in the schema, then traverses the object's children (if any).
        """
        if isinstance(type_, GraphQLSchema):
            # Unlike the other types, the root GraphQLSchema object cannot be
            # replaced by visitor methods, because that would make life very hard
            # for SchemaVisitor subclasses that rely on the original schema object.
            call_method("visit_schema", type_)

            def _start(named_type, type_name):
                if not type_name.startswith("__"):
                    visit(named_type)

            update_each_key(type_.type_map, _start)

            return type_

        if isinstance(type_, GraphQLObjectType):
            # Note that call_method('visit_object', type_) may not actually call any
            # methods, if there are no @directive annotations associated with this
            # type, or if this SchemaDirectiveVisitor subclass does not override
            # the visit_object method.
            new_object = cast(GraphQLObjectType, call_method("visit_object", type_))
            if new_object:
                visit_fields(new_object)

            return new_object

        if isinstance(type_, GraphQLInterfaceType):
            new_interface = cast(
                GraphQLInterfaceType, call_method("visit_interface", type_)
            )
            if new_interface:
                visit_fields(new_interface)

            return new_interface

        if isinstance(type_, GraphQLInputObjectType):
            new_input_object = cast(
                GraphQLInputObjectType, call_method("visit_input_object", type_)
            )

            if new_input_object:
                update_each_key(
                    new_input_object.fields,
                    lambda field, n: call_method(
                        "visit_input_field_definition", field, new_input_object
                    ),
                )

            return new_input_object

        if isinstance(type_, GraphQLScalarType):
            return call_method("visit_scalar", type_)

        if isinstance(type_, GraphQLUnionType):
            return call_method("visit_union", type_)

        if isinstance(type_, GraphQLEnumType):
            new_enum = cast(GraphQLEnumType, call_method("visit_enum", type_))

            if new_enum:
                update_each_key(
                    new_enum.values,
                    lambda value, name: call_method("visit_enum_value", value, name),
                )

            return new_enum

        raise ValueError(f"Unexpected schema type: {type_}")

    def visit_fields(type_: Union[GraphQLObjectType, GraphQLInterfaceType]):
        def _update_fields(field, _):
            # It would be nice if we could call visit(field) recursively here, but
            # GraphQLField is merely a type, not a value that can be detected using
            # an instanceof check, so we have to visit the fields in this lexical
            # context, so that TypeScript can validate the call to
            # visit_field_definition.
            new_field = call_method("visit_field_definition", field, type_)
            # While any field visitor needs a reference to the field object, some
            # field visitors may also need to know the enclosing (parent) type,
            # perhaps to determine if the parent is a GraphQLObjectType or a
            # GraphQLInterfaceType. To obtain a reference to the parent, a
            # visitor method can have a second parameter, which will be reeferring
            # to the parent.

            if new_field and new_field.args:
                update_each_key(
                    new_field.args,
                    lambda arg, _: call_method(
                        "visit_argument_definition", arg, new_field, type_
                    ),
                )

            return new_field

        update_each_key(type_.fields, _update_fields)

    visit(schema)

    # Return the original schema for convenience, even though it cannot have
    # been replaced or removed by the code above.
    return schema
def visit_schema ( schema : GraphQLSchema , visitor_selector : Callable [ [ VisitableSchemaType , str ] , List [ "SchemaDirectiveVisitor" ] ] , ) -> GraphQLSchema : def call_method ( method_name : str , type_ : VisitableSchemaType , * args : Any ) -> Union [ VisitableSchemaType , Literal [ False ] ] : for visitor in visitor_selector ( type_ , method_name ) : new_type = getattr ( visitor , method_name ) ( type_ , * args ) if new_type is None : # Keep going without modifying type. continue if method_name == "visit_schema" or isinstance ( type_ , GraphQLSchema ) : raise ValueError ( f"Method {method_name} cannot replace schema with {new_type}" ) if new_type is False : # Stop the loop and return False form call_method, which will cause # the type to be removed from the schema. del type_ return False # Update type to the new type returned by the visitor method, so that # later directives will see the new type, and call_method will return # the final type. type_ = new_type # If there were no directives for this type object, or if all visitor # methods returned nothing, type will be returned unmodified. return type_ def visit ( # pylint: disable=too-many-return-statements type_ : VisitableSchemaType , ) -> Union [ VisitableSchemaType , Literal [ False ] ] : """
        Recursive helper function that calls any appropriate visitor methods for
        each object in the schema, then traverses the object's children (if any).
        """ if isinstance ( type_ , GraphQLSchema ) : # Unlike the other types, the root GraphQLSchema object cannot be # replaced by visitor methods, because that would make life very hard # for SchemaVisitor subclasses that rely on the original schema object. call_method ( "visit_schema" , type_ ) def _start ( named_type , type_name ) : if not type_name . startswith ( "__" ) : visit ( named_type ) update_each_key ( type_ . type_map , _start ) return type_ if isinstance ( type_ , GraphQLObjectType ) : # Note that call_method('visit_object', type_) may not actually call any # methods, if there are no @directive annotations associated with this # type, or if this SchemaDirectiveVisitor subclass does not override # the visit_object method. new_object = cast ( GraphQLObjectType , call_method ( "visit_object" , type_ ) ) if new_object : visit_fields ( new_object ) return new_object if isinstance ( type_ , GraphQLInterfaceType ) : new_interface = cast ( GraphQLInterfaceType , call_method ( "visit_interface" , type_ ) ) if new_interface : visit_fields ( new_interface ) return new_interface if isinstance ( type_ , GraphQLInputObjectType ) : new_input_object = cast ( GraphQLInputObjectType , call_method ( "visit_input_object" , type_ ) ) if new_input_object : update_each_key ( new_input_object . fields , lambda field , n : call_method ( "visit_input_field_definition" , field , new_input_object ) , ) return new_input_object if isinstance ( type_ , GraphQLScalarType ) : return call_method ( "visit_scalar" , type_ ) if isinstance ( type_ , GraphQLUnionType ) : return call_method ( "visit_union" , type_ ) if isinstance ( type_ , GraphQLEnumType ) : new_enum = cast ( GraphQLEnumType , call_method ( "visit_enum" , type_ ) ) if new_enum : update_each_key ( new_enum . values , lambda value , name : call_method ( "visit_enum_value" , value , name ) , ) return new_enum raise ValueError ( f"Unexpected schema type: {type_}" ) def visit_fields ( type_ : Union [ GraphQLObjectType , GraphQLInterfaceType ] ) : def _update_fields ( field , _ ) : # It would be nice if we could call visit(field) recursively here, but # GraphQLField is merely a type, not a value that can be detected using # an instanceof check, so we have to visit the fields in this lexical # context, so that TypeScript can validate the call to # visit_field_definition. new_field = call_method ( "visit_field_definition" , field , type_ ) # While any field visitor needs a reference to the field object, some # field visitors may also need to know the enclosing (parent) type, # perhaps to determine if the parent is a GraphQLObjectType or a # GraphQLInterfaceType. To obtain a reference to the parent, a # visitor method can have a second parameter, which will be reeferring # to the parent. if new_field and new_field . args : update_each_key ( new_field . args , lambda arg , _ : call_method ( "visit_argument_definition" , arg , new_field , type_ ) , ) return new_field update_each_key ( type_ . fields , _update_fields ) visit ( schema ) # Return the original schema for convenience, even though it cannot have # been replaced or removed by the code above. return schema