Exemple #1
0
 def __init__(
     self,
     fixturemanager,
     baseid,
     argname,
     func,
     scope,
     params,
     unittest=False,
     ids=None,
 ):
     self._fixturemanager = fixturemanager
     self.baseid = baseid or ""
     self.has_location = baseid is not None
     self.func = func
     self.argname = argname
     self.scope = scope
     self.scopenum = scope2index(
         scope or "function",
         descr="Fixture '{}'".format(func.__name__),
         where=baseid,
     )
     self.params = params
     self.argnames = getfuncargnames(func, is_method=unittest)
     self.unittest = unittest
     self.ids = ids
     self._finalizers = []
Exemple #2
0
 def __init__(
     self,
     fixturemanager,
     baseid,
     argname,
     func,
     scope,
     params,
     unittest=False,
     ids=None,
 ):
     self._fixturemanager = fixturemanager
     self.baseid = baseid or ""
     self.has_location = baseid is not None
     self.func = func
     self.argname = argname
     self.scope = scope
     self.scopenum = scope2index(
         scope or "function",
         descr="Fixture '{}'".format(func.__name__),
         where=baseid,
     )
     self.params = params
     self.argnames = getfuncargnames(func, is_method=unittest)
     self.unittest = unittest
     self.ids = ids
     self._finalizers = []
Exemple #3
0
    def decorator(fn: Callable):
        decorated_arg_names = set(getfuncargnames(fn))
        if wrapped_param not in decorated_arg_names:
            raise TypeError(
                f'The decorated method must include an arg named {wrapped_param} '
                f'as the wrapped fixture func.')

        # Don't include the wrapped param in the argspec we expose to pytest
        decorated_arg_names -= {wrapped_param}

        fixture_arg_names = set(getfuncargnames(fixturefunc)) - set(ignore)
        all_arg_names = fixture_arg_names | decorated_arg_names | {'request'}

        def extension_impl(**all_args):
            request = all_args['request']

            ###
            # kwargs requested by the wrapped fixture
            #
            fixture_args = {
                name: value
                for name, value in all_args.items()
                if name in fixture_arg_names
            }

            ###
            # kwargs requested by the decorated method
            #
            decorated_args = {
                name: value
                for name, value in all_args.items()
                if name in decorated_arg_names
            }

            @functools.wraps(fixturefunc)
            def wrapped(**overridden_args):
                kwargs = {
                    **fixture_args,
                    **overridden_args,
                }
                return call_fixture_func(fixturefunc, request, kwargs)

            decorated_args[wrapped_param] = wrapped
            return call_fixture_func(fn, request, decorated_args)

        extension = build_wrapped_method(fn.__name__, all_arg_names, extension_impl)
        return extension
Exemple #4
0
 def test_wrapped_getfuncargnames(self):
     from _pytest.compat import getfuncargnames
     def wrap(f):
         def func():
             pass
         func.__wrapped__ = f
         return func
     @wrap
     def f(x):
         pass
     l = getfuncargnames(f)
     assert l == ("x",)
 def getfixtureinfo(self, node, func, cls, funcargs=True):
     if funcargs and not hasattr(node, "nofuncargs"):
         argnames = getfuncargnames(func, cls=cls)
     else:
         argnames = ()
     usefixtures = getattr(func, "usefixtures", None)
     initialnames = argnames
     if usefixtures is not None:
         initialnames = usefixtures.args + initialnames
     fm = node.session._fixturemanager
     names_closure, arg2fixturedefs = fm.getfixtureclosure(
         initialnames, node)
     return FuncFixtureInfo(argnames, names_closure, arg2fixturedefs)
Exemple #6
0
 def getfixtureinfo(self, node, func, cls, funcargs=True):
     if funcargs and not getattr(node, "nofuncargs", False):
         argnames = getfuncargnames(func, cls=cls)
     else:
         argnames = ()
     usefixtures = flatten(
         mark.args for mark in node.iter_markers(name="usefixtures")
     )
     initialnames = argnames
     initialnames = tuple(usefixtures) + initialnames
     fm = node.session._fixturemanager
     names_closure, arg2fixturedefs = fm.getfixtureclosure(initialnames, node)
     return FuncFixtureInfo(argnames, names_closure, arg2fixturedefs)
Exemple #7
0
 def getfixtureinfo(self, node, func, cls, funcargs=True):
     if funcargs and not getattr(node, "nofuncargs", False):
         argnames = getfuncargnames(func, cls=cls)
     else:
         argnames = ()
     usefixtures = flatten(
         mark.args for mark in node.iter_markers(name="usefixtures"))
     initialnames = tuple(usefixtures) + argnames
     fm = node.session._fixturemanager
     initialnames, names_closure, arg2fixturedefs = fm.getfixtureclosure(
         initialnames, node)
     return FuncFixtureInfo(argnames, initialnames, names_closure,
                            arg2fixturedefs)
