@classmethod
def __prepare__(metacls, name, bases, **kwargs):
    namespace = super().__prepare__(name, bases, **kwargs)
    namespace['_rfm_bases'] = [b for b in bases if hasattr(b, '_rfm_var_space')]
    local_param_space = namespaces.LocalNamespace()
    namespace['_rfm_local_param_space'] = local_param_space
    namespace['parameter'] = parameters.TestParam
    local_var_space = namespaces.LocalNamespace()
    namespace['_rfm_local_var_space'] = local_var_space
    namespace['variable'] = variables.TestVar
    namespace['required'] = variables.Undefined
    namespace['_rfm_ext_bound'] = set()

    def bind(fn, name=None):
        'Directive to bind a free function to a class.\n\n            See online docs for more information.\n\n            .. note::\n               Functions bound using this directive must be re-inspected after\n               the class body execution has completed. This directive attaches\n               the external method into the class namespace and returns the\n               associated instance of the :class:`WrappedFunction`. However,\n               this instance may be further modified by other ReFrame builtins\n               such as :func:`run_before`, :func:`run_after`, :func:`final` and\n               so on after it was added to the namespace, which would bypass\n               the logic implemented in the :func:`__setitem__` method from the\n               :class:`MetaNamespace` class. Hence, we track the items set by\n               this directive in the ``_rfm_ext_bound`` set, so they can be\n               later re-inspected.\n            '
        inst = metacls.WrappedFunction(fn, name)
        namespace[inst.__name__] = inst
        namespace['_rfm_ext_bound'].add(inst.__name__)
        return inst

    def final(fn):
        'Indicate that a function is final and cannot be overridden.'
        fn._rfm_final = True
        return fn
    namespace['bind'] = bind
    namespace['final'] = final
    namespace['_rfm_final_methods'] = set()

    def run_before(stage):
        'Decorator for attaching a test method to a given stage.\n\n            See online docs for more information.\n            '
        return hooks.attach_to(('pre_' + stage))

    def run_after(stage):
        'Decorator for attaching a test method to a given stage.\n\n            See online docs for more information.\n            '
        return hooks.attach_to(('post_' + stage))
    namespace['run_before'] = run_before
    namespace['run_after'] = run_after
    namespace['require_deps'] = hooks.require_deps
    namespace['_rfm_hook_registry'] = hooks.HookRegistry()

    def sanity_function(fn):
        "Mark a function as the test's sanity function.\n\n            Decorated functions must be unary and they will be converted into\n            deferred expressions.\n            "
        _def_fn = deferrable(fn)
        setattr(_def_fn, '_rfm_sanity_fn', True)
        return _def_fn
    namespace['sanity_function'] = sanity_function
    namespace['deferrable'] = deferrable

    def performance_function(units, *, perf_key=None):
        'Decorate a function to extract a performance variable.\n\n            The ``units`` argument indicates the units of the performance\n            variable to be extracted.\n            The ``perf_key`` optional arg will be used as the name of the\n            performance variable. If not provided, the function name will\n            be used as the performance variable name.\n            '
        if (not isinstance(units, str)):
            raise TypeError('performance units must be a string')
        if (perf_key and (not isinstance(perf_key, str))):
            raise TypeError("'perf_key' must be a string")

        def _deco_wrapper(func):
            if (not utils.is_trivially_callable(func, non_def_args=1)):
                raise TypeError(f'performance function {func.__name__!r} has more than one argument without a default value')

            @functools.wraps(func)
            def _perf_fn(*args, **kwargs):
                return _DeferredPerformanceExpression(func, units, *args, **kwargs)
            _perf_key = (perf_key if perf_key else func.__name__)
            setattr(_perf_fn, '_rfm_perf_key', _perf_key)
            return _perf_fn
        return _deco_wrapper
    namespace['performance_function'] = performance_function
    namespace['_rfm_perf_fns'] = namespaces.LocalNamespace()
    return metacls.MetaNamespace(namespace)
