code: def pre(cond):
      
      cond_args, cond_varargs, cond_varkw, cond_defaults = inspect.getargspec(cond)
      source = inspect.getsource(cond).strip()
  
      def inner(f):
          if enabled:
              # deal with the real function, not a wrapper
              f = getattr(f, 'wrapped_fn', f)
  
              # need to check if 'self' is the first arg,
              # since @pre doesn't want the self param
              member_function = is_member_function(f)
  
              # need metadata for checking defaults
              method_args, method_defaults = inspect.getargspec(f)[0::3]
  
              def check_condition(args, kwargs):
                  cond_kwargs = {}
  
                  if method_defaults is not None and len(method_defaults) > 0 \
                  and len(method_args) - len(method_defaults) <= len(args) < len(method_args):
                      args += method_defaults[len(args) - len(method_args):]
  
                  # collection the args
                  for name, value in zip(cond_args, args[member_function:]):
                      cond_kwargs[name] = value
  
                  # collect the remaining kwargs
                  for name in cond_args:
                      if name not in cond_kwargs:
                          cond_kwargs[name] = kwargs.get(name)
  
                  # test the precondition
                  if not cond(**cond_kwargs):
                      # otherwise raise the exception
                      raise AssertionError('Precondition failure, %s' % source)
  
              # append to the rest of the preconditions attached to this method
              if not hasattr(f, 'preconditions'):
                  f.preconditions = []
              f.preconditions.append(check_condition)
  
              return check(f)
          else:
              return f
  
      return inner
docs: Add a precondition check to the annotated method. The condition
       is passed the arguments from the annotated method. It does not
       need to accept all of the methods parameters. The condition
       is inspected to figure out which parameters to pass.