1from __future__ import absolute_import, division, print_function
2
3import functools
4import inspect
5import sys
6import warnings
7from collections import OrderedDict, deque, defaultdict
8from more_itertools import flatten
9
10import attr
11import py
12from py._code.code import FormattedExcinfo
13
14import _pytest
15from _pytest import nodes
16from _pytest._code.code import TerminalRepr
17from _pytest.compat import (
18    NOTSET,
19    exc_clear,
20    _format_args,
21    getfslineno,
22    get_real_func,
23    is_generator,
24    isclass,
25    getimfunc,
26    getlocation,
27    getfuncargnames,
28    safe_getattr,
29    FuncargnamesCompatAttr,
30)
31from _pytest.outcomes import fail, TEST_OUTCOME
32
33FIXTURE_MSG = 'fixtures cannot have "pytest_funcarg__" prefix and be decorated with @pytest.fixture:\n{}'
34
35
36@attr.s(frozen=True)
37class PseudoFixtureDef(object):
38    cached_result = attr.ib()
39    scope = attr.ib()
40
41
42def pytest_sessionstart(session):
43    import _pytest.python
44    import _pytest.nodes
45
46    scopename2class.update(
47        {
48            "class": _pytest.python.Class,
49            "module": _pytest.python.Module,
50            "function": _pytest.nodes.Item,
51            "session": _pytest.main.Session,
52        }
53    )
54    session._fixturemanager = FixtureManager(session)
55
56
57scopename2class = {}
58
59
60scope2props = dict(session=())
61scope2props["module"] = ("fspath", "module")
62scope2props["class"] = scope2props["module"] + ("cls",)
63scope2props["instance"] = scope2props["class"] + ("instance",)
64scope2props["function"] = scope2props["instance"] + ("function", "keywords")
65
66
67def scopeproperty(name=None, doc=None):
68
69    def decoratescope(func):
70        scopename = name or func.__name__
71
72        def provide(self):
73            if func.__name__ in scope2props[self.scope]:
74                return func(self)
75            raise AttributeError(
76                "%s not available in %s-scoped context" % (scopename, self.scope)
77            )
78
79        return property(provide, None, None, func.__doc__)
80
81    return decoratescope
82
83
84def get_scope_node(node, scope):
85    cls = scopename2class.get(scope)
86    if cls is None:
87        raise ValueError("unknown scope")
88    return node.getparent(cls)
89
90
91def add_funcarg_pseudo_fixture_def(collector, metafunc, fixturemanager):
92    # this function will transform all collected calls to a functions
93    # if they use direct funcargs (i.e. direct parametrization)
94    # because we want later test execution to be able to rely on
95    # an existing FixtureDef structure for all arguments.
96    # XXX we can probably avoid this algorithm  if we modify CallSpec2
97    # to directly care for creating the fixturedefs within its methods.
98    if not metafunc._calls[0].funcargs:
99        return  # this function call does not have direct parametrization
100    # collect funcargs of all callspecs into a list of values
101    arg2params = {}
102    arg2scope = {}
103    for callspec in metafunc._calls:
104        for argname, argvalue in callspec.funcargs.items():
105            assert argname not in callspec.params
106            callspec.params[argname] = argvalue
107            arg2params_list = arg2params.setdefault(argname, [])
108            callspec.indices[argname] = len(arg2params_list)
109            arg2params_list.append(argvalue)
110            if argname not in arg2scope:
111                scopenum = callspec._arg2scopenum.get(argname, scopenum_function)
112                arg2scope[argname] = scopes[scopenum]
113        callspec.funcargs.clear()
114
115    # register artificial FixtureDef's so that later at test execution
116    # time we can rely on a proper FixtureDef to exist for fixture setup.
117    arg2fixturedefs = metafunc._arg2fixturedefs
118    for argname, valuelist in arg2params.items():
119        # if we have a scope that is higher than function we need
120        # to make sure we only ever create an according fixturedef on
121        # a per-scope basis. We thus store and cache the fixturedef on the
122        # node related to the scope.
123        scope = arg2scope[argname]
124        node = None
125        if scope != "function":
126            node = get_scope_node(collector, scope)
127            if node is None:
128                assert scope == "class" and isinstance(collector, _pytest.python.Module)
129                # use module-level collector for class-scope (for now)
130                node = collector
131        if node and argname in node._name2pseudofixturedef:
132            arg2fixturedefs[argname] = [node._name2pseudofixturedef[argname]]
133        else:
134            fixturedef = FixtureDef(
135                fixturemanager,
136                "",
137                argname,
138                get_direct_param_fixture_func,
139                arg2scope[argname],
140                valuelist,
141                False,
142                False,
143            )
144            arg2fixturedefs[argname] = [fixturedef]
145            if node is not None:
146                node._name2pseudofixturedef[argname] = fixturedef
147
148
149def getfixturemarker(obj):
150    """ return fixturemarker or None if it doesn't exist or raised
151    exceptions."""
152    try:
153        return getattr(obj, "_pytestfixturefunction", None)
154    except TEST_OUTCOME:
155        # some objects raise errors like request (from flask import request)
156        # we don't expect them to be fixture functions
157        return None
158
159
160def get_parametrized_fixture_keys(item, scopenum):
161    """ return list of keys for all parametrized arguments which match
162    the specified scope. """
163    assert scopenum < scopenum_function  # function
164    try:
165        cs = item.callspec
166    except AttributeError:
167        pass
168    else:
169        # cs.indices.items() is random order of argnames.  Need to
170        # sort this so that different calls to
171        # get_parametrized_fixture_keys will be deterministic.
172        for argname, param_index in sorted(cs.indices.items()):
173            if cs._arg2scopenum[argname] != scopenum:
174                continue
175            if scopenum == 0:  # session
176                key = (argname, param_index)
177            elif scopenum == 1:  # module
178                key = (argname, param_index, item.fspath)
179            elif scopenum == 2:  # class
180                key = (argname, param_index, item.fspath, item.cls)
181            yield key
182
183
184# algorithm for sorting on a per-parametrized resource setup basis
185# it is called for scopenum==0 (session) first and performs sorting
186# down to the lower scopes such as to minimize number of "high scope"
187# setups and teardowns
188
189
190def reorder_items(items):
191    argkeys_cache = {}
192    items_by_argkey = {}
193    for scopenum in range(0, scopenum_function):
194        argkeys_cache[scopenum] = d = {}
195        items_by_argkey[scopenum] = item_d = defaultdict(deque)
196        for item in items:
197            keys = OrderedDict.fromkeys(get_parametrized_fixture_keys(item, scopenum))
198            if keys:
199                d[item] = keys
200                for key in keys:
201                    item_d[key].append(item)
202    items = OrderedDict.fromkeys(items)
203    return list(reorder_items_atscope(items, argkeys_cache, items_by_argkey, 0))
204
205
206def fix_cache_order(item, argkeys_cache, items_by_argkey):
207    for scopenum in range(0, scopenum_function):
208        for key in argkeys_cache[scopenum].get(item, []):
209            items_by_argkey[scopenum][key].appendleft(item)
210
211
212def reorder_items_atscope(items, argkeys_cache, items_by_argkey, scopenum):
213    if scopenum >= scopenum_function or len(items) < 3:
214        return items
215    ignore = set()
216    items_deque = deque(items)
217    items_done = OrderedDict()
218    scoped_items_by_argkey = items_by_argkey[scopenum]
219    scoped_argkeys_cache = argkeys_cache[scopenum]
220    while items_deque:
221        no_argkey_group = OrderedDict()
222        slicing_argkey = None
223        while items_deque:
224            item = items_deque.popleft()
225            if item in items_done or item in no_argkey_group:
226                continue
227            argkeys = OrderedDict.fromkeys(
228                k for k in scoped_argkeys_cache.get(item, []) if k not in ignore
229            )
230            if not argkeys:
231                no_argkey_group[item] = None
232            else:
233                slicing_argkey, _ = argkeys.popitem()
234                # we don't have to remove relevant items from later in the deque because they'll just be ignored
235                matching_items = [
236                    i for i in scoped_items_by_argkey[slicing_argkey] if i in items
237                ]
238                for i in reversed(matching_items):
239                    fix_cache_order(i, argkeys_cache, items_by_argkey)
240                    items_deque.appendleft(i)
241                break
242        if no_argkey_group:
243            no_argkey_group = reorder_items_atscope(
244                no_argkey_group, argkeys_cache, items_by_argkey, scopenum + 1
245            )
246            for item in no_argkey_group:
247                items_done[item] = None
248        ignore.add(slicing_argkey)
249    return items_done
250
251
252def fillfixtures(function):
253    """ fill missing funcargs for a test function. """
254    try:
255        request = function._request
256    except AttributeError:
257        # XXX this special code path is only expected to execute
258        # with the oejskit plugin.  It uses classes with funcargs
259        # and we thus have to work a bit to allow this.
260        fm = function.session._fixturemanager
261        fi = fm.getfixtureinfo(function.parent, function.obj, None)
262        function._fixtureinfo = fi
263        request = function._request = FixtureRequest(function)
264        request._fillfixtures()
265        # prune out funcargs for jstests
266        newfuncargs = {}
267        for name in fi.argnames:
268            newfuncargs[name] = function.funcargs[name]
269        function.funcargs = newfuncargs
270    else:
271        request._fillfixtures()
272
273
274def get_direct_param_fixture_func(request):
275    return request.param
276
277
278class FuncFixtureInfo(object):
279
280    def __init__(self, argnames, names_closure, name2fixturedefs):
281        self.argnames = argnames
282        self.names_closure = names_closure
283        self.name2fixturedefs = name2fixturedefs
284
285
286class FixtureRequest(FuncargnamesCompatAttr):
287    """ A request for a fixture from a test or fixture function.
288
289    A request object gives access to the requesting test context
290    and has an optional ``param`` attribute in case
291    the fixture is parametrized indirectly.
292    """
293
294    def __init__(self, pyfuncitem):
295        self._pyfuncitem = pyfuncitem
296        #: fixture for which this request is being performed
297        self.fixturename = None
298        #: Scope string, one of "function", "class", "module", "session"
299        self.scope = "function"
300        self._fixture_defs = {}  # argname -> FixtureDef
301        fixtureinfo = pyfuncitem._fixtureinfo
302        self._arg2fixturedefs = fixtureinfo.name2fixturedefs.copy()
303        self._arg2index = {}
304        self._fixturemanager = pyfuncitem.session._fixturemanager
305
306    @property
307    def fixturenames(self):
308        # backward incompatible note: now a readonly property
309        return list(self._pyfuncitem._fixtureinfo.names_closure)
310
311    @property
312    def node(self):
313        """ underlying collection node (depends on current request scope)"""
314        return self._getscopeitem(self.scope)
315
316    def _getnextfixturedef(self, argname):
317        fixturedefs = self._arg2fixturedefs.get(argname, None)
318        if fixturedefs is None:
319            # we arrive here because of a dynamic call to
320            # getfixturevalue(argname) usage which was naturally
321            # not known at parsing/collection time
322            parentid = self._pyfuncitem.parent.nodeid
323            fixturedefs = self._fixturemanager.getfixturedefs(argname, parentid)
324            self._arg2fixturedefs[argname] = fixturedefs
325        # fixturedefs list is immutable so we maintain a decreasing index
326        index = self._arg2index.get(argname, 0) - 1
327        if fixturedefs is None or (-index > len(fixturedefs)):
328            raise FixtureLookupError(argname, self)
329        self._arg2index[argname] = index
330        return fixturedefs[index]
331
332    @property
333    def config(self):
334        """ the pytest config object associated with this request. """
335        return self._pyfuncitem.config
336
337    @scopeproperty()
338    def function(self):
339        """ test function object if the request has a per-function scope. """
340        return self._pyfuncitem.obj
341
342    @scopeproperty("class")
343    def cls(self):
344        """ class (can be None) where the test function was collected. """
345        clscol = self._pyfuncitem.getparent(_pytest.python.Class)
346        if clscol:
347            return clscol.obj
348
349    @property
350    def instance(self):
351        """ instance (can be None) on which test function was collected. """
352        # unittest support hack, see _pytest.unittest.TestCaseFunction
353        try:
354            return self._pyfuncitem._testcase
355        except AttributeError:
356            function = getattr(self, "function", None)
357            return getattr(function, "__self__", None)
358
359    @scopeproperty()
360    def module(self):
361        """ python module object where the test function was collected. """
362        return self._pyfuncitem.getparent(_pytest.python.Module).obj
363
364    @scopeproperty()
365    def fspath(self):
366        """ the file system path of the test module which collected this test. """
367        return self._pyfuncitem.fspath
368
369    @property
370    def keywords(self):
371        """ keywords/markers dictionary for the underlying node. """
372        return self.node.keywords
373
374    @property
375    def session(self):
376        """ pytest session object. """
377        return self._pyfuncitem.session
378
379    def addfinalizer(self, finalizer):
380        """ add finalizer/teardown function to be called after the
381        last test within the requesting test context finished
382        execution. """
383        # XXX usually this method is shadowed by fixturedef specific ones
384        self._addfinalizer(finalizer, scope=self.scope)
385
386    def _addfinalizer(self, finalizer, scope):
387        colitem = self._getscopeitem(scope)
388        self._pyfuncitem.session._setupstate.addfinalizer(
389            finalizer=finalizer, colitem=colitem
390        )
391
392    def applymarker(self, marker):
393        """ Apply a marker to a single test function invocation.
394        This method is useful if you don't want to have a keyword/marker
395        on all function invocations.
396
397        :arg marker: a :py:class:`_pytest.mark.MarkDecorator` object
398            created by a call to ``pytest.mark.NAME(...)``.
399        """
400        self.node.add_marker(marker)
401
402    def raiseerror(self, msg):
403        """ raise a FixtureLookupError with the given message. """
404        raise self._fixturemanager.FixtureLookupError(None, self, msg)
405
406    def _fillfixtures(self):
407        item = self._pyfuncitem
408        fixturenames = getattr(item, "fixturenames", self.fixturenames)
409        for argname in fixturenames:
410            if argname not in item.funcargs:
411                item.funcargs[argname] = self.getfixturevalue(argname)
412
413    def cached_setup(self, setup, teardown=None, scope="module", extrakey=None):
414        """ (deprecated) Return a testing resource managed by ``setup`` &
415        ``teardown`` calls.  ``scope`` and ``extrakey`` determine when the
416        ``teardown`` function will be called so that subsequent calls to
417        ``setup`` would recreate the resource.  With pytest-2.3 you often
418        do not need ``cached_setup()`` as you can directly declare a scope
419        on a fixture function and register a finalizer through
420        ``request.addfinalizer()``.
421
422        :arg teardown: function receiving a previously setup resource.
423        :arg setup: a no-argument function creating a resource.
424        :arg scope: a string value out of ``function``, ``class``, ``module``
425            or ``session`` indicating the caching lifecycle of the resource.
426        :arg extrakey: added to internal caching key of (funcargname, scope).
427        """
428        if not hasattr(self.config, "_setupcache"):
429            self.config._setupcache = {}  # XXX weakref?
430        cachekey = (self.fixturename, self._getscopeitem(scope), extrakey)
431        cache = self.config._setupcache
432        try:
433            val = cache[cachekey]
434        except KeyError:
435            self._check_scope(self.fixturename, self.scope, scope)
436            val = setup()
437            cache[cachekey] = val
438            if teardown is not None:
439
440                def finalizer():
441                    del cache[cachekey]
442                    teardown(val)
443
444                self._addfinalizer(finalizer, scope=scope)
445        return val
446
447    def getfixturevalue(self, argname):
448        """ Dynamically run a named fixture function.
449
450        Declaring fixtures via function argument is recommended where possible.
451        But if you can only decide whether to use another fixture at test
452        setup time, you may use this function to retrieve it inside a fixture
453        or test function body.
454        """
455        return self._get_active_fixturedef(argname).cached_result[0]
456
457    def getfuncargvalue(self, argname):
458        """ Deprecated, use getfixturevalue. """
459        from _pytest import deprecated
460
461        warnings.warn(deprecated.GETFUNCARGVALUE, DeprecationWarning, stacklevel=2)
462        return self.getfixturevalue(argname)
463
464    def _get_active_fixturedef(self, argname):
465        try:
466            return self._fixture_defs[argname]
467        except KeyError:
468            try:
469                fixturedef = self._getnextfixturedef(argname)
470            except FixtureLookupError:
471                if argname == "request":
472                    cached_result = (self, [0], None)
473                    scope = "function"
474                    return PseudoFixtureDef(cached_result, scope)
475                raise
476        # remove indent to prevent the python3 exception
477        # from leaking into the call
478        self._compute_fixture_value(fixturedef)
479        self._fixture_defs[argname] = fixturedef
480        return fixturedef
481
482    def _get_fixturestack(self):
483        current = self
484        values = []
485        while 1:
486            fixturedef = getattr(current, "_fixturedef", None)
487            if fixturedef is None:
488                values.reverse()
489                return values
490            values.append(fixturedef)
491            current = current._parent_request
492
493    def _compute_fixture_value(self, fixturedef):
494        """
495        Creates a SubRequest based on "self" and calls the execute method of the given fixturedef object. This will
496        force the FixtureDef object to throw away any previous results and compute a new fixture value, which
497        will be stored into the FixtureDef object itself.
498
499        :param FixtureDef fixturedef:
500        """
501        # prepare a subrequest object before calling fixture function
502        # (latter managed by fixturedef)
503        argname = fixturedef.argname
504        funcitem = self._pyfuncitem
505        scope = fixturedef.scope
506        try:
507            param = funcitem.callspec.getparam(argname)
508        except (AttributeError, ValueError):
509            param = NOTSET
510            param_index = 0
511            if fixturedef.params is not None:
512                frame = inspect.stack()[3]
513                frameinfo = inspect.getframeinfo(frame[0])
514                source_path = frameinfo.filename
515                source_lineno = frameinfo.lineno
516                source_path = py.path.local(source_path)
517                if source_path.relto(funcitem.config.rootdir):
518                    source_path = source_path.relto(funcitem.config.rootdir)
519                msg = (
520                    "The requested fixture has no parameter defined for the "
521                    "current test.\n\nRequested fixture '{}' defined in:\n{}"
522                    "\n\nRequested here:\n{}:{}".format(
523                        fixturedef.argname,
524                        getlocation(fixturedef.func, funcitem.config.rootdir),
525                        source_path,
526                        source_lineno,
527                    )
528                )
529                fail(msg)
530        else:
531            # indices might not be set if old-style metafunc.addcall() was used
532            param_index = funcitem.callspec.indices.get(argname, 0)
533            # if a parametrize invocation set a scope it will override
534            # the static scope defined with the fixture function
535            paramscopenum = funcitem.callspec._arg2scopenum.get(argname)
536            if paramscopenum is not None:
537                scope = scopes[paramscopenum]
538
539        subrequest = SubRequest(self, scope, param, param_index, fixturedef)
540
541        # check if a higher-level scoped fixture accesses a lower level one
542        subrequest._check_scope(argname, self.scope, scope)
543
544        # clear sys.exc_info before invoking the fixture (python bug?)
545        # if its not explicitly cleared it will leak into the call
546        exc_clear()
547        try:
548            # call the fixture function
549            fixturedef.execute(request=subrequest)
550        finally:
551            # if fixture function failed it might have registered finalizers
552            self.session._setupstate.addfinalizer(
553                functools.partial(fixturedef.finish, request=subrequest),
554                subrequest.node,
555            )
556
557    def _check_scope(self, argname, invoking_scope, requested_scope):
558        if argname == "request":
559            return
560        if scopemismatch(invoking_scope, requested_scope):
561            # try to report something helpful
562            lines = self._factorytraceback()
563            fail(
564                "ScopeMismatch: You tried to access the %r scoped "
565                "fixture %r with a %r scoped request object, "
566                "involved factories\n%s"
567                % ((requested_scope, argname, invoking_scope, "\n".join(lines))),
568                pytrace=False,
569            )
570
571    def _factorytraceback(self):
572        lines = []
573        for fixturedef in self._get_fixturestack():
574            factory = fixturedef.func
575            fs, lineno = getfslineno(factory)
576            p = self._pyfuncitem.session.fspath.bestrelpath(fs)
577            args = _format_args(factory)
578            lines.append("%s:%d:  def %s%s" % (p, lineno, factory.__name__, args))
579        return lines
580
581    def _getscopeitem(self, scope):
582        if scope == "function":
583            # this might also be a non-function Item despite its attribute name
584            return self._pyfuncitem
585        node = get_scope_node(self._pyfuncitem, scope)
586        if node is None and scope == "class":
587            # fallback to function item itself
588            node = self._pyfuncitem
589        assert node, 'Could not obtain a node for scope "{}" for function {!r}'.format(
590            scope, self._pyfuncitem
591        )
592        return node
593
594    def __repr__(self):
595        return "<FixtureRequest for %r>" % (self.node)
596
597
598class SubRequest(FixtureRequest):
599    """ a sub request for handling getting a fixture from a
600    test function/fixture. """
601
602    def __init__(self, request, scope, param, param_index, fixturedef):
603        self._parent_request = request
604        self.fixturename = fixturedef.argname
605        if param is not NOTSET:
606            self.param = param
607        self.param_index = param_index
608        self.scope = scope
609        self._fixturedef = fixturedef
610        self._pyfuncitem = request._pyfuncitem
611        self._fixture_defs = request._fixture_defs
612        self._arg2fixturedefs = request._arg2fixturedefs
613        self._arg2index = request._arg2index
614        self._fixturemanager = request._fixturemanager
615
616    def __repr__(self):
617        return "<SubRequest %r for %r>" % (self.fixturename, self._pyfuncitem)
618
619    def addfinalizer(self, finalizer):
620        self._fixturedef.addfinalizer(finalizer)
621
622
623class ScopeMismatchError(Exception):
624    """ A fixture function tries to use a different fixture function which
625    which has a lower scope (e.g. a Session one calls a function one)
626    """
627
628
629scopes = "session module class function".split()
630scopenum_function = scopes.index("function")
631
632
633def scopemismatch(currentscope, newscope):
634    return scopes.index(newscope) > scopes.index(currentscope)
635
636
637def scope2index(scope, descr, where=None):
638    """Look up the index of ``scope`` and raise a descriptive value error
639    if not defined.
640    """
641    try:
642        return scopes.index(scope)
643    except ValueError:
644        raise ValueError(
645            "{} {}has an unsupported scope value '{}'".format(
646                descr, "from {} ".format(where) if where else "", scope
647            )
648        )
649
650
651class FixtureLookupError(LookupError):
652    """ could not return a requested Fixture (missing or invalid). """
653
654    def __init__(self, argname, request, msg=None):
655        self.argname = argname
656        self.request = request
657        self.fixturestack = request._get_fixturestack()
658        self.msg = msg
659
660    def formatrepr(self):
661        tblines = []
662        addline = tblines.append
663        stack = [self.request._pyfuncitem.obj]
664        stack.extend(map(lambda x: x.func, self.fixturestack))
665        msg = self.msg
666        if msg is not None:
667            # the last fixture raise an error, let's present
668            # it at the requesting side
669            stack = stack[:-1]
670        for function in stack:
671            fspath, lineno = getfslineno(function)
672            try:
673                lines, _ = inspect.getsourcelines(get_real_func(function))
674            except (IOError, IndexError, TypeError):
675                error_msg = "file %s, line %s: source code not available"
676                addline(error_msg % (fspath, lineno + 1))
677            else:
678                addline("file %s, line %s" % (fspath, lineno + 1))
679                for i, line in enumerate(lines):
680                    line = line.rstrip()
681                    addline("  " + line)
682                    if line.lstrip().startswith("def"):
683                        break
684
685        if msg is None:
686            fm = self.request._fixturemanager
687            available = []
688            parentid = self.request._pyfuncitem.parent.nodeid
689            for name, fixturedefs in fm._arg2fixturedefs.items():
690                faclist = list(fm._matchfactories(fixturedefs, parentid))
691                if faclist and name not in available:
692                    available.append(name)
693            msg = "fixture %r not found" % (self.argname,)
694            msg += "\n available fixtures: %s" % (", ".join(sorted(available)),)
695            msg += "\n use 'pytest --fixtures [testpath]' for help on them."
696
697        return FixtureLookupErrorRepr(fspath, lineno, tblines, msg, self.argname)
698
699
700class FixtureLookupErrorRepr(TerminalRepr):
701
702    def __init__(self, filename, firstlineno, tblines, errorstring, argname):
703        self.tblines = tblines
704        self.errorstring = errorstring
705        self.filename = filename
706        self.firstlineno = firstlineno
707        self.argname = argname
708
709    def toterminal(self, tw):
710        # tw.line("FixtureLookupError: %s" %(self.argname), red=True)
711        for tbline in self.tblines:
712            tw.line(tbline.rstrip())
713        lines = self.errorstring.split("\n")
714        if lines:
715            tw.line(
716                "{}       {}".format(FormattedExcinfo.fail_marker, lines[0].strip()),
717                red=True,
718            )
719            for line in lines[1:]:
720                tw.line(
721                    "{}       {}".format(FormattedExcinfo.flow_marker, line.strip()),
722                    red=True,
723                )
724        tw.line()
725        tw.line("%s:%d" % (self.filename, self.firstlineno + 1))
726
727
728def fail_fixturefunc(fixturefunc, msg):
729    fs, lineno = getfslineno(fixturefunc)
730    location = "%s:%s" % (fs, lineno + 1)
731    source = _pytest._code.Source(fixturefunc)
732    fail(msg + ":\n\n" + str(source.indent()) + "\n" + location, pytrace=False)
733
734
735def call_fixture_func(fixturefunc, request, kwargs):
736    yieldctx = is_generator(fixturefunc)
737    if yieldctx:
738        it = fixturefunc(**kwargs)
739        res = next(it)
740
741        def teardown():
742            try:
743                next(it)
744            except StopIteration:
745                pass
746            else:
747                fail_fixturefunc(
748                    fixturefunc, "yield_fixture function has more than one 'yield'"
749                )
750
751        request.addfinalizer(teardown)
752    else:
753        res = fixturefunc(**kwargs)
754    return res
755
756
757class FixtureDef(object):
758    """ A container for a factory definition. """
759
760    def __init__(
761        self,
762        fixturemanager,
763        baseid,
764        argname,
765        func,
766        scope,
767        params,
768        unittest=False,
769        ids=None,
770    ):
771        self._fixturemanager = fixturemanager
772        self.baseid = baseid or ""
773        self.has_location = baseid is not None
774        self.func = func
775        self.argname = argname
776        self.scope = scope
777        self.scopenum = scope2index(
778            scope or "function", descr="fixture {}".format(func.__name__), where=baseid
779        )
780        self.params = params
781        self.argnames = getfuncargnames(func, is_method=unittest)
782        self.unittest = unittest
783        self.ids = ids
784        self._finalizers = []
785
786    def addfinalizer(self, finalizer):
787        self._finalizers.append(finalizer)
788
789    def finish(self, request):
790        exceptions = []
791        try:
792            while self._finalizers:
793                try:
794                    func = self._finalizers.pop()
795                    func()
796                except:  # noqa
797                    exceptions.append(sys.exc_info())
798            if exceptions:
799                e = exceptions[0]
800                del exceptions  # ensure we don't keep all frames alive because of the traceback
801                py.builtin._reraise(*e)
802
803        finally:
804            hook = self._fixturemanager.session.gethookproxy(request.node.fspath)
805            hook.pytest_fixture_post_finalizer(fixturedef=self, request=request)
806            # even if finalization fails, we invalidate
807            # the cached fixture value and remove
808            # all finalizers because they may be bound methods which will
809            # keep instances alive
810            if hasattr(self, "cached_result"):
811                del self.cached_result
812            self._finalizers = []
813
814    def execute(self, request):
815        # get required arguments and register our own finish()
816        # with their finalization
817        for argname in self.argnames:
818            fixturedef = request._get_active_fixturedef(argname)
819            if argname != "request":
820                fixturedef.addfinalizer(functools.partial(self.finish, request=request))
821
822        my_cache_key = request.param_index
823        cached_result = getattr(self, "cached_result", None)
824        if cached_result is not None:
825            result, cache_key, err = cached_result
826            if my_cache_key == cache_key:
827                if err is not None:
828                    py.builtin._reraise(*err)
829                else:
830                    return result
831            # we have a previous but differently parametrized fixture instance
832            # so we need to tear it down before creating a new one
833            self.finish(request)
834            assert not hasattr(self, "cached_result")
835
836        hook = self._fixturemanager.session.gethookproxy(request.node.fspath)
837        return hook.pytest_fixture_setup(fixturedef=self, request=request)
838
839    def __repr__(self):
840        return (
841            "<FixtureDef name=%r scope=%r baseid=%r >"
842            % (self.argname, self.scope, self.baseid)
843        )
844
845
846def pytest_fixture_setup(fixturedef, request):
847    """ Execution of fixture setup. """
848    kwargs = {}
849    for argname in fixturedef.argnames:
850        fixdef = request._get_active_fixturedef(argname)
851        result, arg_cache_key, exc = fixdef.cached_result
852        request._check_scope(argname, request.scope, fixdef.scope)
853        kwargs[argname] = result
854
855    fixturefunc = fixturedef.func
856    if fixturedef.unittest:
857        if request.instance is not None:
858            # bind the unbound method to the TestCase instance
859            fixturefunc = fixturedef.func.__get__(request.instance)
860    else:
861        # the fixture function needs to be bound to the actual
862        # request.instance so that code working with "fixturedef" behaves
863        # as expected.
864        if request.instance is not None:
865            fixturefunc = getimfunc(fixturedef.func)
866            if fixturefunc != fixturedef.func:
867                fixturefunc = fixturefunc.__get__(request.instance)
868    my_cache_key = request.param_index
869    try:
870        result = call_fixture_func(fixturefunc, request, kwargs)
871    except TEST_OUTCOME:
872        fixturedef.cached_result = (None, my_cache_key, sys.exc_info())
873        raise
874    fixturedef.cached_result = (result, my_cache_key, None)
875    return result
876
877
878def _ensure_immutable_ids(ids):
879    if ids is None:
880        return
881    if callable(ids):
882        return ids
883    return tuple(ids)
884
885
886@attr.s(frozen=True)
887class FixtureFunctionMarker(object):
888    scope = attr.ib()
889    params = attr.ib(converter=attr.converters.optional(tuple))
890    autouse = attr.ib(default=False)
891    ids = attr.ib(default=None, converter=_ensure_immutable_ids)
892    name = attr.ib(default=None)
893
894    def __call__(self, function):
895        if isclass(function):
896            raise ValueError("class fixtures not supported (may be in the future)")
897
898        if getattr(function, "_pytestfixturefunction", False):
899            raise ValueError(
900                "fixture is being applied more than once to the same function"
901            )
902
903        function._pytestfixturefunction = self
904        return function
905
906
907def fixture(scope="function", params=None, autouse=False, ids=None, name=None):
908    """Decorator to mark a fixture factory function.
909
910    This decorator can be used (with or without parameters) to define a
911    fixture function.  The name of the fixture function can later be
912    referenced to cause its invocation ahead of running tests: test
913    modules or classes can use the pytest.mark.usefixtures(fixturename)
914    marker.  Test functions can directly use fixture names as input
915    arguments in which case the fixture instance returned from the fixture
916    function will be injected.
917
918    :arg scope: the scope for which this fixture is shared, one of
919                "function" (default), "class", "module" or "session".
920
921    :arg params: an optional list of parameters which will cause multiple
922                invocations of the fixture function and all of the tests
923                using it.
924
925    :arg autouse: if True, the fixture func is activated for all tests that
926                can see it.  If False (the default) then an explicit
927                reference is needed to activate the fixture.
928
929    :arg ids: list of string ids each corresponding to the params
930                so that they are part of the test id. If no ids are provided
931                they will be generated automatically from the params.
932
933    :arg name: the name of the fixture. This defaults to the name of the
934                decorated function. If a fixture is used in the same module in
935                which it is defined, the function name of the fixture will be
936                shadowed by the function arg that requests the fixture; one way
937                to resolve this is to name the decorated function
938                ``fixture_<fixturename>`` and then use
939                ``@pytest.fixture(name='<fixturename>')``.
940
941    Fixtures can optionally provide their values to test functions using a ``yield`` statement,
942    instead of ``return``. In this case, the code block after the ``yield`` statement is executed
943    as teardown code regardless of the test outcome. A fixture function must yield exactly once.
944    """
945    if callable(scope) and params is None and autouse is False:
946        # direct decoration
947        return FixtureFunctionMarker("function", params, autouse, name=name)(scope)
948    if params is not None and not isinstance(params, (list, tuple)):
949        params = list(params)
950    return FixtureFunctionMarker(scope, params, autouse, ids=ids, name=name)
951
952
953def yield_fixture(scope="function", params=None, autouse=False, ids=None, name=None):
954    """ (return a) decorator to mark a yield-fixture factory function.
955
956    .. deprecated:: 3.0
957        Use :py:func:`pytest.fixture` directly instead.
958    """
959    if callable(scope) and params is None and not autouse:
960        # direct decoration
961        return FixtureFunctionMarker("function", params, autouse, ids=ids, name=name)(
962            scope
963        )
964    else:
965        return FixtureFunctionMarker(scope, params, autouse, ids=ids, name=name)
966
967
968defaultfuncargprefixmarker = fixture()
969
970
971@fixture(scope="session")
972def pytestconfig(request):
973    """Session-scoped fixture that returns the :class:`_pytest.config.Config` object.
974
975    Example::
976
977        def test_foo(pytestconfig):
978            if pytestconfig.getoption("verbose"):
979                ...
980
981    """
982    return request.config
983
984
985class FixtureManager(object):
986    """
987    pytest fixtures definitions and information is stored and managed
988    from this class.
989
990    During collection fm.parsefactories() is called multiple times to parse
991    fixture function definitions into FixtureDef objects and internal
992    data structures.
993
994    During collection of test functions, metafunc-mechanics instantiate
995    a FuncFixtureInfo object which is cached per node/func-name.
996    This FuncFixtureInfo object is later retrieved by Function nodes
997    which themselves offer a fixturenames attribute.
998
999    The FuncFixtureInfo object holds information about fixtures and FixtureDefs
1000    relevant for a particular function.  An initial list of fixtures is
1001    assembled like this:
1002
1003    - ini-defined usefixtures
1004    - autouse-marked fixtures along the collection chain up from the function
1005    - usefixtures markers at module/class/function level
1006    - test function funcargs
1007
1008    Subsequently the funcfixtureinfo.fixturenames attribute is computed
1009    as the closure of the fixtures needed to setup the initial fixtures,
1010    i. e. fixtures needed by fixture functions themselves are appended
1011    to the fixturenames list.
1012
1013    Upon the test-setup phases all fixturenames are instantiated, retrieved
1014    by a lookup of their FuncFixtureInfo.
1015    """
1016
1017    _argprefix = "pytest_funcarg__"
1018    FixtureLookupError = FixtureLookupError
1019    FixtureLookupErrorRepr = FixtureLookupErrorRepr
1020
1021    def __init__(self, session):
1022        self.session = session
1023        self.config = session.config
1024        self._arg2fixturedefs = {}
1025        self._holderobjseen = set()
1026        self._arg2finish = {}
1027        self._nodeid_and_autousenames = [("", self.config.getini("usefixtures"))]
1028        session.config.pluginmanager.register(self, "funcmanage")
1029
1030    def getfixtureinfo(self, node, func, cls, funcargs=True):
1031        if funcargs and not getattr(node, "nofuncargs", False):
1032            argnames = getfuncargnames(func, cls=cls)
1033        else:
1034            argnames = ()
1035        usefixtures = flatten(
1036            mark.args for mark in node.iter_markers(name="usefixtures")
1037        )
1038        initialnames = argnames
1039        initialnames = tuple(usefixtures) + initialnames
1040        fm = node.session._fixturemanager
1041        names_closure, arg2fixturedefs = fm.getfixtureclosure(initialnames, node)
1042        return FuncFixtureInfo(argnames, names_closure, arg2fixturedefs)
1043
1044    def pytest_plugin_registered(self, plugin):
1045        nodeid = None
1046        try:
1047            p = py.path.local(plugin.__file__)
1048        except AttributeError:
1049            pass
1050        else:
1051            # construct the base nodeid which is later used to check
1052            # what fixtures are visible for particular tests (as denoted
1053            # by their test id)
1054            if p.basename.startswith("conftest.py"):
1055                nodeid = p.dirpath().relto(self.config.rootdir)
1056                if p.sep != nodes.SEP:
1057                    nodeid = nodeid.replace(p.sep, nodes.SEP)
1058        self.parsefactories(plugin, nodeid)
1059
1060    def _getautousenames(self, nodeid):
1061        """ return a tuple of fixture names to be used. """
1062        autousenames = []
1063        for baseid, basenames in self._nodeid_and_autousenames:
1064            if nodeid.startswith(baseid):
1065                if baseid:
1066                    i = len(baseid)
1067                    nextchar = nodeid[i:i + 1]
1068                    if nextchar and nextchar not in ":/":
1069                        continue
1070                autousenames.extend(basenames)
1071        return autousenames
1072
1073    def getfixtureclosure(self, fixturenames, parentnode):
1074        # collect the closure of all fixtures , starting with the given
1075        # fixturenames as the initial set.  As we have to visit all
1076        # factory definitions anyway, we also return an arg2fixturedefs
1077        # mapping so that the caller can reuse it and does not have
1078        # to re-discover fixturedefs again for each fixturename
1079        # (discovering matching fixtures for a given name/node is expensive)
1080
1081        parentid = parentnode.nodeid
1082        fixturenames_closure = self._getautousenames(parentid)
1083
1084        def merge(otherlist):
1085            for arg in otherlist:
1086                if arg not in fixturenames_closure:
1087                    fixturenames_closure.append(arg)
1088
1089        merge(fixturenames)
1090        arg2fixturedefs = {}
1091        lastlen = -1
1092        while lastlen != len(fixturenames_closure):
1093            lastlen = len(fixturenames_closure)
1094            for argname in fixturenames_closure:
1095                if argname in arg2fixturedefs:
1096                    continue
1097                fixturedefs = self.getfixturedefs(argname, parentid)
1098                if fixturedefs:
1099                    arg2fixturedefs[argname] = fixturedefs
1100                    merge(fixturedefs[-1].argnames)
1101
1102        def sort_by_scope(arg_name):
1103            try:
1104                fixturedefs = arg2fixturedefs[arg_name]
1105            except KeyError:
1106                return scopes.index("function")
1107            else:
1108                return fixturedefs[-1].scopenum
1109
1110        fixturenames_closure.sort(key=sort_by_scope)
1111        return fixturenames_closure, arg2fixturedefs
1112
1113    def pytest_generate_tests(self, metafunc):
1114        for argname in metafunc.fixturenames:
1115            faclist = metafunc._arg2fixturedefs.get(argname)
1116            if faclist:
1117                fixturedef = faclist[-1]
1118                if fixturedef.params is not None:
1119                    parametrize_func = getattr(metafunc.function, "parametrize", None)
1120                    if parametrize_func is not None:
1121                        parametrize_func = parametrize_func.combined
1122                    func_params = getattr(parametrize_func, "args", [[None]])
1123                    func_kwargs = getattr(parametrize_func, "kwargs", {})
1124                    # skip directly parametrized arguments
1125                    if "argnames" in func_kwargs:
1126                        argnames = parametrize_func.kwargs["argnames"]
1127                    else:
1128                        argnames = func_params[0]
1129                    if not isinstance(argnames, (tuple, list)):
1130                        argnames = [x.strip() for x in argnames.split(",") if x.strip()]
1131                    if argname not in func_params and argname not in argnames:
1132                        metafunc.parametrize(
1133                            argname,
1134                            fixturedef.params,
1135                            indirect=True,
1136                            scope=fixturedef.scope,
1137                            ids=fixturedef.ids,
1138                        )
1139            else:
1140                continue  # will raise FixtureLookupError at setup time
1141
1142    def pytest_collection_modifyitems(self, items):
1143        # separate parametrized setups
1144        items[:] = reorder_items(items)
1145
1146    def parsefactories(self, node_or_obj, nodeid=NOTSET, unittest=False):
1147        if nodeid is not NOTSET:
1148            holderobj = node_or_obj
1149        else:
1150            holderobj = node_or_obj.obj
1151            nodeid = node_or_obj.nodeid
1152        if holderobj in self._holderobjseen:
1153            return
1154        self._holderobjseen.add(holderobj)
1155        autousenames = []
1156        for name in dir(holderobj):
1157            # The attribute can be an arbitrary descriptor, so the attribute
1158            # access below can raise. safe_getatt() ignores such exceptions.
1159            obj = safe_getattr(holderobj, name, None)
1160            # fixture functions have a pytest_funcarg__ prefix (pre-2.3 style)
1161            # or are "@pytest.fixture" marked
1162            marker = getfixturemarker(obj)
1163            if marker is None:
1164                if not name.startswith(self._argprefix):
1165                    continue
1166                if not callable(obj):
1167                    continue
1168                marker = defaultfuncargprefixmarker
1169                from _pytest import deprecated
1170
1171                self.config.warn(
1172                    "C1", deprecated.FUNCARG_PREFIX.format(name=name), nodeid=nodeid
1173                )
1174                name = name[len(self._argprefix):]
1175            elif not isinstance(marker, FixtureFunctionMarker):
1176                # magic globals  with __getattr__ might have got us a wrong
1177                # fixture attribute
1178                continue
1179            else:
1180                if marker.name:
1181                    name = marker.name
1182                assert not name.startswith(self._argprefix), FIXTURE_MSG.format(name)
1183
1184            fixture_def = FixtureDef(
1185                self,
1186                nodeid,
1187                name,
1188                obj,
1189                marker.scope,
1190                marker.params,
1191                unittest=unittest,
1192                ids=marker.ids,
1193            )
1194
1195            faclist = self._arg2fixturedefs.setdefault(name, [])
1196            if fixture_def.has_location:
1197                faclist.append(fixture_def)
1198            else:
1199                # fixturedefs with no location are at the front
1200                # so this inserts the current fixturedef after the
1201                # existing fixturedefs from external plugins but
1202                # before the fixturedefs provided in conftests.
1203                i = len([f for f in faclist if not f.has_location])
1204                faclist.insert(i, fixture_def)
1205            if marker.autouse:
1206                autousenames.append(name)
1207
1208        if autousenames:
1209            self._nodeid_and_autousenames.append((nodeid or "", autousenames))
1210
1211    def getfixturedefs(self, argname, nodeid):
1212        """
1213        Gets a list of fixtures which are applicable to the given node id.
1214
1215        :param str argname: name of the fixture to search for
1216        :param str nodeid: full node id of the requesting test.
1217        :return: list[FixtureDef]
1218        """
1219        try:
1220            fixturedefs = self._arg2fixturedefs[argname]
1221        except KeyError:
1222            return None
1223        else:
1224            return tuple(self._matchfactories(fixturedefs, nodeid))
1225
1226    def _matchfactories(self, fixturedefs, nodeid):
1227        for fixturedef in fixturedefs:
1228            if nodes.ischildnode(fixturedef.baseid, nodeid):
1229                yield fixturedef
1230