# Source code for graphene.types.field

    import inspect
    from collections.abc import Mapping
    from functools import partial

    from .argument import Argument, to_arguments
    from .mountedtype import MountedType
    from .resolver import default_resolver
    from .structures import NonNull
    from .unmountedtype import UnmountedType
    from .utils import get_type
    from ..utils.deprecated import warn_deprecation

    base_type = type

    def source_resolver(source, root, info, **args):
        resolved = default_resolver(source, None, root, info, **args)
        if inspect.isfunction(resolved) or inspect.ismethod(resolved):
            return resolved()
        return resolved

    class Field(MountedType):
        """
        Makes a field available on an ObjectType in the GraphQL schema. Any type can be mounted as a
        Field:

        - Object Type
        - Scalar Type
        - Enum
        - Interface
        - Union

        All class attributes of ``graphene.ObjectType`` are implicitly mounted as Field using the below
        arguments.

        .. code:: python

            class Person(ObjectType):
                first_name = graphene.String(required=True)                # implicitly mounted as Field
                last_name = graphene.Field(String, description='Surname')  # explicitly mounted as Field

        args:
            type (class for a graphene.UnmountedType): Must be a class (not an instance) of an
                unmounted graphene type (ex. scalar or object) which is used for the type of this
                field in the GraphQL schema. You can provide a dotted module import path (string)
                to the class instead of the class itself (e.g. to avoid circular import issues).
            args (optional, Dict[str, graphene.Argument]): Arguments that can be input to the field.
                Prefer to use ``**extra_args``, unless you use an argument name that clashes with one
                of the Field arguments presented here (see :ref:`example<ResolverParamGraphQLArguments>`).
            resolver (optional, Callable): A function to get the value for a Field from the parent
                value object. If not set, the default resolver method for the schema is used.
            source (optional, str): attribute name to resolve for this field from the parent value
                object. Alternative to resolver (cannot set both source and resolver).
            deprecation_reason (optional, str): Setting this value indicates that the field is
                depreciated and may provide instruction or reason on how for clients to proceed.
            required (optional, bool): indicates this field as not null in the graphql schema. Same behavior as
                graphene.NonNull. Default False.
            name (optional, str): the name of the GraphQL field (must be unique in a type). Defaults to attribute
                name.
            description (optional, str): the description of the GraphQL field in the schema.
            default_value (optional, Any): Default value to resolve if none set from schema.
            **extra_args (optional, Dict[str, Union[graphene.Argument, graphene.UnmountedType]): any
                additional arguments to mount on the field.
        """

        def __init__(
            self,
            type_,
            args=None,
            resolver=None,
            source=None,
            deprecation_reason=None,
            name=None,
            description=None,
            required=False,
            _creation_counter=None,
            default_value=None,
            **extra_args,
        ):
            super(Field, self).__init__(_creation_counter=_creation_counter)
            assert not args or isinstance(
                args, Mapping
            ), f'Arguments in a field have to be a mapping, received "{args}".'
            assert not (
                source and resolver
            ), "A Field cannot have a source and a resolver in at the same time."
            assert not callable(
                default_value
            ), f'The default value can not be a function but received "{base_type(default_value)}".'

            if required:
                type_ = NonNull(type_)

            # Check if name is actually an argument of the field
            if isinstance(name, (Argument, UnmountedType)):
                extra_args["name"] = name
                name = None

            # Check if source is actually an argument of the field
            if isinstance(source, (Argument, UnmountedType)):
                extra_args["source"] = source
                source = None

            self.name = name
            self._type = type_
            self.args = to_arguments(args or {}, extra_args)
            if source:
                resolver = partial(source_resolver, source)
            self.resolver = resolver
            self.deprecation_reason = deprecation_reason
            self.description = description
            self.default_value = default_value

        @property
        def type(self):
            return get_type(self._type)

        get_resolver = None

        def wrap_resolve(self, parent_resolver):
            """
            Wraps a function resolver, using the ObjectType resolve_{FIELD_NAME}
            (parent_resolver) if the Field definition has no resolver.
            """
            if self.get_resolver is not None:
                warn_deprecation(
                    "The get_resolver method is being deprecated, please rename it to wrap_resolve."
                )
                return self.get_resolver(parent_resolver)

            return self.resolver or parent_resolver

        def wrap_subscribe(self, parent_subscribe):
            """
            Wraps a function subscribe, using the ObjectType subscribe_{FIELD_NAME}
            (parent_subscribe) if the Field definition has no subscribe.
            """
            return parent_subscribe