text: import sys
  from os import PathLike
  from typing import (  # type: ignore
      TYPE_CHECKING,
      AbstractSet,
      Any,
      ClassVar,
      Dict,
      Generator,
      List,
      Mapping,
      NewType,
      Optional,
      Sequence,
      Set,
      Tuple,
      Type,
      Union,
      _eval_type,
      cast,
      get_type_hints,
  )
  
  from typing_extensions import Annotated, Literal
  
  try:
      from typing import _TypingBase as typing_base  # type: ignore
  except ImportError:
      from typing import _Final as typing_base  # type: ignore
  
  try:
      from typing import GenericAlias as TypingGenericAlias  # type: ignore
  except ImportError:
      # python < 3.9 does not have GenericAlias (list[int], tuple[str, ...] and so on)
      TypingGenericAlias = ()
  
  
  if sys.version_info < (3, 7):
      if TYPE_CHECKING:
  
          class ForwardRef:
              def __init__(self, arg: Any):
                  pass
  
              def _eval_type(self, globalns: Any, localns: Any) -> Any:
                  pass
  
      else:
          from typing import _ForwardRef as ForwardRef
  else:
      from typing import ForwardRef
  
  
  if sys.version_info < (3, 7):
  
      def evaluate_forwardref(type_: ForwardRef, globalns: Any, localns: Any) -> Any:
          return type_._eval_type(globalns, localns)
  
  
  elif sys.version_info < (3, 9):
  
      def evaluate_forwardref(type_: ForwardRef, globalns: Any, localns: Any) -> Any:
          return type_._evaluate(globalns, localns)
  
  
  else:
  
      def evaluate_forwardref(type_: ForwardRef, globalns: Any, localns: Any) -> Any:
          # Even though it is the right signature for python 3.9, mypy complains with
          # `error: Too many arguments for "_evaluate" of "ForwardRef"` hence the cast...
          return cast(Any, type_)._evaluate(globalns, localns, set())
  
  
  if sys.version_info < (3, 9):
      # Ensure we always get all the whole `Annotated` hint, not just the annotated type.
      # For 3.6 to 3.8, `get_type_hints` doesn't recognize `typing_extensions.Annotated`,
      # so it already returns the full annotation
      get_all_type_hints = get_type_hints
  
  else:
  
      def get_all_type_hints(obj: Any, globalns: Any = None, localns: Any = None) -> Any:
          return get_type_hints(obj, globalns, localns, include_extras=True)
  
  
  if sys.version_info < (3, 7):
      from typing import Callable as Callable
  
      AnyCallable = Callable[..., Any]
      NoArgAnyCallable = Callable[[], Any]
  else:
      from collections.abc import Callable as Callable
      from typing import Callable as TypingCallable
  
      AnyCallable = TypingCallable[..., Any]
      NoArgAnyCallable = TypingCallable[[], Any]
  
  
  # Annotated[...] is implemented by returning an instance of one of these classes, depending on
  # python/typing_extensions version.
  AnnotatedTypeNames = {'AnnotatedMeta', '_AnnotatedAlias'}
  
  
  if sys.version_info < (3, 8):
  
      def get_origin(t: Type[Any]) -> Optional[Type[Any]]:
          if type(t).__name__ in AnnotatedTypeNames:
              return cast(Type[Any], Annotated)  # mypy complains about _SpecialForm in py3.6
          return getattr(t, '__origin__', None)
  
  
  else:
      from typing import get_origin as _typing_get_origin
  
      def get_origin(tp: Type[Any]) -> Type[Any]:
          """
          We can't directly use `typing.get_origin` since we need a fallback to support
          custom generic classes like `ConstrainedList`
          It should be useless once https://github.com/cython/cython/issues/3537 is
          solved and https://github.com/samuelcolvin/pydantic/pull/1753 is merged.
          """
          if type(tp).__name__ in AnnotatedTypeNames:
              return cast(Type[Any], Annotated)  # mypy complains about _SpecialForm
          return _typing_get_origin(tp) or getattr(tp, '__origin__', None)
  
  
  if sys.version_info < (3, 7):  # noqa: C901 (ignore complexity)
  
      def get_args(t: Type[Any]) -> Tuple[Any, ...]:
          """Simplest get_args compatibility layer possible.
  
          The Python 3.6 typing module does not have `_GenericAlias` so
          this won't work for everything. In particular this will not
          support the `generics` module (we don't support generic models in
          python 3.6).
  
          """
          if type(t).__name__ in AnnotatedTypeNames:
              return t.__args__ + t.__metadata__
          return getattr(t, '__args__', ())
  
  
  elif sys.version_info < (3, 8):  # noqa: C901
      from typing import _GenericAlias
  
      def get_args(t: Type[Any]) -> Tuple[Any, ...]:
          """Compatibility version of get_args for python 3.7.
  
          Mostly compatible with the python 3.8 `typing` module version
          and able to handle almost all use cases.
          """
          if type(t).__name__ in AnnotatedTypeNames:
              return t.__args__ + t.__metadata__
          if isinstance(t, _GenericAlias):
              res = t.__args__
              if t.__origin__ is Callable and res and res[0] is not Ellipsis:
                  res = (list(res[:-1]), res[-1])
              return res
          return getattr(t, '__args__', ())
  
  
  else:
      from typing import get_args as _typing_get_args
  
      def _generic_get_args(tp: Type[Any]) -> Tuple[Any, ...]:
          """
          In python 3.9, `typing.Dict`, `typing.List`, ...
          do have an empty `__args__` by default (instead of the generic ~T for example).
          In order to still support `Dict` for example and consider it as `Dict[Any, Any]`,
          we retrieve the `_nparams` value that tells us how many parameters it needs.
          """
          if hasattr(tp, '_nparams'):
              return (Any,) * tp._nparams
          return ()
  
      def get_args(tp: Type[Any]) -> Tuple[Any, ...]:
          """Get type arguments with all substitutions performed.
  
          For unions, basic simplifications used by Union constructor are performed.
          Examples::
              get_args(Dict[str, int]) == (str, int)
              get_args(int) == ()
              get_args(Union[int, Union[T, int], str][int]) == (int, str)
              get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
              get_args(Callable[[], T][int]) == ([], int)
          """
          if type(tp).__name__ in AnnotatedTypeNames:
              return tp.__args__ + tp.__metadata__
          # the fallback is needed for the same reasons as `get_origin` (see above)
          return _typing_get_args(tp) or getattr(tp, '__args__', ()) or _generic_get_args(tp)
  
  
  if sys.version_info < (3, 10):
  
      def is_union_origin(tp: Type[Any]) -> bool:
          return tp is Union
  
      WithArgsTypes = (TypingGenericAlias,)
  
  else:
      import types
      import typing
  
      def is_union_origin(origin: Type[Any]) -> bool:
          return origin is Union or origin is types.UnionType  # noqa: E721
  
      WithArgsTypes = (typing._GenericAlias, types.GenericAlias, types.UnionType)
  
  
  if sys.version_info < (3, 9):
      StrPath = Union[str, PathLike]
  else:
      StrPath = Union[str, PathLike]
      # TODO: Once we switch to Cython 3 to handle generics properly
      #  (https://github.com/cython/cython/issues/2753), use following lines instead
      #  of the one above
      # # os.PathLike only becomes subscriptable from Python 3.9 onwards
      # StrPath = Union[str, PathLike[str]]
  
  
  if TYPE_CHECKING:
      from .fields import ModelField
  
      TupleGenerator = Generator[Tuple[str, Any], None, None]
      DictStrAny = Dict[str, Any]
      DictAny = Dict[Any, Any]
      SetStr = Set[str]
      ListStr = List[str]
      IntStr = Union[int, str]
      AbstractSetIntStr = AbstractSet[IntStr]
      DictIntStrAny = Dict[IntStr, Any]
      MappingIntStrAny = Mapping[IntStr, Any]
      CallableGenerator = Generator[AnyCallable, None, None]
      ReprArgs = Sequence[Tuple[Optional[str], Any]]
  
  __all__ = (
      'ForwardRef',
      'Callable',
      'AnyCallable',
      'NoArgAnyCallable',
      'NoneType',
      'is_none_type',
      'display_as_type',
      'resolve_annotations',
      'is_callable_type',
      'is_literal_type',
      'all_literal_values',
      'is_namedtuple',
      'is_typeddict',
      'is_new_type',
      'new_type_supertype',
      'is_classvar',
      'update_field_forward_refs',
      'TupleGenerator',
      'DictStrAny',
      'DictAny',
      'SetStr',
      'ListStr',
      'IntStr',
      'AbstractSetIntStr',
      'DictIntStrAny',
      'CallableGenerator',
      'ReprArgs',
      'CallableGenerator',
      'WithArgsTypes',
      'get_args',
      'get_origin',
      'typing_base',
      'get_all_type_hints',
      'is_union_origin',
      'StrPath',
  )
  
  
  NoneType = None.__class__
  
  
  NONE_TYPES: Tuple[Any, Any, Any] = (None, NoneType, Literal[None])
  
  
  if sys.version_info < (3, 8):  # noqa: C901 (ignore complexity)
      # Even though this implementation is slower, we need it for python 3.6/3.7:
      # In python 3.6/3.7 "Literal" is not a builtin type and uses a different
      # mechanism.
      # for this reason `Literal[None] is Literal[None]` evaluates to `False`,
      # breaking the faster implementation used for the other python versions.
  
      def is_none_type(type_: Any) -> bool:
          return type_ in NONE_TYPES
  
  
  else:
  
      def is_none_type(type_: Any) -> bool:
          for none_type in NONE_TYPES:
              if type_ is none_type:
                  return True
          return False
  
  
  def display_as_type(v: Type[Any]) -> str:
      if not isinstance(v, typing_base) and not isinstance(v, WithArgsTypes) and not isinstance(v, type):
          v = v.__class__
  
      if isinstance(v, WithArgsTypes):
          # Generic alias are constructs like `list[int]`
          return str(v).replace('typing.', '')
  
      try:
          return v.__name__
      except AttributeError:
          # happens with typing objects
          return str(v).replace('typing.', '')
  
  
  def resolve_annotations(raw_annotations: Dict[str, Type[Any]], module_name: Optional[str]) -> Dict[str, Type[Any]]:
      """
      Partially taken from typing.get_type_hints.
  
      Resolve string or ForwardRef annotations into type objects if possible.
      """
      base_globals: Optional[Dict[str, Any]] = None
      if module_name:
          try:
              module = sys.modules[module_name]
          except KeyError:
              # happens occasionally, see https://github.com/samuelcolvin/pydantic/issues/2363
              pass
          else:
              base_globals = module.__dict__
  
      annotations = {}
      for name, value in raw_annotations.items():
          if isinstance(value, str):
              if (3, 10) > sys.version_info >= (3, 9, 8) or sys.version_info >= (3, 10, 1):
                  value = ForwardRef(value, is_argument=False, is_class=True)
              elif sys.version_info >= (3, 7):
                  value = ForwardRef(value, is_argument=False)
              else:
                  value = ForwardRef(value)
          try:
              value = _eval_type(value, base_globals, None)
          except NameError:
              # this is ok, it can be fixed with update_forward_refs
              pass
          annotations[name] = value
      return annotations
  
  
  def is_callable_type(type_: Type[Any]) -> bool:
      return type_ is Callable or get_origin(type_) is Callable
  
  
  if sys.version_info >= (3, 7):
  
      def is_literal_type(type_: Type[Any]) -> bool:
          return Literal is not None and get_origin(type_) is Literal
  
      def literal_values(type_: Type[Any]) -> Tuple[Any, ...]:
          return get_args(type_)
  
  
  else:
  
      def is_literal_type(type_: Type[Any]) -> bool:
          return Literal is not None and hasattr(type_, '__values__') and type_ == Literal[type_.__values__]
  
      def literal_values(type_: Type[Any]) -> Tuple[Any, ...]:
          return type_.__values__
  
  
  def all_literal_values(type_: Type[Any]) -> Tuple[Any, ...]:
      """
      This method is used to retrieve all Literal values as
      Literal can be used recursively (see https://www.python.org/dev/peps/pep-0586)
      e.g. `Literal[Literal[Literal[1, 2, 3], "foo"], 5, None]`
      """
      if not is_literal_type(type_):
          return (type_,)
  
      values = literal_values(type_)
      return tuple(x for value in values for x in all_literal_values(value))
  
  
  def is_namedtuple(type_: Type[Any]) -> bool:
      """
      Check if a given class is a named tuple.
      It can be either a `typing.NamedTuple` or `collections.namedtuple`
      """
      from .utils import lenient_issubclass
  
      return lenient_issubclass(type_, tuple) and hasattr(type_, '_fields')
  
  
  def is_typeddict(type_: Type[Any]) -> bool:
      """
      Check if a given class is a typed dict (from `typing` or `typing_extensions`)
      In 3.10, there will be a public method (https://docs.python.org/3.10/library/typing.html#typing.is_typeddict)
      """
      from .utils import lenient_issubclass
  
      return lenient_issubclass(type_, dict) and hasattr(type_, '__total__')
  
  
  test_type = NewType('test_type', str)
  
  
  def is_new_type(type_: Type[Any]) -> bool:
      """
      Check whether type_ was created using typing.NewType
      """
      return isinstance(type_, test_type.__class__) and hasattr(type_, '__supertype__')  # type: ignore
  
  
  def new_type_supertype(type_: Type[Any]) -> Type[Any]:
      while hasattr(type_, '__supertype__'):
          type_ = type_.__supertype__
      return type_
  
  
  def _check_classvar(v: Optional[Type[Any]]) -> bool:
      if v is None:
          return False
  
      return v.__class__ == ClassVar.__class__ and (sys.version_info < (3, 7) or getattr(v, '_name', None) == 'ClassVar')
  
  
  def is_classvar(ann_type: Type[Any]) -> bool:
      return _check_classvar(ann_type) or _check_classvar(get_origin(ann_type))
  
  
  def update_field_forward_refs(field: 'ModelField', globalns: Any, localns: Any) -> None:
      """
      Try to update ForwardRefs on fields based on this ModelField, globalns and localns.
      """
      if field.type_.__class__ == ForwardRef:
          field.type_ = evaluate_forwardref(field.type_, globalns, localns or None)
          field.prepare()
      if field.sub_fields:
          for sub_f in field.sub_fields:
              update_field_forward_refs(sub_f, globalns=globalns, localns=localns)
  
  
  def get_class(type_: Type[Any]) -> Union[None, bool, Type[Any]]:
      """
      Tries to get the class of a Type[T] annotation. Returns True if Type is used
      without brackets. Otherwise returns None.
      """
      try:
          origin = get_origin(type_)
          if origin is None:  # Python 3.6
              origin = type_
          if issubclass(origin, Type):  # type: ignore
              if not get_args(type_) or not isinstance(get_args(type_)[0], type):
                  return True
              return get_args(type_)[0]
      except (AttributeError, TypeError):
          pass
      return None
  