code: def get_type_hints(thing):
      """Like the typing version, but tries harder and never errors.
  
      Tries harder: if the thing to inspect is a class but typing.get_type_hints
      raises an error or returns no hints, then this function will try calling it
      on the __init__ method. This second step often helps with user-defined
      classes on older versions of Python. The third step we take is trying
      to fetch types from the __signature__ property.
      They override any other ones we found earlier.
  
      Never errors: instead of raising TypeError for uninspectable objects, or
      NameError for unresolvable forward references, just return an empty dict.
      """
      if isinstance(thing, partial):
          from hypothesis.internal.reflection import get_signature
  
          bound = set(get_signature(thing.func).parameters).difference(
              get_signature(thing).parameters
          )
          return {
              k: v
              for k, v in get_type_hints(thing.func).items()
              if k not in bound
          }
  
      kwargs = (
          {}
          if sys.version_info[:2] < (3, 9)
          else {"include_extras": True}
      )
  
      try:
          hints = typing.get_type_hints(thing, **kwargs)
      except (AttributeError, TypeError, NameError):  # pragma: no cover
          hints = {}
  
      if inspect.isclass(thing):
          try:
              hints.update(
                  typing.get_type_hints(thing.__init__, **kwargs)
              )
          except (TypeError, NameError, AttributeError):
              pass
  
      try:
          if hasattr(thing, "__signature__"):
              # It is possible for the signature and annotations attributes to
              # differ on an object due to renamed arguments.
              from hypothesis.internal.reflection import get_signature
              from hypothesis.strategies._internal.types import (
                  is_a_type,
              )
  
              vkinds = (
                  inspect.Parameter.VAR_POSITIONAL,
                  inspect.Parameter.VAR_KEYWORD,
              )
              for p in get_signature(thing).parameters.values():
                  if (
                      p.kind not in vkinds
                      and is_a_type(p.annotation)
                      and p.annotation is not p.empty
                  ):
                      p_hint = p.annotation
  
                      # Defer to `get_type_hints` if signature annotation is, or
                      # contains, a forward reference that is otherwise resolved.
                      if any(
                          isinstance(sig_hint, ForwardRef)
                          and not isinstance(hint, ForwardRef)
                          for sig_hint, hint in zip(
                              _hint_and_args(p.annotation),
                              _hint_and_args(hints.get(p.name, Any)),
                          )
                      ):
                          p_hint = hints[p.name]
                      if p.default is None:
                          hints[p.name] = typing.Optional[p_hint]
                      else:
                          hints[p.name] = p_hint
      except (AttributeError, TypeError, NameError):  # pragma: no cover
          pass
  
      return hints
  
imports: import codecs
  import copy
  import dataclasses
  import inspect
  import platform
  import sys
  import typing
  from functools import partial
  from typing import Any, ForwardRef, get_args
label_desc: Use image node_id 8 for calling a global function with example usage: get_type_hints(thing) and returns: hints, unknown