def decorator(f):

        argspec = getargspec(f)
        if argspec.varargs:
            raise AssertionError("parameter_space() doesn't support *args")
        if argspec.keywords:
            raise AssertionError("parameter_space() doesn't support **kwargs")
        if argspec.defaults:
            raise AssertionError("parameter_space() doesn't support defaults.")

        # Skip over implicit self.
        argnames = argspec.args
        if argnames[0] == 'self':
            argnames = argnames[1:]

        extra = set(params) - set(argnames)
        if extra:
            raise AssertionError(
                "Keywords %s supplied to parameter_space() are "
                "not in function signature." % extra
            )

        unspecified = set(argnames) - set(params)
        if unspecified:
            raise AssertionError(
                "Function arguments %s were not "
                "supplied to parameter_space()." % extra
            )

        def make_param_sets():
            return product(*(params[name] for name in argnames))

        if __fail_fast:
            @wraps(f)
            def wrapped(self):
                for args in make_param_sets():
                    f(self, *args)
            return wrapped
        else:
            @wraps(f)
            def wrapped(*args, **kwargs):
                subtest(make_param_sets(), *argnames)(f)(*args, **kwargs)

        return wrapped