code: def type_check(arg_name, pos, reqd_type):
      
  
      def decorator(fn):
  
          # brevity compromised in favour of readability
          def logic(*args, **kwargs):
              arg_count = len(args)
              if arg_count:
                  if pos < arg_count:
                      if isinstance(args[pos], reqd_type):
                          return fn(*args, **kwargs)
                      else:
                          raise TypeError("'{0}' at position {1} not of type {2}".format(args[pos], pos, reqd_type))
                  else:
                      if arg_name in kwargs:
                          value = kwargs[arg_name]
                          if isinstance(value, reqd_type):
                              return fn(*args, **kwargs)
                          else:
                              raise TypeError("'{0}' is not of type {1}".format(arg_name, reqd_type))
                      else:
                          # partially applied functions because of incomplete args, let python handle this
                          return fn(*args, **kwargs)
              else:
                  if arg_name in kwargs:
                      value = kwargs[arg_name]
                      if isinstance(value, reqd_type):
                          return fn(*args, **kwargs)
                  else:
                      raise TypeError("'{0}' is not of type {1}".format(arg_name, reqd_type))
  
          return logic
  
      return decorator
docs: allows type checking at runtime for args or kwargs