Exemple #8
0
 def test_wrapped_getfuncargnames_patching(self):
     from _pytest.compat import getfuncargnames
     def wrap(f):
         def func():
             pass
         func.__wrapped__ = f
         func.patchings = ["qwe"]
         return func
     @wrap
     def f(x, y, z):
         pass
     l = getfuncargnames(f)
     assert l == ("y", "z")
Exemple #9
0
    def it_includes_extended_and_wrapped_args_in_spec(self):
        def fixture(fixture_unique):
            pass

        @wrap_fixture(fixture)
        def extended_fixture(extension_unique, wrapped):
            pass

        args = getfuncargnames(extended_fixture)

        expected = {'fixture_unique', 'extension_unique'}
        actual = set(args) - {'request'}
        assert expected == actual
Exemple #10
0
 def getfixtureinfo(self, node, func, cls, funcargs=True):
     if funcargs and not hasattr(node, "nofuncargs"):
         argnames = getfuncargnames(func, cls=cls)
     else:
         argnames = ()
     usefixtures = getattr(func, "usefixtures", None)
     initialnames = argnames
     if usefixtures is not None:
         initialnames = usefixtures.args + initialnames
     fm = node.session._fixturemanager
     names_closure, arg2fixturedefs = fm.getfixtureclosure(initialnames,
                                                           node)
     return FuncFixtureInfo(argnames, names_closure, arg2fixturedefs)
Exemple #11
0
    def test_getfuncargnames_patching(self):
        from _pytest.compat import getfuncargnames
        from unittest.mock import patch

        class T:
            def original(self, x, y, z):
                pass

        @patch.object(T, "original")
        def f(x, y, z):
            pass

        values = getfuncargnames(f)
        assert values == ("y", "z")
Exemple #12
0
 def __init__(self, fixturemanager, baseid, argname, func, scope, params,
              unittest=False, ids=None):
     self._fixturemanager = fixturemanager
     self.baseid = baseid or ''
     self.has_location = baseid is not None
     self.func = func
     self.argname = argname
     self.scope = scope
     self.scopenum = scopes.index(scope or "function")
     self.params = params
     startindex = unittest and 1 or None
     self.argnames = getfuncargnames(func, startindex=startindex)
     self.unittest = unittest
     self.ids = ids
     self._finalizer = []
 def __init__(self, func):
     self.config = None
     self.function = func
     self.definition = MiniFuncDef(func.__name__)
     self._calls = []
     # non-default parameters
     self.fixturenames = getfuncargnames(func)
     # get parametrization marks
     self.pmarks = get_pytest_parametrize_marks(self.function)
     if self.is_parametrized:
         self.update_callspecs()
         self.required_fixtures = set(self.fixturenames) - set(
             self._calls[0].funcargs)
     else:
         self.required_fixtures = self.fixturenames
Exemple #14
0
    def test_wrapped_getfuncargnames_patching(self):
        from _pytest.compat import getfuncargnames

        def wrap(f):
            def func():
                pass
            func.__wrapped__ = f
            func.patchings = ["qwe"]
            return func

        @wrap
        def f(x, y, z):
            pass

        l = getfuncargnames(f)
        assert l == ("y", "z")
Exemple #15
0
    def test_wrapped_getfuncargnames(self):
        from _pytest.compat import getfuncargnames

        def wrap(f):
            def func():
                pass

            func.__wrapped__ = f
            return func

        @wrap
        def f(x):
            pass

        values = getfuncargnames(f)
        assert values == ("x",)
    def decorator_factory(func):
        """
        py.test introsepects the names of arguments in functions to pass in fixtures
        This means we need to dynamically construct the inner call to `func` to contain
        these names.
        """
        from _pytest.compat import getfuncargnames

        args = getfuncargnames(func)

        monkey_args = set(args + ('monkeypatch', ))

        wrapper_str = trim("""
        @pytest.fixture(autouse={autouse})
        def {fixture_name}({monkey_args}):
            val = func({args})
            if isinstance(path_or_obj, str):
                monkeypatch.setattr(path_or_obj, val, raising=raising)
            elif isinstance(path_or_obj, (tuple, list)):
                for item in path_or_obj:
                    monkeypatch.setattr(item, val, raising=raising)
            else:
                monkeypatch.setattr(path_or_obj, key, value=val, raising=raising)
            return val
        """).format(
            fixture_name=func.__name__,
            args=', '.join(args),
            monkey_args=', '.join(monkey_args),
            autouse=repr(autouse)
        )

        # Execute the template string in a temporary namespace and support
        # tracing utilities by setting a value for frame.f_globals['__name__']
        namespace = {
            'func': func,
            'key': key,
            'path_or_obj': path_or_obj,
            'pytest': pytest,
            'raising': raising,
            'wraps': wraps,
            '__name__': 'patcher_%s' % func.__name__,
        }
        exec(wrapper_str, namespace)
        return namespace[func.__name__]