@classmethod
def __prepare__(metacls, name, bases, **kwargs):
    namespace = super().__prepare__(name, bases, **kwargs)
    namespace['_rfm_bases'] = [b for b in bases if hasattr(b, '_rfm_var_space')]
    local_param_space = namespaces.LocalNamespace()
    namespace['_rfm_local_param_space'] = local_param_space
    namespace['parameter'] = parameters.TestParam
    local_var_space = namespaces.LocalNamespace()
    namespace['_rfm_local_var_space'] = local_var_space
    namespace['variable'] = variables.TestVar
    namespace['required'] = variables.Undefined
    namespace['_rfm_ext_bound'] = set()

    def bind(fn, name=None):
        'Directive to bind a free function to a class.\n\n            See online docs for more information.\n\n            .. note::\n               Functions bound using this directive must be re-inspected after\n               the class body execution has completed. This directive attaches\n               the external method into the class namespace and returns the\n               associated instance of the :class:`WrappedFunction`. However,\n               this instance may be further modified by other ReFrame builtins\n               such as :func:`run_before`, :func:`run_after`, :func:`final` and\n               so on after it was added to the namespace, which would bypass\n               the logic implemented in the :func:`__setitem__` method from the\n               :class:`MetaNamespace` class. Hence, we track the items set by\n               this directive in the ``_rfm_ext_bound`` set, so they can be\n               later re-inspected.\n            '
        inst = metacls.WrappedFunction(fn, name)
        namespace[inst.__name__] = inst
        namespace['_rfm_ext_bound'].add(inst.__name__)
        return inst

    def final(fn):
        'Indicate that a function is final and cannot be overridden.'
        fn._rfm_final = True
        return fn
    namespace['bind'] = bind
    namespace['final'] = final
    namespace['_rfm_final_methods'] = set()

    def run_before(stage):
        'Decorator for attaching a test method to a given stage.\n\n            See online docs for more information.\n            '
        return hooks.attach_to(('pre_' + stage))

    def run_after(stage):
        'Decorator for attaching a test method to a given stage.\n\n            See online docs for more information.\n            '
        return hooks.attach_to(('post_' + stage))
    namespace['run_before'] = run_before
    namespace['run_after'] = run_after
    namespace['require_deps'] = hooks.require_deps
    namespace['_rfm_hook_registry'] = hooks.HookRegistry()

    def sanity_function(fn):
        "Mark a function as the test's sanity function.\n\n            Decorated functions must be unary and they will be converted into\n            deferred expressions.\n            "
        _def_fn = deferrable(fn)
        setattr(_def_fn, '_rfm_sanity_fn', True)
        return _def_fn
    namespace['sanity_function'] = sanity_function
    namespace['deferrable'] = deferrable

    def performance_function(units, *, perf_key=None):
        'Decorate a function to extract a performance variable.\n\n            The ``units`` argument indicates the units of the performance\n            variable to be extracted.\n            The ``perf_key`` optional arg will be used as the name of the\n            performance variable. If not provided, the function name will\n            be used as the performance variable name.\n            '
        if (not isinstance(units, str)):
            raise TypeError('performance units must be a string')
        if (perf_key and (not isinstance(perf_key, str))):
            raise TypeError("'perf_key' must be a string")

        def _deco_wrapper(func):
            if (not utils.is_trivially_callable(func, non_def_args=1)):
                raise TypeError(f'performance function {func.__name__!r} has more than one argument without a default value')

            @functools.wraps(func)
            def _perf_fn(*args, **kwargs):
                return _DeferredPerformanceExpression(func, units, *args, **kwargs)
            _perf_key = (perf_key if perf_key else func.__name__)
            setattr(_perf_fn, '_rfm_perf_key', _perf_key)
            return _perf_fn
        return _deco_wrapper
    namespace['performance_function'] = performance_function
    namespace['_rfm_perf_fns'] = namespaces.LocalNamespace()
    return metacls.MetaNamespace(namespace)