code: def accepts(*argtypes, **kwargtypes):
      
  
      theseargtypes = [T.TypeFactory(a) for a in argtypes]
      thesekwargtypes = {k : T.TypeFactory(a) for k,a in kwargtypes.items()}
      def _decorator(func):
          # @accepts decorator
          f = func.__wrapped__ if hasattr(func, "__wrapped__") else func
          try:
              argtypes = inspect.getcallargs(f, *theseargtypes, **thesekwargtypes)
              argtypes = {k: v if issubclass(type(v), T.Type) else T.Constant(v)
                          for k,v in argtypes.items()}
          except TypeError:
              raise E.ArgumentTypeError("Invalid argument specification to @accepts in %s" % func.__qualname__)
          # Support keyword arguments.  Find the name of the **kwargs
          # parameter (not necessarily "kwargs") and set it to be a
          # dictionary of unspecified types.
          kwargname = U.get_func_kwargs_name(func)
          if kwargname in argtypes.keys():
              argtypes[kwargname] = T.KeywordArguments()
          # Support positional arguments.  Find the name of the *args
          # parameter (not necessarily "args") and set it to be an
          # unspecified type.
          posargname = U.get_func_posargs_name(func)
          if posargname in argtypes.keys():
              argtypes[posargname] = T.PositionalArguments() # TODO merge with actual argument names
          if U.has_fun_prop(func, "argtypes"):
              raise ValueError("Cannot set argument types twice")
          U.set_fun_prop(func, "argtypes", argtypes)
          return _wrap(func)
      return _decorator
docs: A function decorator to specify argument types of the function.
  
      Types may be specified either in the order that they appear in the
      function or via keyword arguments (just as if you were calling the
      function).
  
      Example usage:
  
        | @accepts(Positive0)
        | def square_root(x):
        |     ...