Exemple #17
0
    def decorator_factory(func):
        """
        py.test introsepects the names of arguments in functions to pass in fixtures
        This means we need to dynamically construct the inner call to `func` to contain
        these names.
        """
        from _pytest.compat import getfuncargnames

        args = getfuncargnames(func)

        monkey_args = set(args + ('monkeypatch', ))

        wrapper_str = """
@pytest.fixture(autouse={autouse})
def {fixture_name}({monkey_args}):
    val = func({args})
    if isinstance(path_or_obj, str):
        monkeypatch.setattr(path_or_obj, val, raising=raising)
    elif isinstance(path_or_obj, (tuple, list)):
        for item in path_or_obj:
            monkeypatch.setattr(item, val, raising=raising)
    else:
        monkeypatch.setattr(path_or_obj, key, value=val, raising=raising)
    return val
        """.format(
            fixture_name=func.__name__,
            args=', '.join(args),
            monkey_args=', '.join(monkey_args),
            autouse=repr(autouse)
        )

        # Execute the template string in a temporary namespace and support
        # tracing utilities by setting a value for frame.f_globals['__name__']
        namespace = {
            'func': func,
            'key': key,
            'path_or_obj': path_or_obj,
            'pytest': pytest,
            'raising': raising,
            'wraps': wraps,
            '__name__': 'patcher_%s' % func.__name__,
        }
        exec(wrapper_str, namespace)
        return namespace[func.__name__]
 def __init__(self, fixturemanager, baseid, argname, func, scope, params,
              unittest=False, ids=None):
     self._fixturemanager = fixturemanager
     self.baseid = baseid or ''
     self.has_location = baseid is not None
     self.func = func
     self.argname = argname
     self.scope = scope
     self.scopenum = scope2index(
         scope or "function",
         descr='fixture {0}'.format(func.__name__),
         where=baseid
     )
     self.params = params
     startindex = unittest and 1 or None
     self.argnames = getfuncargnames(func, startindex=startindex)
     self.unittest = unittest
     self.ids = ids
     self._finalizer = []
    def __init__(self, func):
        from .plugin import PYTEST_CONFIG  # late import to ensure config has been loaded by now

        self.config = PYTEST_CONFIG
        self.function = func
        self.definition = MiniFuncDef(func.__name__)
        self._calls = []
        # non-default parameters
        self.fixturenames = getfuncargnames(func)
        # add declared used fixtures with @pytest.mark.usefixtures
        self.fixturenames_not_in_sig = [f for f in get_pytest_usefixture_marks(func) if f not in self.fixturenames]
        if self.fixturenames_not_in_sig:
            self.fixturenames = tuple(self.fixturenames_not_in_sig + list(self.fixturenames))
        # get parametrization marks
        self.pmarks = get_pytest_parametrize_marks(self.function)
        if self.is_parametrized:
            self.update_callspecs()
            # preserve order
            self.required_fixtures = tuple(f for f in self.fixturenames if f not in self._calls[0].funcargs)
        else:
            self.required_fixtures = self.fixturenames
Exemple #20
0
    def __init__(self, func):
        from .plugin import PYTEST_CONFIG  # late import to ensure config has been loaded by now

        self.config = PYTEST_CONFIG

        # self.config can be `None` if the same module is reloaded by another thread/process inside a test (parallelism)
        # In that case, a priori we are outside the pytest main runner so we can silently ignore, this
        # MetaFunc will not be used/read by anyone.
        # See https://github.com/smarie/python-pytest-cases/issues/242
        #
        # if self.config is None:
        #     if pytest_is_running():
        #             raise ValueError("Internal error - config has not been correctly loaded. Please report")

        self.function = func
        self.definition = MiniFuncDef(func.__name__)
        self._calls = []
        # non-default parameters
        self.fixturenames = getfuncargnames(func)
        # add declared used fixtures with @pytest.mark.usefixtures
        self.fixturenames_not_in_sig = [
            f for f in get_pytest_usefixture_marks(func)
            if f not in self.fixturenames
        ]
        if self.fixturenames_not_in_sig:
            self.fixturenames = tuple(self.fixturenames_not_in_sig +
                                      list(self.fixturenames))
        # get parametrization marks
        self.pmarks = get_pytest_parametrize_marks(self.function)
        if self.is_parametrized:
            self.update_callspecs()
            # preserve order
            self.required_fixtures = tuple(f for f in self.fixturenames
                                           if f not in self._calls[0].funcargs)
        else:
            self.required_fixtures = self.fixturenames