fixtures.py 51 KB

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