python.py 87 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301
  1. """ Python test discovery, setup and run of test functions. """
  2. import fnmatch
  3. import functools
  4. import inspect
  5. import re
  6. import types
  7. import sys
  8. import py
  9. import pytest
  10. from _pytest._code.code import TerminalRepr
  11. from _pytest.mark import MarkDecorator, MarkerError
  12. try:
  13. import enum
  14. except ImportError: # pragma: no cover
  15. # Only available in Python 3.4+ or as a backport
  16. enum = None
  17. import _pytest
  18. import _pytest._pluggy as pluggy
  19. cutdir2 = py.path.local(_pytest.__file__).dirpath()
  20. cutdir1 = py.path.local(pluggy.__file__.rstrip("oc"))
  21. NoneType = type(None)
  22. NOTSET = object()
  23. isfunction = inspect.isfunction
  24. isclass = inspect.isclass
  25. callable = py.builtin.callable
  26. # used to work around a python2 exception info leak
  27. exc_clear = getattr(sys, 'exc_clear', lambda: None)
  28. # The type of re.compile objects is not exposed in Python.
  29. REGEX_TYPE = type(re.compile(''))
  30. _PY3 = sys.version_info > (3, 0)
  31. _PY2 = not _PY3
  32. if hasattr(inspect, 'signature'):
  33. def _format_args(func):
  34. return str(inspect.signature(func))
  35. else:
  36. def _format_args(func):
  37. return inspect.formatargspec(*inspect.getargspec(func))
  38. if sys.version_info[:2] == (2, 6):
  39. def isclass(object):
  40. """ Return true if the object is a class. Overrides inspect.isclass for
  41. python 2.6 because it will return True for objects which always return
  42. something on __getattr__ calls (see #1035).
  43. Backport of https://hg.python.org/cpython/rev/35bf8f7a8edc
  44. """
  45. return isinstance(object, (type, types.ClassType))
  46. def _has_positional_arg(func):
  47. return func.__code__.co_argcount
  48. def filter_traceback(entry):
  49. # entry.path might sometimes return a str object when the entry
  50. # points to dynamically generated code
  51. # see https://bitbucket.org/pytest-dev/py/issues/71
  52. raw_filename = entry.frame.code.raw.co_filename
  53. is_generated = '<' in raw_filename and '>' in raw_filename
  54. if is_generated:
  55. return False
  56. # entry.path might point to an inexisting file, in which case it will
  57. # alsso return a str object. see #1133
  58. p = py.path.local(entry.path)
  59. return p != cutdir1 and not p.relto(cutdir2)
  60. def get_real_func(obj):
  61. """ gets the real function object of the (possibly) wrapped object by
  62. functools.wraps or functools.partial.
  63. """
  64. while hasattr(obj, "__wrapped__"):
  65. obj = obj.__wrapped__
  66. if isinstance(obj, functools.partial):
  67. obj = obj.func
  68. return obj
  69. def getfslineno(obj):
  70. # xxx let decorators etc specify a sane ordering
  71. obj = get_real_func(obj)
  72. if hasattr(obj, 'place_as'):
  73. obj = obj.place_as
  74. fslineno = _pytest._code.getfslineno(obj)
  75. assert isinstance(fslineno[1], int), obj
  76. return fslineno
  77. def getimfunc(func):
  78. try:
  79. return func.__func__
  80. except AttributeError:
  81. try:
  82. return func.im_func
  83. except AttributeError:
  84. return func
  85. def safe_getattr(object, name, default):
  86. """ Like getattr but return default upon any Exception.
  87. Attribute access can potentially fail for 'evil' Python objects.
  88. See issue214
  89. """
  90. try:
  91. return getattr(object, name, default)
  92. except Exception:
  93. return default
  94. class FixtureFunctionMarker:
  95. def __init__(self, scope, params,
  96. autouse=False, yieldctx=False, ids=None):
  97. self.scope = scope
  98. self.params = params
  99. self.autouse = autouse
  100. self.yieldctx = yieldctx
  101. self.ids = ids
  102. def __call__(self, function):
  103. if isclass(function):
  104. raise ValueError(
  105. "class fixtures not supported (may be in the future)")
  106. function._pytestfixturefunction = self
  107. return function
  108. def fixture(scope="function", params=None, autouse=False, ids=None):
  109. """ (return a) decorator to mark a fixture factory function.
  110. This decorator can be used (with or or without parameters) to define
  111. a fixture function. The name of the fixture function can later be
  112. referenced to cause its invocation ahead of running tests: test
  113. modules or classes can use the pytest.mark.usefixtures(fixturename)
  114. marker. Test functions can directly use fixture names as input
  115. arguments in which case the fixture instance returned from the fixture
  116. function will be injected.
  117. :arg scope: the scope for which this fixture is shared, one of
  118. "function" (default), "class", "module", "session".
  119. :arg params: an optional list of parameters which will cause multiple
  120. invocations of the fixture function and all of the tests
  121. using it.
  122. :arg autouse: if True, the fixture func is activated for all tests that
  123. can see it. If False (the default) then an explicit
  124. reference is needed to activate the fixture.
  125. :arg ids: list of string ids each corresponding to the params
  126. so that they are part of the test id. If no ids are provided
  127. they will be generated automatically from the params.
  128. """
  129. if callable(scope) and params is None and autouse == False:
  130. # direct decoration
  131. return FixtureFunctionMarker(
  132. "function", params, autouse)(scope)
  133. if params is not None and not isinstance(params, (list, tuple)):
  134. params = list(params)
  135. return FixtureFunctionMarker(scope, params, autouse, ids=ids)
  136. def yield_fixture(scope="function", params=None, autouse=False, ids=None):
  137. """ (return a) decorator to mark a yield-fixture factory function
  138. (EXPERIMENTAL).
  139. This takes the same arguments as :py:func:`pytest.fixture` but
  140. expects a fixture function to use a ``yield`` instead of a ``return``
  141. statement to provide a fixture. See
  142. http://pytest.org/en/latest/yieldfixture.html for more info.
  143. """
  144. if callable(scope) and params is None and autouse == False:
  145. # direct decoration
  146. return FixtureFunctionMarker(
  147. "function", params, autouse, yieldctx=True)(scope)
  148. else:
  149. return FixtureFunctionMarker(scope, params, autouse,
  150. yieldctx=True, ids=ids)
  151. defaultfuncargprefixmarker = fixture()
  152. def pyobj_property(name):
  153. def get(self):
  154. node = self.getparent(getattr(pytest, name))
  155. if node is not None:
  156. return node.obj
  157. doc = "python %s object this node was collected from (can be None)." % (
  158. name.lower(),)
  159. return property(get, None, None, doc)
  160. def pytest_addoption(parser):
  161. group = parser.getgroup("general")
  162. group.addoption('--fixtures', '--funcargs',
  163. action="store_true", dest="showfixtures", default=False,
  164. help="show available fixtures, sorted by plugin appearance")
  165. parser.addini("usefixtures", type="args", default=[],
  166. help="list of default fixtures to be used with this project")
  167. parser.addini("python_files", type="args",
  168. default=['test_*.py', '*_test.py'],
  169. help="glob-style file patterns for Python test module discovery")
  170. parser.addini("python_classes", type="args", default=["Test",],
  171. help="prefixes or glob names for Python test class discovery")
  172. parser.addini("python_functions", type="args", default=["test",],
  173. help="prefixes or glob names for Python test function and "
  174. "method discovery")
  175. group.addoption("--import-mode", default="prepend",
  176. choices=["prepend", "append"], dest="importmode",
  177. help="prepend/append to sys.path when importing test modules, "
  178. "default is to prepend.")
  179. def pytest_cmdline_main(config):
  180. if config.option.showfixtures:
  181. showfixtures(config)
  182. return 0
  183. def pytest_generate_tests(metafunc):
  184. # those alternative spellings are common - raise a specific error to alert
  185. # the user
  186. alt_spellings = ['parameterize', 'parametrise', 'parameterise']
  187. for attr in alt_spellings:
  188. if hasattr(metafunc.function, attr):
  189. msg = "{0} has '{1}', spelling should be 'parametrize'"
  190. raise MarkerError(msg.format(metafunc.function.__name__, attr))
  191. try:
  192. markers = metafunc.function.parametrize
  193. except AttributeError:
  194. return
  195. for marker in markers:
  196. metafunc.parametrize(*marker.args, **marker.kwargs)
  197. def pytest_configure(config):
  198. config.addinivalue_line("markers",
  199. "parametrize(argnames, argvalues): call a test function multiple "
  200. "times passing in different arguments in turn. argvalues generally "
  201. "needs to be a list of values if argnames specifies only one name "
  202. "or a list of tuples of values if argnames specifies multiple names. "
  203. "Example: @parametrize('arg1', [1,2]) would lead to two calls of the "
  204. "decorated test function, one with arg1=1 and another with arg1=2."
  205. "see http://pytest.org/latest/parametrize.html for more info and "
  206. "examples."
  207. )
  208. config.addinivalue_line("markers",
  209. "usefixtures(fixturename1, fixturename2, ...): mark tests as needing "
  210. "all of the specified fixtures. see http://pytest.org/latest/fixture.html#usefixtures "
  211. )
  212. def pytest_sessionstart(session):
  213. session._fixturemanager = FixtureManager(session)
  214. @pytest.hookimpl(trylast=True)
  215. def pytest_namespace():
  216. raises.Exception = pytest.fail.Exception
  217. return {
  218. 'fixture': fixture,
  219. 'yield_fixture': yield_fixture,
  220. 'raises' : raises,
  221. 'collect': {
  222. 'Module': Module, 'Class': Class, 'Instance': Instance,
  223. 'Function': Function, 'Generator': Generator,
  224. '_fillfuncargs': fillfixtures}
  225. }
  226. @fixture(scope="session")
  227. def pytestconfig(request):
  228. """ the pytest config object with access to command line opts."""
  229. return request.config
  230. @pytest.hookimpl(trylast=True)
  231. def pytest_pyfunc_call(pyfuncitem):
  232. testfunction = pyfuncitem.obj
  233. if pyfuncitem._isyieldedfunction():
  234. testfunction(*pyfuncitem._args)
  235. else:
  236. funcargs = pyfuncitem.funcargs
  237. testargs = {}
  238. for arg in pyfuncitem._fixtureinfo.argnames:
  239. testargs[arg] = funcargs[arg]
  240. testfunction(**testargs)
  241. return True
  242. def pytest_collect_file(path, parent):
  243. ext = path.ext
  244. if ext == ".py":
  245. if not parent.session.isinitpath(path):
  246. for pat in parent.config.getini('python_files'):
  247. if path.fnmatch(pat):
  248. break
  249. else:
  250. return
  251. ihook = parent.session.gethookproxy(path)
  252. return ihook.pytest_pycollect_makemodule(path=path, parent=parent)
  253. def pytest_pycollect_makemodule(path, parent):
  254. return Module(path, parent)
  255. @pytest.hookimpl(hookwrapper=True)
  256. def pytest_pycollect_makeitem(collector, name, obj):
  257. outcome = yield
  258. res = outcome.get_result()
  259. if res is not None:
  260. raise StopIteration
  261. # nothing was collected elsewhere, let's do it here
  262. if isclass(obj):
  263. if collector.istestclass(obj, name):
  264. Class = collector._getcustomclass("Class")
  265. outcome.force_result(Class(name, parent=collector))
  266. elif collector.istestfunction(obj, name):
  267. # mock seems to store unbound methods (issue473), normalize it
  268. obj = getattr(obj, "__func__", obj)
  269. # We need to try and unwrap the function if it's a functools.partial
  270. # or a funtools.wrapped.
  271. # We musn't if it's been wrapped with mock.patch (python 2 only)
  272. if not (isfunction(obj) or isfunction(get_real_func(obj))):
  273. collector.warn(code="C2", message=
  274. "cannot collect %r because it is not a function."
  275. % name, )
  276. elif getattr(obj, "__test__", True):
  277. if is_generator(obj):
  278. res = Generator(name, parent=collector)
  279. else:
  280. res = list(collector._genfunctions(name, obj))
  281. outcome.force_result(res)
  282. def is_generator(func):
  283. try:
  284. return _pytest._code.getrawcode(func).co_flags & 32 # generator function
  285. except AttributeError: # builtin functions have no bytecode
  286. # assume them to not be generators
  287. return False
  288. class PyobjContext(object):
  289. module = pyobj_property("Module")
  290. cls = pyobj_property("Class")
  291. instance = pyobj_property("Instance")
  292. class PyobjMixin(PyobjContext):
  293. def obj():
  294. def fget(self):
  295. try:
  296. return self._obj
  297. except AttributeError:
  298. self._obj = obj = self._getobj()
  299. return obj
  300. def fset(self, value):
  301. self._obj = value
  302. return property(fget, fset, None, "underlying python object")
  303. obj = obj()
  304. def _getobj(self):
  305. return getattr(self.parent.obj, self.name)
  306. def getmodpath(self, stopatmodule=True, includemodule=False):
  307. """ return python path relative to the containing module. """
  308. chain = self.listchain()
  309. chain.reverse()
  310. parts = []
  311. for node in chain:
  312. if isinstance(node, Instance):
  313. continue
  314. name = node.name
  315. if isinstance(node, Module):
  316. assert name.endswith(".py")
  317. name = name[:-3]
  318. if stopatmodule:
  319. if includemodule:
  320. parts.append(name)
  321. break
  322. parts.append(name)
  323. parts.reverse()
  324. s = ".".join(parts)
  325. return s.replace(".[", "[")
  326. def _getfslineno(self):
  327. return getfslineno(self.obj)
  328. def reportinfo(self):
  329. # XXX caching?
  330. obj = self.obj
  331. compat_co_firstlineno = getattr(obj, 'compat_co_firstlineno', None)
  332. if isinstance(compat_co_firstlineno, int):
  333. # nose compatibility
  334. fspath = sys.modules[obj.__module__].__file__
  335. if fspath.endswith(".pyc"):
  336. fspath = fspath[:-1]
  337. lineno = compat_co_firstlineno
  338. else:
  339. fspath, lineno = getfslineno(obj)
  340. modpath = self.getmodpath()
  341. assert isinstance(lineno, int)
  342. return fspath, lineno, modpath
  343. class PyCollector(PyobjMixin, pytest.Collector):
  344. def funcnamefilter(self, name):
  345. return self._matches_prefix_or_glob_option('python_functions', name)
  346. def isnosetest(self, obj):
  347. """ Look for the __test__ attribute, which is applied by the
  348. @nose.tools.istest decorator
  349. """
  350. # We explicitly check for "is True" here to not mistakenly treat
  351. # classes with a custom __getattr__ returning something truthy (like a
  352. # function) as test classes.
  353. return safe_getattr(obj, '__test__', False) is True
  354. def classnamefilter(self, name):
  355. return self._matches_prefix_or_glob_option('python_classes', name)
  356. def istestfunction(self, obj, name):
  357. return (
  358. (self.funcnamefilter(name) or self.isnosetest(obj)) and
  359. safe_getattr(obj, "__call__", False) and getfixturemarker(obj) is None
  360. )
  361. def istestclass(self, obj, name):
  362. return self.classnamefilter(name) or self.isnosetest(obj)
  363. def _matches_prefix_or_glob_option(self, option_name, name):
  364. """
  365. checks if the given name matches the prefix or glob-pattern defined
  366. in ini configuration.
  367. """
  368. for option in self.config.getini(option_name):
  369. if name.startswith(option):
  370. return True
  371. # check that name looks like a glob-string before calling fnmatch
  372. # because this is called for every name in each collected module,
  373. # and fnmatch is somewhat expensive to call
  374. elif ('*' in option or '?' in option or '[' in option) and \
  375. fnmatch.fnmatch(name, option):
  376. return True
  377. return False
  378. def collect(self):
  379. if not getattr(self.obj, "__test__", True):
  380. return []
  381. # NB. we avoid random getattrs and peek in the __dict__ instead
  382. # (XXX originally introduced from a PyPy need, still true?)
  383. dicts = [getattr(self.obj, '__dict__', {})]
  384. for basecls in inspect.getmro(self.obj.__class__):
  385. dicts.append(basecls.__dict__)
  386. seen = {}
  387. l = []
  388. for dic in dicts:
  389. for name, obj in list(dic.items()):
  390. if name in seen:
  391. continue
  392. seen[name] = True
  393. res = self.makeitem(name, obj)
  394. if res is None:
  395. continue
  396. if not isinstance(res, list):
  397. res = [res]
  398. l.extend(res)
  399. l.sort(key=lambda item: item.reportinfo()[:2])
  400. return l
  401. def makeitem(self, name, obj):
  402. #assert self.ihook.fspath == self.fspath, self
  403. return self.ihook.pytest_pycollect_makeitem(
  404. collector=self, name=name, obj=obj)
  405. def _genfunctions(self, name, funcobj):
  406. module = self.getparent(Module).obj
  407. clscol = self.getparent(Class)
  408. cls = clscol and clscol.obj or None
  409. transfer_markers(funcobj, cls, module)
  410. fm = self.session._fixturemanager
  411. fixtureinfo = fm.getfixtureinfo(self, funcobj, cls)
  412. metafunc = Metafunc(funcobj, fixtureinfo, self.config,
  413. cls=cls, module=module)
  414. methods = []
  415. if hasattr(module, "pytest_generate_tests"):
  416. methods.append(module.pytest_generate_tests)
  417. if hasattr(cls, "pytest_generate_tests"):
  418. methods.append(cls().pytest_generate_tests)
  419. if methods:
  420. self.ihook.pytest_generate_tests.call_extra(methods,
  421. dict(metafunc=metafunc))
  422. else:
  423. self.ihook.pytest_generate_tests(metafunc=metafunc)
  424. Function = self._getcustomclass("Function")
  425. if not metafunc._calls:
  426. yield Function(name, parent=self, fixtureinfo=fixtureinfo)
  427. else:
  428. # add funcargs() as fixturedefs to fixtureinfo.arg2fixturedefs
  429. add_funcarg_pseudo_fixture_def(self, metafunc, fm)
  430. for callspec in metafunc._calls:
  431. subname = "%s[%s]" %(name, callspec.id)
  432. yield Function(name=subname, parent=self,
  433. callspec=callspec, callobj=funcobj,
  434. fixtureinfo=fixtureinfo,
  435. keywords={callspec.id:True})
  436. def add_funcarg_pseudo_fixture_def(collector, metafunc, fixturemanager):
  437. # this function will transform all collected calls to a functions
  438. # if they use direct funcargs (i.e. direct parametrization)
  439. # because we want later test execution to be able to rely on
  440. # an existing FixtureDef structure for all arguments.
  441. # XXX we can probably avoid this algorithm if we modify CallSpec2
  442. # to directly care for creating the fixturedefs within its methods.
  443. if not metafunc._calls[0].funcargs:
  444. return # this function call does not have direct parametrization
  445. # collect funcargs of all callspecs into a list of values
  446. arg2params = {}
  447. arg2scope = {}
  448. for callspec in metafunc._calls:
  449. for argname, argvalue in callspec.funcargs.items():
  450. assert argname not in callspec.params
  451. callspec.params[argname] = argvalue
  452. arg2params_list = arg2params.setdefault(argname, [])
  453. callspec.indices[argname] = len(arg2params_list)
  454. arg2params_list.append(argvalue)
  455. if argname not in arg2scope:
  456. scopenum = callspec._arg2scopenum.get(argname,
  457. scopenum_function)
  458. arg2scope[argname] = scopes[scopenum]
  459. callspec.funcargs.clear()
  460. # register artificial FixtureDef's so that later at test execution
  461. # time we can rely on a proper FixtureDef to exist for fixture setup.
  462. arg2fixturedefs = metafunc._arg2fixturedefs
  463. for argname, valuelist in arg2params.items():
  464. # if we have a scope that is higher than function we need
  465. # to make sure we only ever create an according fixturedef on
  466. # a per-scope basis. We thus store and cache the fixturedef on the
  467. # node related to the scope.
  468. scope = arg2scope[argname]
  469. node = None
  470. if scope != "function":
  471. node = get_scope_node(collector, scope)
  472. if node is None:
  473. assert scope == "class" and isinstance(collector, Module)
  474. # use module-level collector for class-scope (for now)
  475. node = collector
  476. if node and argname in node._name2pseudofixturedef:
  477. arg2fixturedefs[argname] = [node._name2pseudofixturedef[argname]]
  478. else:
  479. fixturedef = FixtureDef(fixturemanager, '', argname,
  480. get_direct_param_fixture_func,
  481. arg2scope[argname],
  482. valuelist, False, False)
  483. arg2fixturedefs[argname] = [fixturedef]
  484. if node is not None:
  485. node._name2pseudofixturedef[argname] = fixturedef
  486. def get_direct_param_fixture_func(request):
  487. return request.param
  488. class FuncFixtureInfo:
  489. def __init__(self, argnames, names_closure, name2fixturedefs):
  490. self.argnames = argnames
  491. self.names_closure = names_closure
  492. self.name2fixturedefs = name2fixturedefs
  493. def _marked(func, mark):
  494. """ Returns True if :func: is already marked with :mark:, False otherwise.
  495. This can happen if marker is applied to class and the test file is
  496. invoked more than once.
  497. """
  498. try:
  499. func_mark = getattr(func, mark.name)
  500. except AttributeError:
  501. return False
  502. return mark.args == func_mark.args and mark.kwargs == func_mark.kwargs
  503. def transfer_markers(funcobj, cls, mod):
  504. # XXX this should rather be code in the mark plugin or the mark
  505. # plugin should merge with the python plugin.
  506. for holder in (cls, mod):
  507. try:
  508. pytestmark = holder.pytestmark
  509. except AttributeError:
  510. continue
  511. if isinstance(pytestmark, list):
  512. for mark in pytestmark:
  513. if not _marked(funcobj, mark):
  514. mark(funcobj)
  515. else:
  516. if not _marked(funcobj, pytestmark):
  517. pytestmark(funcobj)
  518. class Module(pytest.File, PyCollector):
  519. """ Collector for test classes and functions. """
  520. def _getobj(self):
  521. return self._memoizedcall('_obj', self._importtestmodule)
  522. def collect(self):
  523. self.session._fixturemanager.parsefactories(self)
  524. return super(Module, self).collect()
  525. def _importtestmodule(self):
  526. # we assume we are only called once per module
  527. importmode = self.config.getoption("--import-mode")
  528. try:
  529. mod = self.fspath.pyimport(ensuresyspath=importmode)
  530. except SyntaxError:
  531. raise self.CollectError(
  532. _pytest._code.ExceptionInfo().getrepr(style="short"))
  533. except self.fspath.ImportMismatchError:
  534. e = sys.exc_info()[1]
  535. raise self.CollectError(
  536. "import file mismatch:\n"
  537. "imported module %r has this __file__ attribute:\n"
  538. " %s\n"
  539. "which is not the same as the test file we want to collect:\n"
  540. " %s\n"
  541. "HINT: remove __pycache__ / .pyc files and/or use a "
  542. "unique basename for your test file modules"
  543. % e.args
  544. )
  545. #print "imported test module", mod
  546. self.config.pluginmanager.consider_module(mod)
  547. return mod
  548. def setup(self):
  549. setup_module = xunitsetup(self.obj, "setUpModule")
  550. if setup_module is None:
  551. setup_module = xunitsetup(self.obj, "setup_module")
  552. if setup_module is not None:
  553. #XXX: nose compat hack, move to nose plugin
  554. # if it takes a positional arg, its probably a pytest style one
  555. # so we pass the current module object
  556. if _has_positional_arg(setup_module):
  557. setup_module(self.obj)
  558. else:
  559. setup_module()
  560. fin = getattr(self.obj, 'tearDownModule', None)
  561. if fin is None:
  562. fin = getattr(self.obj, 'teardown_module', None)
  563. if fin is not None:
  564. #XXX: nose compat hack, move to nose plugin
  565. # if it takes a positional arg, it's probably a pytest style one
  566. # so we pass the current module object
  567. if _has_positional_arg(fin):
  568. finalizer = lambda: fin(self.obj)
  569. else:
  570. finalizer = fin
  571. self.addfinalizer(finalizer)
  572. class Class(PyCollector):
  573. """ Collector for test methods. """
  574. def collect(self):
  575. if hasinit(self.obj):
  576. self.warn("C1", "cannot collect test class %r because it has a "
  577. "__init__ constructor" % self.obj.__name__)
  578. return []
  579. return [self._getcustomclass("Instance")(name="()", parent=self)]
  580. def setup(self):
  581. setup_class = xunitsetup(self.obj, 'setup_class')
  582. if setup_class is not None:
  583. setup_class = getattr(setup_class, 'im_func', setup_class)
  584. setup_class = getattr(setup_class, '__func__', setup_class)
  585. setup_class(self.obj)
  586. fin_class = getattr(self.obj, 'teardown_class', None)
  587. if fin_class is not None:
  588. fin_class = getattr(fin_class, 'im_func', fin_class)
  589. fin_class = getattr(fin_class, '__func__', fin_class)
  590. self.addfinalizer(lambda: fin_class(self.obj))
  591. class Instance(PyCollector):
  592. def _getobj(self):
  593. obj = self.parent.obj()
  594. return obj
  595. def collect(self):
  596. self.session._fixturemanager.parsefactories(self)
  597. return super(Instance, self).collect()
  598. def newinstance(self):
  599. self.obj = self._getobj()
  600. return self.obj
  601. class FunctionMixin(PyobjMixin):
  602. """ mixin for the code common to Function and Generator.
  603. """
  604. def setup(self):
  605. """ perform setup for this test function. """
  606. if hasattr(self, '_preservedparent'):
  607. obj = self._preservedparent
  608. elif isinstance(self.parent, Instance):
  609. obj = self.parent.newinstance()
  610. self.obj = self._getobj()
  611. else:
  612. obj = self.parent.obj
  613. if inspect.ismethod(self.obj):
  614. setup_name = 'setup_method'
  615. teardown_name = 'teardown_method'
  616. else:
  617. setup_name = 'setup_function'
  618. teardown_name = 'teardown_function'
  619. setup_func_or_method = xunitsetup(obj, setup_name)
  620. if setup_func_or_method is not None:
  621. setup_func_or_method(self.obj)
  622. fin = getattr(obj, teardown_name, None)
  623. if fin is not None:
  624. self.addfinalizer(lambda: fin(self.obj))
  625. def _prunetraceback(self, excinfo):
  626. if hasattr(self, '_obj') and not self.config.option.fulltrace:
  627. code = _pytest._code.Code(get_real_func(self.obj))
  628. path, firstlineno = code.path, code.firstlineno
  629. traceback = excinfo.traceback
  630. ntraceback = traceback.cut(path=path, firstlineno=firstlineno)
  631. if ntraceback == traceback:
  632. ntraceback = ntraceback.cut(path=path)
  633. if ntraceback == traceback:
  634. #ntraceback = ntraceback.cut(excludepath=cutdir2)
  635. ntraceback = ntraceback.filter(filter_traceback)
  636. if not ntraceback:
  637. ntraceback = traceback
  638. excinfo.traceback = ntraceback.filter()
  639. # issue364: mark all but first and last frames to
  640. # only show a single-line message for each frame
  641. if self.config.option.tbstyle == "auto":
  642. if len(excinfo.traceback) > 2:
  643. for entry in excinfo.traceback[1:-1]:
  644. entry.set_repr_style('short')
  645. def _repr_failure_py(self, excinfo, style="long"):
  646. if excinfo.errisinstance(pytest.fail.Exception):
  647. if not excinfo.value.pytrace:
  648. return py._builtin._totext(excinfo.value)
  649. return super(FunctionMixin, self)._repr_failure_py(excinfo,
  650. style=style)
  651. def repr_failure(self, excinfo, outerr=None):
  652. assert outerr is None, "XXX outerr usage is deprecated"
  653. style = self.config.option.tbstyle
  654. if style == "auto":
  655. style = "long"
  656. return self._repr_failure_py(excinfo, style=style)
  657. class Generator(FunctionMixin, PyCollector):
  658. def collect(self):
  659. # test generators are seen as collectors but they also
  660. # invoke setup/teardown on popular request
  661. # (induced by the common "test_*" naming shared with normal tests)
  662. self.session._setupstate.prepare(self)
  663. # see FunctionMixin.setup and test_setupstate_is_preserved_134
  664. self._preservedparent = self.parent.obj
  665. l = []
  666. seen = {}
  667. for i, x in enumerate(self.obj()):
  668. name, call, args = self.getcallargs(x)
  669. if not callable(call):
  670. raise TypeError("%r yielded non callable test %r" %(self.obj, call,))
  671. if name is None:
  672. name = "[%d]" % i
  673. else:
  674. name = "['%s']" % name
  675. if name in seen:
  676. raise ValueError("%r generated tests with non-unique name %r" %(self, name))
  677. seen[name] = True
  678. l.append(self.Function(name, self, args=args, callobj=call))
  679. return l
  680. def getcallargs(self, obj):
  681. if not isinstance(obj, (tuple, list)):
  682. obj = (obj,)
  683. # explict naming
  684. if isinstance(obj[0], py.builtin._basestring):
  685. name = obj[0]
  686. obj = obj[1:]
  687. else:
  688. name = None
  689. call, args = obj[0], obj[1:]
  690. return name, call, args
  691. def hasinit(obj):
  692. init = getattr(obj, '__init__', None)
  693. if init:
  694. if init != object.__init__:
  695. return True
  696. def fillfixtures(function):
  697. """ fill missing funcargs for a test function. """
  698. try:
  699. request = function._request
  700. except AttributeError:
  701. # XXX this special code path is only expected to execute
  702. # with the oejskit plugin. It uses classes with funcargs
  703. # and we thus have to work a bit to allow this.
  704. fm = function.session._fixturemanager
  705. fi = fm.getfixtureinfo(function.parent, function.obj, None)
  706. function._fixtureinfo = fi
  707. request = function._request = FixtureRequest(function)
  708. request._fillfixtures()
  709. # prune out funcargs for jstests
  710. newfuncargs = {}
  711. for name in fi.argnames:
  712. newfuncargs[name] = function.funcargs[name]
  713. function.funcargs = newfuncargs
  714. else:
  715. request._fillfixtures()
  716. _notexists = object()
  717. class CallSpec2(object):
  718. def __init__(self, metafunc):
  719. self.metafunc = metafunc
  720. self.funcargs = {}
  721. self._idlist = []
  722. self.params = {}
  723. self._globalid = _notexists
  724. self._globalid_args = set()
  725. self._globalparam = _notexists
  726. self._arg2scopenum = {} # used for sorting parametrized resources
  727. self.keywords = {}
  728. self.indices = {}
  729. def copy(self, metafunc):
  730. cs = CallSpec2(self.metafunc)
  731. cs.funcargs.update(self.funcargs)
  732. cs.params.update(self.params)
  733. cs.keywords.update(self.keywords)
  734. cs.indices.update(self.indices)
  735. cs._arg2scopenum.update(self._arg2scopenum)
  736. cs._idlist = list(self._idlist)
  737. cs._globalid = self._globalid
  738. cs._globalid_args = self._globalid_args
  739. cs._globalparam = self._globalparam
  740. return cs
  741. def _checkargnotcontained(self, arg):
  742. if arg in self.params or arg in self.funcargs:
  743. raise ValueError("duplicate %r" %(arg,))
  744. def getparam(self, name):
  745. try:
  746. return self.params[name]
  747. except KeyError:
  748. if self._globalparam is _notexists:
  749. raise ValueError(name)
  750. return self._globalparam
  751. @property
  752. def id(self):
  753. return "-".join(map(str, filter(None, self._idlist)))
  754. def setmulti(self, valtypes, argnames, valset, id, keywords, scopenum,
  755. param_index):
  756. for arg,val in zip(argnames, valset):
  757. self._checkargnotcontained(arg)
  758. valtype_for_arg = valtypes[arg]
  759. getattr(self, valtype_for_arg)[arg] = val
  760. self.indices[arg] = param_index
  761. self._arg2scopenum[arg] = scopenum
  762. self._idlist.append(id)
  763. self.keywords.update(keywords)
  764. def setall(self, funcargs, id, param):
  765. for x in funcargs:
  766. self._checkargnotcontained(x)
  767. self.funcargs.update(funcargs)
  768. if id is not _notexists:
  769. self._idlist.append(id)
  770. if param is not _notexists:
  771. assert self._globalparam is _notexists
  772. self._globalparam = param
  773. for arg in funcargs:
  774. self._arg2scopenum[arg] = scopenum_function
  775. class FuncargnamesCompatAttr:
  776. """ helper class so that Metafunc, Function and FixtureRequest
  777. don't need to each define the "funcargnames" compatibility attribute.
  778. """
  779. @property
  780. def funcargnames(self):
  781. """ alias attribute for ``fixturenames`` for pre-2.3 compatibility"""
  782. return self.fixturenames
  783. class Metafunc(FuncargnamesCompatAttr):
  784. """
  785. Metafunc objects are passed to the ``pytest_generate_tests`` hook.
  786. They help to inspect a test function and to generate tests according to
  787. test configuration or values specified in the class or module where a
  788. test function is defined.
  789. :ivar fixturenames: set of fixture names required by the test function
  790. :ivar function: underlying python test function
  791. :ivar cls: class object where the test function is defined in or ``None``.
  792. :ivar module: the module object where the test function is defined in.
  793. :ivar config: access to the :class:`_pytest.config.Config` object for the
  794. test session.
  795. :ivar funcargnames:
  796. .. deprecated:: 2.3
  797. Use ``fixturenames`` instead.
  798. """
  799. def __init__(self, function, fixtureinfo, config, cls=None, module=None):
  800. self.config = config
  801. self.module = module
  802. self.function = function
  803. self.fixturenames = fixtureinfo.names_closure
  804. self._arg2fixturedefs = fixtureinfo.name2fixturedefs
  805. self.cls = cls
  806. self._calls = []
  807. self._ids = py.builtin.set()
  808. def parametrize(self, argnames, argvalues, indirect=False, ids=None,
  809. scope=None):
  810. """ Add new invocations to the underlying test function using the list
  811. of argvalues for the given argnames. Parametrization is performed
  812. during the collection phase. If you need to setup expensive resources
  813. see about setting indirect to do it rather at test setup time.
  814. :arg argnames: a comma-separated string denoting one or more argument
  815. names, or a list/tuple of argument strings.
  816. :arg argvalues: The list of argvalues determines how often a
  817. test is invoked with different argument values. If only one
  818. argname was specified argvalues is a list of values. If N
  819. argnames were specified, argvalues must be a list of N-tuples,
  820. where each tuple-element specifies a value for its respective
  821. argname.
  822. :arg indirect: The list of argnames or boolean. A list of arguments'
  823. names (subset of argnames). If True the list contains all names from
  824. the argnames. Each argvalue corresponding to an argname in this list will
  825. be passed as request.param to its respective argname fixture
  826. function so that it can perform more expensive setups during the
  827. setup phase of a test rather than at collection time.
  828. :arg ids: list of string ids, or a callable.
  829. If strings, each is corresponding to the argvalues so that they are
  830. part of the test id.
  831. If callable, it should take one argument (a single argvalue) and return
  832. a string or return None. If None, the automatically generated id for that
  833. argument will be used.
  834. If no ids are provided they will be generated automatically from
  835. the argvalues.
  836. :arg scope: if specified it denotes the scope of the parameters.
  837. The scope is used for grouping tests by parameter instances.
  838. It will also override any fixture-function defined scope, allowing
  839. to set a dynamic scope using test context or configuration.
  840. """
  841. # individual parametrized argument sets can be wrapped in a series
  842. # of markers in which case we unwrap the values and apply the mark
  843. # at Function init
  844. newkeywords = {}
  845. unwrapped_argvalues = []
  846. for i, argval in enumerate(argvalues):
  847. while isinstance(argval, MarkDecorator):
  848. newmark = MarkDecorator(argval.markname,
  849. argval.args[:-1], argval.kwargs)
  850. newmarks = newkeywords.setdefault(i, {})
  851. newmarks[newmark.markname] = newmark
  852. argval = argval.args[-1]
  853. unwrapped_argvalues.append(argval)
  854. argvalues = unwrapped_argvalues
  855. if not isinstance(argnames, (tuple, list)):
  856. argnames = [x.strip() for x in argnames.split(",") if x.strip()]
  857. if len(argnames) == 1:
  858. argvalues = [(val,) for val in argvalues]
  859. if not argvalues:
  860. argvalues = [(_notexists,) * len(argnames)]
  861. # we passed a empty list to parameterize, skip that test
  862. #
  863. fs, lineno = getfslineno(self.function)
  864. newmark = pytest.mark.skip(
  865. reason="got empty parameter set %r, function %s at %s:%d" % (
  866. argnames, self.function.__name__, fs, lineno))
  867. newmarks = newkeywords.setdefault(0, {})
  868. newmarks[newmark.markname] = newmark
  869. if scope is None:
  870. scope = "function"
  871. scopenum = scopes.index(scope)
  872. valtypes = {}
  873. for arg in argnames:
  874. if arg not in self.fixturenames:
  875. raise ValueError("%r uses no fixture %r" %(self.function, arg))
  876. if indirect is True:
  877. valtypes = dict.fromkeys(argnames, "params")
  878. elif indirect is False:
  879. valtypes = dict.fromkeys(argnames, "funcargs")
  880. elif isinstance(indirect, (tuple, list)):
  881. valtypes = dict.fromkeys(argnames, "funcargs")
  882. for arg in indirect:
  883. if arg not in argnames:
  884. raise ValueError("indirect given to %r: fixture %r doesn't exist" %(
  885. self.function, arg))
  886. valtypes[arg] = "params"
  887. idfn = None
  888. if callable(ids):
  889. idfn = ids
  890. ids = None
  891. if ids and len(ids) != len(argvalues):
  892. raise ValueError('%d tests specified with %d ids' %(
  893. len(argvalues), len(ids)))
  894. if not ids:
  895. ids = idmaker(argnames, argvalues, idfn)
  896. newcalls = []
  897. for callspec in self._calls or [CallSpec2(self)]:
  898. for param_index, valset in enumerate(argvalues):
  899. assert len(valset) == len(argnames)
  900. newcallspec = callspec.copy(self)
  901. newcallspec.setmulti(valtypes, argnames, valset, ids[param_index],
  902. newkeywords.get(param_index, {}), scopenum,
  903. param_index)
  904. newcalls.append(newcallspec)
  905. self._calls = newcalls
  906. def addcall(self, funcargs=None, id=_notexists, param=_notexists):
  907. """ (deprecated, use parametrize) Add a new call to the underlying
  908. test function during the collection phase of a test run. Note that
  909. request.addcall() is called during the test collection phase prior and
  910. independently to actual test execution. You should only use addcall()
  911. if you need to specify multiple arguments of a test function.
  912. :arg funcargs: argument keyword dictionary used when invoking
  913. the test function.
  914. :arg id: used for reporting and identification purposes. If you
  915. don't supply an `id` an automatic unique id will be generated.
  916. :arg param: a parameter which will be exposed to a later fixture function
  917. invocation through the ``request.param`` attribute.
  918. """
  919. assert funcargs is None or isinstance(funcargs, dict)
  920. if funcargs is not None:
  921. for name in funcargs:
  922. if name not in self.fixturenames:
  923. pytest.fail("funcarg %r not used in this function." % name)
  924. else:
  925. funcargs = {}
  926. if id is None:
  927. raise ValueError("id=None not allowed")
  928. if id is _notexists:
  929. id = len(self._calls)
  930. id = str(id)
  931. if id in self._ids:
  932. raise ValueError("duplicate id %r" % id)
  933. self._ids.add(id)
  934. cs = CallSpec2(self)
  935. cs.setall(funcargs, id, param)
  936. self._calls.append(cs)
  937. if _PY3:
  938. import codecs
  939. def _escape_bytes(val):
  940. """
  941. If val is pure ascii, returns it as a str(), otherwise escapes
  942. into a sequence of escaped bytes:
  943. b'\xc3\xb4\xc5\xd6' -> u'\\xc3\\xb4\\xc5\\xd6'
  944. note:
  945. the obvious "v.decode('unicode-escape')" will return
  946. valid utf-8 unicode if it finds them in the string, but we
  947. want to return escaped bytes for any byte, even if they match
  948. a utf-8 string.
  949. """
  950. if val:
  951. # source: http://goo.gl/bGsnwC
  952. encoded_bytes, _ = codecs.escape_encode(val)
  953. return encoded_bytes.decode('ascii')
  954. else:
  955. # empty bytes crashes codecs.escape_encode (#1087)
  956. return ''
  957. else:
  958. def _escape_bytes(val):
  959. """
  960. In py2 bytes and str are the same type, so return it unchanged if it
  961. is a full ascii string, otherwise escape it into its binary form.
  962. """
  963. try:
  964. return val.decode('ascii')
  965. except UnicodeDecodeError:
  966. return val.encode('string-escape')
  967. def _idval(val, argname, idx, idfn):
  968. if idfn:
  969. try:
  970. s = idfn(val)
  971. if s:
  972. return s
  973. except Exception:
  974. pass
  975. if isinstance(val, bytes):
  976. return _escape_bytes(val)
  977. elif isinstance(val, (float, int, str, bool, NoneType)):
  978. return str(val)
  979. elif isinstance(val, REGEX_TYPE):
  980. return _escape_bytes(val.pattern) if isinstance(val.pattern, bytes) else val.pattern
  981. elif enum is not None and isinstance(val, enum.Enum):
  982. return str(val)
  983. elif isclass(val) and hasattr(val, '__name__'):
  984. return val.__name__
  985. elif _PY2 and isinstance(val, unicode):
  986. # special case for python 2: if a unicode string is
  987. # convertible to ascii, return it as an str() object instead
  988. try:
  989. return str(val)
  990. except UnicodeError:
  991. # fallthrough
  992. pass
  993. return str(argname)+str(idx)
  994. def _idvalset(idx, valset, argnames, idfn):
  995. this_id = [_idval(val, argname, idx, idfn)
  996. for val, argname in zip(valset, argnames)]
  997. return "-".join(this_id)
  998. def idmaker(argnames, argvalues, idfn=None):
  999. ids = [_idvalset(valindex, valset, argnames, idfn)
  1000. for valindex, valset in enumerate(argvalues)]
  1001. if len(set(ids)) < len(ids):
  1002. # user may have provided a bad idfn which means the ids are not unique
  1003. ids = [str(i) + testid for i, testid in enumerate(ids)]
  1004. return ids
  1005. def showfixtures(config):
  1006. from _pytest.main import wrap_session
  1007. return wrap_session(config, _showfixtures_main)
  1008. def _showfixtures_main(config, session):
  1009. import _pytest.config
  1010. session.perform_collect()
  1011. curdir = py.path.local()
  1012. tw = _pytest.config.create_terminal_writer(config)
  1013. verbose = config.getvalue("verbose")
  1014. fm = session._fixturemanager
  1015. available = []
  1016. for argname, fixturedefs in fm._arg2fixturedefs.items():
  1017. assert fixturedefs is not None
  1018. if not fixturedefs:
  1019. continue
  1020. for fixturedef in fixturedefs:
  1021. loc = getlocation(fixturedef.func, curdir)
  1022. available.append((len(fixturedef.baseid),
  1023. fixturedef.func.__module__,
  1024. curdir.bestrelpath(loc),
  1025. fixturedef.argname, fixturedef))
  1026. available.sort()
  1027. currentmodule = None
  1028. for baseid, module, bestrel, argname, fixturedef in available:
  1029. if currentmodule != module:
  1030. if not module.startswith("_pytest."):
  1031. tw.line()
  1032. tw.sep("-", "fixtures defined from %s" %(module,))
  1033. currentmodule = module
  1034. if verbose <= 0 and argname[0] == "_":
  1035. continue
  1036. if verbose > 0:
  1037. funcargspec = "%s -- %s" %(argname, bestrel,)
  1038. else:
  1039. funcargspec = argname
  1040. tw.line(funcargspec, green=True)
  1041. loc = getlocation(fixturedef.func, curdir)
  1042. doc = fixturedef.func.__doc__ or ""
  1043. if doc:
  1044. for line in doc.strip().split("\n"):
  1045. tw.line(" " + line.strip())
  1046. else:
  1047. tw.line(" %s: no docstring available" %(loc,),
  1048. red=True)
  1049. def getlocation(function, curdir):
  1050. import inspect
  1051. fn = py.path.local(inspect.getfile(function))
  1052. lineno = py.builtin._getcode(function).co_firstlineno
  1053. if fn.relto(curdir):
  1054. fn = fn.relto(curdir)
  1055. return "%s:%d" %(fn, lineno+1)
  1056. # builtin pytest.raises helper
  1057. def raises(expected_exception, *args, **kwargs):
  1058. """ assert that a code block/function call raises ``expected_exception``
  1059. and raise a failure exception otherwise.
  1060. This helper produces a ``ExceptionInfo()`` object (see below).
  1061. If using Python 2.5 or above, you may use this function as a
  1062. context manager::
  1063. >>> with raises(ZeroDivisionError):
  1064. ... 1/0
  1065. .. note::
  1066. When using ``pytest.raises`` as a context manager, it's worthwhile to
  1067. note that normal context manager rules apply and that the exception
  1068. raised *must* be the final line in the scope of the context manager.
  1069. Lines of code after that, within the scope of the context manager will
  1070. not be executed. For example::
  1071. >>> with raises(OSError) as exc_info:
  1072. assert 1 == 1 # this will execute as expected
  1073. raise OSError(errno.EEXISTS, 'directory exists')
  1074. assert exc_info.value.errno == errno.EEXISTS # this will not execute
  1075. Instead, the following approach must be taken (note the difference in
  1076. scope)::
  1077. >>> with raises(OSError) as exc_info:
  1078. assert 1 == 1 # this will execute as expected
  1079. raise OSError(errno.EEXISTS, 'directory exists')
  1080. assert exc_info.value.errno == errno.EEXISTS # this will now execute
  1081. Or you can specify a callable by passing a to-be-called lambda::
  1082. >>> raises(ZeroDivisionError, lambda: 1/0)
  1083. <ExceptionInfo ...>
  1084. or you can specify an arbitrary callable with arguments::
  1085. >>> def f(x): return 1/x
  1086. ...
  1087. >>> raises(ZeroDivisionError, f, 0)
  1088. <ExceptionInfo ...>
  1089. >>> raises(ZeroDivisionError, f, x=0)
  1090. <ExceptionInfo ...>
  1091. A third possibility is to use a string to be executed::
  1092. >>> raises(ZeroDivisionError, "f(0)")
  1093. <ExceptionInfo ...>
  1094. .. autoclass:: _pytest._code.ExceptionInfo
  1095. :members:
  1096. .. note::
  1097. Similar to caught exception objects in Python, explicitly clearing
  1098. local references to returned ``ExceptionInfo`` objects can
  1099. help the Python interpreter speed up its garbage collection.
  1100. Clearing those references breaks a reference cycle
  1101. (``ExceptionInfo`` --> caught exception --> frame stack raising
  1102. the exception --> current frame stack --> local variables -->
  1103. ``ExceptionInfo``) which makes Python keep all objects referenced
  1104. from that cycle (including all local variables in the current
  1105. frame) alive until the next cyclic garbage collection run. See the
  1106. official Python ``try`` statement documentation for more detailed
  1107. information.
  1108. """
  1109. __tracebackhide__ = True
  1110. if expected_exception is AssertionError:
  1111. # we want to catch a AssertionError
  1112. # replace our subclass with the builtin one
  1113. # see https://github.com/pytest-dev/pytest/issues/176
  1114. from _pytest.assertion.util import BuiltinAssertionError \
  1115. as expected_exception
  1116. msg = ("exceptions must be old-style classes or"
  1117. " derived from BaseException, not %s")
  1118. if isinstance(expected_exception, tuple):
  1119. for exc in expected_exception:
  1120. if not isclass(exc):
  1121. raise TypeError(msg % type(exc))
  1122. elif not isclass(expected_exception):
  1123. raise TypeError(msg % type(expected_exception))
  1124. if not args:
  1125. return RaisesContext(expected_exception)
  1126. elif isinstance(args[0], str):
  1127. code, = args
  1128. assert isinstance(code, str)
  1129. frame = sys._getframe(1)
  1130. loc = frame.f_locals.copy()
  1131. loc.update(kwargs)
  1132. #print "raises frame scope: %r" % frame.f_locals
  1133. try:
  1134. code = _pytest._code.Source(code).compile()
  1135. py.builtin.exec_(code, frame.f_globals, loc)
  1136. # XXX didn'T mean f_globals == f_locals something special?
  1137. # this is destroyed here ...
  1138. except expected_exception:
  1139. return _pytest._code.ExceptionInfo()
  1140. else:
  1141. func = args[0]
  1142. try:
  1143. func(*args[1:], **kwargs)
  1144. except expected_exception:
  1145. return _pytest._code.ExceptionInfo()
  1146. pytest.fail("DID NOT RAISE {0}".format(expected_exception))
  1147. class RaisesContext(object):
  1148. def __init__(self, expected_exception):
  1149. self.expected_exception = expected_exception
  1150. self.excinfo = None
  1151. def __enter__(self):
  1152. self.excinfo = object.__new__(_pytest._code.ExceptionInfo)
  1153. return self.excinfo
  1154. def __exit__(self, *tp):
  1155. __tracebackhide__ = True
  1156. if tp[0] is None:
  1157. pytest.fail("DID NOT RAISE")
  1158. if sys.version_info < (2, 7):
  1159. # py26: on __exit__() exc_value often does not contain the
  1160. # exception value.
  1161. # http://bugs.python.org/issue7853
  1162. if not isinstance(tp[1], BaseException):
  1163. exc_type, value, traceback = tp
  1164. tp = exc_type, exc_type(value), traceback
  1165. self.excinfo.__init__(tp)
  1166. return issubclass(self.excinfo.type, self.expected_exception)
  1167. #
  1168. # the basic pytest Function item
  1169. #
  1170. class Function(FunctionMixin, pytest.Item, FuncargnamesCompatAttr):
  1171. """ a Function Item is responsible for setting up and executing a
  1172. Python test function.
  1173. """
  1174. _genid = None
  1175. def __init__(self, name, parent, args=None, config=None,
  1176. callspec=None, callobj=NOTSET, keywords=None, session=None,
  1177. fixtureinfo=None):
  1178. super(Function, self).__init__(name, parent, config=config,
  1179. session=session)
  1180. self._args = args
  1181. if callobj is not NOTSET:
  1182. self.obj = callobj
  1183. self.keywords.update(self.obj.__dict__)
  1184. if callspec:
  1185. self.callspec = callspec
  1186. self.keywords.update(callspec.keywords)
  1187. if keywords:
  1188. self.keywords.update(keywords)
  1189. if fixtureinfo is None:
  1190. fixtureinfo = self.session._fixturemanager.getfixtureinfo(
  1191. self.parent, self.obj, self.cls,
  1192. funcargs=not self._isyieldedfunction())
  1193. self._fixtureinfo = fixtureinfo
  1194. self.fixturenames = fixtureinfo.names_closure
  1195. self._initrequest()
  1196. def _initrequest(self):
  1197. self.funcargs = {}
  1198. if self._isyieldedfunction():
  1199. assert not hasattr(self, "callspec"), (
  1200. "yielded functions (deprecated) cannot have funcargs")
  1201. else:
  1202. if hasattr(self, "callspec"):
  1203. callspec = self.callspec
  1204. assert not callspec.funcargs
  1205. self._genid = callspec.id
  1206. if hasattr(callspec, "param"):
  1207. self.param = callspec.param
  1208. self._request = FixtureRequest(self)
  1209. @property
  1210. def function(self):
  1211. "underlying python 'function' object"
  1212. return getattr(self.obj, 'im_func', self.obj)
  1213. def _getobj(self):
  1214. name = self.name
  1215. i = name.find("[") # parametrization
  1216. if i != -1:
  1217. name = name[:i]
  1218. return getattr(self.parent.obj, name)
  1219. @property
  1220. def _pyfuncitem(self):
  1221. "(compatonly) for code expecting pytest-2.2 style request objects"
  1222. return self
  1223. def _isyieldedfunction(self):
  1224. return getattr(self, "_args", None) is not None
  1225. def runtest(self):
  1226. """ execute the underlying test function. """
  1227. self.ihook.pytest_pyfunc_call(pyfuncitem=self)
  1228. def setup(self):
  1229. super(Function, self).setup()
  1230. fillfixtures(self)
  1231. scope2props = dict(session=())
  1232. scope2props["module"] = ("fspath", "module")
  1233. scope2props["class"] = scope2props["module"] + ("cls",)
  1234. scope2props["instance"] = scope2props["class"] + ("instance", )
  1235. scope2props["function"] = scope2props["instance"] + ("function", "keywords")
  1236. def scopeproperty(name=None, doc=None):
  1237. def decoratescope(func):
  1238. scopename = name or func.__name__
  1239. def provide(self):
  1240. if func.__name__ in scope2props[self.scope]:
  1241. return func(self)
  1242. raise AttributeError("%s not available in %s-scoped context" % (
  1243. scopename, self.scope))
  1244. return property(provide, None, None, func.__doc__)
  1245. return decoratescope
  1246. class FixtureRequest(FuncargnamesCompatAttr):
  1247. """ A request for a fixture from a test or fixture function.
  1248. A request object gives access to the requesting test context
  1249. and has an optional ``param`` attribute in case
  1250. the fixture is parametrized indirectly.
  1251. """
  1252. def __init__(self, pyfuncitem):
  1253. self._pyfuncitem = pyfuncitem
  1254. #: fixture for which this request is being performed
  1255. self.fixturename = None
  1256. #: Scope string, one of "function", "class", "module", "session"
  1257. self.scope = "function"
  1258. self._funcargs = {}
  1259. self._fixturedefs = {}
  1260. fixtureinfo = pyfuncitem._fixtureinfo
  1261. self._arg2fixturedefs = fixtureinfo.name2fixturedefs.copy()
  1262. self._arg2index = {}
  1263. self.fixturenames = fixtureinfo.names_closure
  1264. self._fixturemanager = pyfuncitem.session._fixturemanager
  1265. @property
  1266. def node(self):
  1267. """ underlying collection node (depends on current request scope)"""
  1268. return self._getscopeitem(self.scope)
  1269. def _getnextfixturedef(self, argname):
  1270. fixturedefs = self._arg2fixturedefs.get(argname, None)
  1271. if fixturedefs is None:
  1272. # we arrive here because of a a dynamic call to
  1273. # getfuncargvalue(argname) usage which was naturally
  1274. # not known at parsing/collection time
  1275. fixturedefs = self._fixturemanager.getfixturedefs(
  1276. argname, self._pyfuncitem.parent.nodeid)
  1277. self._arg2fixturedefs[argname] = fixturedefs
  1278. # fixturedefs list is immutable so we maintain a decreasing index
  1279. index = self._arg2index.get(argname, 0) - 1
  1280. if fixturedefs is None or (-index > len(fixturedefs)):
  1281. raise FixtureLookupError(argname, self)
  1282. self._arg2index[argname] = index
  1283. return fixturedefs[index]
  1284. @property
  1285. def config(self):
  1286. """ the pytest config object associated with this request. """
  1287. return self._pyfuncitem.config
  1288. @scopeproperty()
  1289. def function(self):
  1290. """ test function object if the request has a per-function scope. """
  1291. return self._pyfuncitem.obj
  1292. @scopeproperty("class")
  1293. def cls(self):
  1294. """ class (can be None) where the test function was collected. """
  1295. clscol = self._pyfuncitem.getparent(pytest.Class)
  1296. if clscol:
  1297. return clscol.obj
  1298. @property
  1299. def instance(self):
  1300. """ instance (can be None) on which test function was collected. """
  1301. # unittest support hack, see _pytest.unittest.TestCaseFunction
  1302. try:
  1303. return self._pyfuncitem._testcase
  1304. except AttributeError:
  1305. function = getattr(self, "function", None)
  1306. if function is not None:
  1307. return py.builtin._getimself(function)
  1308. @scopeproperty()
  1309. def module(self):
  1310. """ python module object where the test function was collected. """
  1311. return self._pyfuncitem.getparent(pytest.Module).obj
  1312. @scopeproperty()
  1313. def fspath(self):
  1314. """ the file system path of the test module which collected this test. """
  1315. return self._pyfuncitem.fspath
  1316. @property
  1317. def keywords(self):
  1318. """ keywords/markers dictionary for the underlying node. """
  1319. return self.node.keywords
  1320. @property
  1321. def session(self):
  1322. """ pytest session object. """
  1323. return self._pyfuncitem.session
  1324. def addfinalizer(self, finalizer):
  1325. """ add finalizer/teardown function to be called after the
  1326. last test within the requesting test context finished
  1327. execution. """
  1328. # XXX usually this method is shadowed by fixturedef specific ones
  1329. self._addfinalizer(finalizer, scope=self.scope)
  1330. def _addfinalizer(self, finalizer, scope):
  1331. colitem = self._getscopeitem(scope)
  1332. self._pyfuncitem.session._setupstate.addfinalizer(
  1333. finalizer=finalizer, colitem=colitem)
  1334. def applymarker(self, marker):
  1335. """ Apply a marker to a single test function invocation.
  1336. This method is useful if you don't want to have a keyword/marker
  1337. on all function invocations.
  1338. :arg marker: a :py:class:`_pytest.mark.MarkDecorator` object
  1339. created by a call to ``pytest.mark.NAME(...)``.
  1340. """
  1341. try:
  1342. self.node.keywords[marker.markname] = marker
  1343. except AttributeError:
  1344. raise ValueError(marker)
  1345. def raiseerror(self, msg):
  1346. """ raise a FixtureLookupError with the given message. """
  1347. raise self._fixturemanager.FixtureLookupError(None, self, msg)
  1348. def _fillfixtures(self):
  1349. item = self._pyfuncitem
  1350. fixturenames = getattr(item, "fixturenames", self.fixturenames)
  1351. for argname in fixturenames:
  1352. if argname not in item.funcargs:
  1353. item.funcargs[argname] = self.getfuncargvalue(argname)
  1354. def cached_setup(self, setup, teardown=None, scope="module", extrakey=None):
  1355. """ (deprecated) Return a testing resource managed by ``setup`` &
  1356. ``teardown`` calls. ``scope`` and ``extrakey`` determine when the
  1357. ``teardown`` function will be called so that subsequent calls to
  1358. ``setup`` would recreate the resource. With pytest-2.3 you often
  1359. do not need ``cached_setup()`` as you can directly declare a scope
  1360. on a fixture function and register a finalizer through
  1361. ``request.addfinalizer()``.
  1362. :arg teardown: function receiving a previously setup resource.
  1363. :arg setup: a no-argument function creating a resource.
  1364. :arg scope: a string value out of ``function``, ``class``, ``module``
  1365. or ``session`` indicating the caching lifecycle of the resource.
  1366. :arg extrakey: added to internal caching key of (funcargname, scope).
  1367. """
  1368. if not hasattr(self.config, '_setupcache'):
  1369. self.config._setupcache = {} # XXX weakref?
  1370. cachekey = (self.fixturename, self._getscopeitem(scope), extrakey)
  1371. cache = self.config._setupcache
  1372. try:
  1373. val = cache[cachekey]
  1374. except KeyError:
  1375. self._check_scope(self.fixturename, self.scope, scope)
  1376. val = setup()
  1377. cache[cachekey] = val
  1378. if teardown is not None:
  1379. def finalizer():
  1380. del cache[cachekey]
  1381. teardown(val)
  1382. self._addfinalizer(finalizer, scope=scope)
  1383. return val
  1384. def getfuncargvalue(self, argname):
  1385. """ Dynamically retrieve a named fixture function argument.
  1386. As of pytest-2.3, it is easier and usually better to access other
  1387. fixture values by stating it as an input argument in the fixture
  1388. function. If you only can decide about using another fixture at test
  1389. setup time, you may use this function to retrieve it inside a fixture
  1390. function body.
  1391. """
  1392. return self._get_active_fixturedef(argname).cached_result[0]
  1393. def _get_active_fixturedef(self, argname):
  1394. try:
  1395. return self._fixturedefs[argname]
  1396. except KeyError:
  1397. try:
  1398. fixturedef = self._getnextfixturedef(argname)
  1399. except FixtureLookupError:
  1400. if argname == "request":
  1401. class PseudoFixtureDef:
  1402. cached_result = (self, [0], None)
  1403. scope = "function"
  1404. return PseudoFixtureDef
  1405. raise
  1406. # remove indent to prevent the python3 exception
  1407. # from leaking into the call
  1408. result = self._getfuncargvalue(fixturedef)
  1409. self._funcargs[argname] = result
  1410. self._fixturedefs[argname] = fixturedef
  1411. return fixturedef
  1412. def _get_fixturestack(self):
  1413. current = self
  1414. l = []
  1415. while 1:
  1416. fixturedef = getattr(current, "_fixturedef", None)
  1417. if fixturedef is None:
  1418. l.reverse()
  1419. return l
  1420. l.append(fixturedef)
  1421. current = current._parent_request
  1422. def _getfuncargvalue(self, fixturedef):
  1423. # prepare a subrequest object before calling fixture function
  1424. # (latter managed by fixturedef)
  1425. argname = fixturedef.argname
  1426. funcitem = self._pyfuncitem
  1427. scope = fixturedef.scope
  1428. try:
  1429. param = funcitem.callspec.getparam(argname)
  1430. except (AttributeError, ValueError):
  1431. param = NOTSET
  1432. param_index = 0
  1433. else:
  1434. # indices might not be set if old-style metafunc.addcall() was used
  1435. param_index = funcitem.callspec.indices.get(argname, 0)
  1436. # if a parametrize invocation set a scope it will override
  1437. # the static scope defined with the fixture function
  1438. paramscopenum = funcitem.callspec._arg2scopenum.get(argname)
  1439. if paramscopenum is not None:
  1440. scope = scopes[paramscopenum]
  1441. subrequest = SubRequest(self, scope, param, param_index, fixturedef)
  1442. # check if a higher-level scoped fixture accesses a lower level one
  1443. subrequest._check_scope(argname, self.scope, scope)
  1444. # clear sys.exc_info before invoking the fixture (python bug?)
  1445. # if its not explicitly cleared it will leak into the call
  1446. exc_clear()
  1447. try:
  1448. # call the fixture function
  1449. val = fixturedef.execute(request=subrequest)
  1450. finally:
  1451. # if fixture function failed it might have registered finalizers
  1452. self.session._setupstate.addfinalizer(fixturedef.finish,
  1453. subrequest.node)
  1454. return val
  1455. def _check_scope(self, argname, invoking_scope, requested_scope):
  1456. if argname == "request":
  1457. return
  1458. if scopemismatch(invoking_scope, requested_scope):
  1459. # try to report something helpful
  1460. lines = self._factorytraceback()
  1461. pytest.fail("ScopeMismatch: You tried to access the %r scoped "
  1462. "fixture %r with a %r scoped request object, "
  1463. "involved factories\n%s" %(
  1464. (requested_scope, argname, invoking_scope, "\n".join(lines))),
  1465. pytrace=False)
  1466. def _factorytraceback(self):
  1467. lines = []
  1468. for fixturedef in self._get_fixturestack():
  1469. factory = fixturedef.func
  1470. fs, lineno = getfslineno(factory)
  1471. p = self._pyfuncitem.session.fspath.bestrelpath(fs)
  1472. args = _format_args(factory)
  1473. lines.append("%s:%d: def %s%s" %(
  1474. p, lineno, factory.__name__, args))
  1475. return lines
  1476. def _getscopeitem(self, scope):
  1477. if scope == "function":
  1478. # this might also be a non-function Item despite its attribute name
  1479. return self._pyfuncitem
  1480. node = get_scope_node(self._pyfuncitem, scope)
  1481. if node is None and scope == "class":
  1482. # fallback to function item itself
  1483. node = self._pyfuncitem
  1484. assert node
  1485. return node
  1486. def __repr__(self):
  1487. return "<FixtureRequest for %r>" %(self.node)
  1488. class SubRequest(FixtureRequest):
  1489. """ a sub request for handling getting a fixture from a
  1490. test function/fixture. """
  1491. def __init__(self, request, scope, param, param_index, fixturedef):
  1492. self._parent_request = request
  1493. self.fixturename = fixturedef.argname
  1494. if param is not NOTSET:
  1495. self.param = param
  1496. self.param_index = param_index
  1497. self.scope = scope
  1498. self._fixturedef = fixturedef
  1499. self.addfinalizer = fixturedef.addfinalizer
  1500. self._pyfuncitem = request._pyfuncitem
  1501. self._funcargs = request._funcargs
  1502. self._fixturedefs = request._fixturedefs
  1503. self._arg2fixturedefs = request._arg2fixturedefs
  1504. self._arg2index = request._arg2index
  1505. self.fixturenames = request.fixturenames
  1506. self._fixturemanager = request._fixturemanager
  1507. def __repr__(self):
  1508. return "<SubRequest %r for %r>" % (self.fixturename, self._pyfuncitem)
  1509. class ScopeMismatchError(Exception):
  1510. """ A fixture function tries to use a different fixture function which
  1511. which has a lower scope (e.g. a Session one calls a function one)
  1512. """
  1513. scopes = "session module class function".split()
  1514. scopenum_function = scopes.index("function")
  1515. def scopemismatch(currentscope, newscope):
  1516. return scopes.index(newscope) > scopes.index(currentscope)
  1517. class FixtureLookupError(LookupError):
  1518. """ could not return a requested Fixture (missing or invalid). """
  1519. def __init__(self, argname, request, msg=None):
  1520. self.argname = argname
  1521. self.request = request
  1522. self.fixturestack = request._get_fixturestack()
  1523. self.msg = msg
  1524. def formatrepr(self):
  1525. tblines = []
  1526. addline = tblines.append
  1527. stack = [self.request._pyfuncitem.obj]
  1528. stack.extend(map(lambda x: x.func, self.fixturestack))
  1529. msg = self.msg
  1530. if msg is not None:
  1531. # the last fixture raise an error, let's present
  1532. # it at the requesting side
  1533. stack = stack[:-1]
  1534. for function in stack:
  1535. fspath, lineno = getfslineno(function)
  1536. try:
  1537. lines, _ = inspect.getsourcelines(get_real_func(function))
  1538. except (IOError, IndexError):
  1539. error_msg = "file %s, line %s: source code not available"
  1540. addline(error_msg % (fspath, lineno+1))
  1541. else:
  1542. addline("file %s, line %s" % (fspath, lineno+1))
  1543. for i, line in enumerate(lines):
  1544. line = line.rstrip()
  1545. addline(" " + line)
  1546. if line.lstrip().startswith('def'):
  1547. break
  1548. if msg is None:
  1549. fm = self.request._fixturemanager
  1550. available = []
  1551. for name, fixturedef in fm._arg2fixturedefs.items():
  1552. parentid = self.request._pyfuncitem.parent.nodeid
  1553. faclist = list(fm._matchfactories(fixturedef, parentid))
  1554. if faclist:
  1555. available.append(name)
  1556. msg = "fixture %r not found" % (self.argname,)
  1557. msg += "\n available fixtures: %s" %(", ".join(available),)
  1558. msg += "\n use 'py.test --fixtures [testpath]' for help on them."
  1559. return FixtureLookupErrorRepr(fspath, lineno, tblines, msg, self.argname)
  1560. class FixtureLookupErrorRepr(TerminalRepr):
  1561. def __init__(self, filename, firstlineno, tblines, errorstring, argname):
  1562. self.tblines = tblines
  1563. self.errorstring = errorstring
  1564. self.filename = filename
  1565. self.firstlineno = firstlineno
  1566. self.argname = argname
  1567. def toterminal(self, tw):
  1568. #tw.line("FixtureLookupError: %s" %(self.argname), red=True)
  1569. for tbline in self.tblines:
  1570. tw.line(tbline.rstrip())
  1571. for line in self.errorstring.split("\n"):
  1572. tw.line(" " + line.strip(), red=True)
  1573. tw.line()
  1574. tw.line("%s:%d" % (self.filename, self.firstlineno+1))
  1575. class FixtureManager:
  1576. """
  1577. pytest fixtures definitions and information is stored and managed
  1578. from this class.
  1579. During collection fm.parsefactories() is called multiple times to parse
  1580. fixture function definitions into FixtureDef objects and internal
  1581. data structures.
  1582. During collection of test functions, metafunc-mechanics instantiate
  1583. a FuncFixtureInfo object which is cached per node/func-name.
  1584. This FuncFixtureInfo object is later retrieved by Function nodes
  1585. which themselves offer a fixturenames attribute.
  1586. The FuncFixtureInfo object holds information about fixtures and FixtureDefs
  1587. relevant for a particular function. An initial list of fixtures is
  1588. assembled like this:
  1589. - ini-defined usefixtures
  1590. - autouse-marked fixtures along the collection chain up from the function
  1591. - usefixtures markers at module/class/function level
  1592. - test function funcargs
  1593. Subsequently the funcfixtureinfo.fixturenames attribute is computed
  1594. as the closure of the fixtures needed to setup the initial fixtures,
  1595. i. e. fixtures needed by fixture functions themselves are appended
  1596. to the fixturenames list.
  1597. Upon the test-setup phases all fixturenames are instantiated, retrieved
  1598. by a lookup of their FuncFixtureInfo.
  1599. """
  1600. _argprefix = "pytest_funcarg__"
  1601. FixtureLookupError = FixtureLookupError
  1602. FixtureLookupErrorRepr = FixtureLookupErrorRepr
  1603. def __init__(self, session):
  1604. self.session = session
  1605. self.config = session.config
  1606. self._arg2fixturedefs = {}
  1607. self._holderobjseen = set()
  1608. self._arg2finish = {}
  1609. self._nodeid_and_autousenames = [("", self.config.getini("usefixtures"))]
  1610. session.config.pluginmanager.register(self, "funcmanage")
  1611. def getfixtureinfo(self, node, func, cls, funcargs=True):
  1612. if funcargs and not hasattr(node, "nofuncargs"):
  1613. if cls is not None:
  1614. startindex = 1
  1615. else:
  1616. startindex = None
  1617. argnames = getfuncargnames(func, startindex)
  1618. else:
  1619. argnames = ()
  1620. usefixtures = getattr(func, "usefixtures", None)
  1621. initialnames = argnames
  1622. if usefixtures is not None:
  1623. initialnames = usefixtures.args + initialnames
  1624. fm = node.session._fixturemanager
  1625. names_closure, arg2fixturedefs = fm.getfixtureclosure(initialnames,
  1626. node)
  1627. return FuncFixtureInfo(argnames, names_closure, arg2fixturedefs)
  1628. def pytest_plugin_registered(self, plugin):
  1629. nodeid = None
  1630. try:
  1631. p = py.path.local(plugin.__file__)
  1632. except AttributeError:
  1633. pass
  1634. else:
  1635. # construct the base nodeid which is later used to check
  1636. # what fixtures are visible for particular tests (as denoted
  1637. # by their test id)
  1638. if p.basename.startswith("conftest.py"):
  1639. nodeid = p.dirpath().relto(self.config.rootdir)
  1640. if p.sep != "/":
  1641. nodeid = nodeid.replace(p.sep, "/")
  1642. self.parsefactories(plugin, nodeid)
  1643. def _getautousenames(self, nodeid):
  1644. """ return a tuple of fixture names to be used. """
  1645. autousenames = []
  1646. for baseid, basenames in self._nodeid_and_autousenames:
  1647. if nodeid.startswith(baseid):
  1648. if baseid:
  1649. i = len(baseid)
  1650. nextchar = nodeid[i:i+1]
  1651. if nextchar and nextchar not in ":/":
  1652. continue
  1653. autousenames.extend(basenames)
  1654. # make sure autousenames are sorted by scope, scopenum 0 is session
  1655. autousenames.sort(
  1656. key=lambda x: self._arg2fixturedefs[x][-1].scopenum)
  1657. return autousenames
  1658. def getfixtureclosure(self, fixturenames, parentnode):
  1659. # collect the closure of all fixtures , starting with the given
  1660. # fixturenames as the initial set. As we have to visit all
  1661. # factory definitions anyway, we also return a arg2fixturedefs
  1662. # mapping so that the caller can reuse it and does not have
  1663. # to re-discover fixturedefs again for each fixturename
  1664. # (discovering matching fixtures for a given name/node is expensive)
  1665. parentid = parentnode.nodeid
  1666. fixturenames_closure = self._getautousenames(parentid)
  1667. def merge(otherlist):
  1668. for arg in otherlist:
  1669. if arg not in fixturenames_closure:
  1670. fixturenames_closure.append(arg)
  1671. merge(fixturenames)
  1672. arg2fixturedefs = {}
  1673. lastlen = -1
  1674. while lastlen != len(fixturenames_closure):
  1675. lastlen = len(fixturenames_closure)
  1676. for argname in fixturenames_closure:
  1677. if argname in arg2fixturedefs:
  1678. continue
  1679. fixturedefs = self.getfixturedefs(argname, parentid)
  1680. if fixturedefs:
  1681. arg2fixturedefs[argname] = fixturedefs
  1682. merge(fixturedefs[-1].argnames)
  1683. return fixturenames_closure, arg2fixturedefs
  1684. def pytest_generate_tests(self, metafunc):
  1685. for argname in metafunc.fixturenames:
  1686. faclist = metafunc._arg2fixturedefs.get(argname)
  1687. if faclist:
  1688. fixturedef = faclist[-1]
  1689. if fixturedef.params is not None:
  1690. func_params = getattr(getattr(metafunc.function, 'parametrize', None), 'args', [[None]])
  1691. # skip directly parametrized arguments
  1692. argnames = func_params[0]
  1693. if not isinstance(argnames, (tuple, list)):
  1694. argnames = [x.strip() for x in argnames.split(",") if x.strip()]
  1695. if argname not in func_params and argname not in argnames:
  1696. metafunc.parametrize(argname, fixturedef.params,
  1697. indirect=True, scope=fixturedef.scope,
  1698. ids=fixturedef.ids)
  1699. else:
  1700. continue # will raise FixtureLookupError at setup time
  1701. def pytest_collection_modifyitems(self, items):
  1702. # separate parametrized setups
  1703. items[:] = reorder_items(items)
  1704. def parsefactories(self, node_or_obj, nodeid=NOTSET, unittest=False):
  1705. if nodeid is not NOTSET:
  1706. holderobj = node_or_obj
  1707. else:
  1708. holderobj = node_or_obj.obj
  1709. nodeid = node_or_obj.nodeid
  1710. if holderobj in self._holderobjseen:
  1711. return
  1712. self._holderobjseen.add(holderobj)
  1713. autousenames = []
  1714. for name in dir(holderobj):
  1715. obj = getattr(holderobj, name, None)
  1716. # fixture functions have a pytest_funcarg__ prefix (pre-2.3 style)
  1717. # or are "@pytest.fixture" marked
  1718. marker = getfixturemarker(obj)
  1719. if marker is None:
  1720. if not name.startswith(self._argprefix):
  1721. continue
  1722. if not callable(obj):
  1723. continue
  1724. marker = defaultfuncargprefixmarker
  1725. name = name[len(self._argprefix):]
  1726. elif not isinstance(marker, FixtureFunctionMarker):
  1727. # magic globals with __getattr__ might have got us a wrong
  1728. # fixture attribute
  1729. continue
  1730. else:
  1731. assert not name.startswith(self._argprefix)
  1732. fixturedef = FixtureDef(self, nodeid, name, obj,
  1733. marker.scope, marker.params,
  1734. yieldctx=marker.yieldctx,
  1735. unittest=unittest, ids=marker.ids)
  1736. faclist = self._arg2fixturedefs.setdefault(name, [])
  1737. if fixturedef.has_location:
  1738. faclist.append(fixturedef)
  1739. else:
  1740. # fixturedefs with no location are at the front
  1741. # so this inserts the current fixturedef after the
  1742. # existing fixturedefs from external plugins but
  1743. # before the fixturedefs provided in conftests.
  1744. i = len([f for f in faclist if not f.has_location])
  1745. faclist.insert(i, fixturedef)
  1746. if marker.autouse:
  1747. autousenames.append(name)
  1748. if autousenames:
  1749. self._nodeid_and_autousenames.append((nodeid or '', autousenames))
  1750. def getfixturedefs(self, argname, nodeid):
  1751. try:
  1752. fixturedefs = self._arg2fixturedefs[argname]
  1753. except KeyError:
  1754. return None
  1755. else:
  1756. return tuple(self._matchfactories(fixturedefs, nodeid))
  1757. def _matchfactories(self, fixturedefs, nodeid):
  1758. for fixturedef in fixturedefs:
  1759. if nodeid.startswith(fixturedef.baseid):
  1760. yield fixturedef
  1761. def fail_fixturefunc(fixturefunc, msg):
  1762. fs, lineno = getfslineno(fixturefunc)
  1763. location = "%s:%s" % (fs, lineno+1)
  1764. source = _pytest._code.Source(fixturefunc)
  1765. pytest.fail(msg + ":\n\n" + str(source.indent()) + "\n" + location,
  1766. pytrace=False)
  1767. def call_fixture_func(fixturefunc, request, kwargs, yieldctx):
  1768. if yieldctx:
  1769. if not is_generator(fixturefunc):
  1770. fail_fixturefunc(fixturefunc,
  1771. msg="yield_fixture requires yield statement in function")
  1772. iter = fixturefunc(**kwargs)
  1773. next = getattr(iter, "__next__", None)
  1774. if next is None:
  1775. next = getattr(iter, "next")
  1776. res = next()
  1777. def teardown():
  1778. try:
  1779. next()
  1780. except StopIteration:
  1781. pass
  1782. else:
  1783. fail_fixturefunc(fixturefunc,
  1784. "yield_fixture function has more than one 'yield'")
  1785. request.addfinalizer(teardown)
  1786. else:
  1787. if is_generator(fixturefunc):
  1788. fail_fixturefunc(fixturefunc,
  1789. msg="pytest.fixture functions cannot use ``yield``. "
  1790. "Instead write and return an inner function/generator "
  1791. "and let the consumer call and iterate over it.")
  1792. res = fixturefunc(**kwargs)
  1793. return res
  1794. class FixtureDef:
  1795. """ A container for a factory definition. """
  1796. def __init__(self, fixturemanager, baseid, argname, func, scope, params,
  1797. yieldctx, unittest=False, ids=None):
  1798. self._fixturemanager = fixturemanager
  1799. self.baseid = baseid or ''
  1800. self.has_location = baseid is not None
  1801. self.func = func
  1802. self.argname = argname
  1803. self.scope = scope
  1804. self.scopenum = scopes.index(scope or "function")
  1805. self.params = params
  1806. startindex = unittest and 1 or None
  1807. self.argnames = getfuncargnames(func, startindex=startindex)
  1808. self.yieldctx = yieldctx
  1809. self.unittest = unittest
  1810. self.ids = ids
  1811. self._finalizer = []
  1812. def addfinalizer(self, finalizer):
  1813. self._finalizer.append(finalizer)
  1814. def finish(self):
  1815. try:
  1816. while self._finalizer:
  1817. func = self._finalizer.pop()
  1818. func()
  1819. finally:
  1820. # even if finalization fails, we invalidate
  1821. # the cached fixture value
  1822. if hasattr(self, "cached_result"):
  1823. del self.cached_result
  1824. def execute(self, request):
  1825. # get required arguments and register our own finish()
  1826. # with their finalization
  1827. kwargs = {}
  1828. for argname in self.argnames:
  1829. fixturedef = request._get_active_fixturedef(argname)
  1830. result, arg_cache_key, exc = fixturedef.cached_result
  1831. request._check_scope(argname, request.scope, fixturedef.scope)
  1832. kwargs[argname] = result
  1833. if argname != "request":
  1834. fixturedef.addfinalizer(self.finish)
  1835. my_cache_key = request.param_index
  1836. cached_result = getattr(self, "cached_result", None)
  1837. if cached_result is not None:
  1838. result, cache_key, err = cached_result
  1839. if my_cache_key == cache_key:
  1840. if err is not None:
  1841. py.builtin._reraise(*err)
  1842. else:
  1843. return result
  1844. # we have a previous but differently parametrized fixture instance
  1845. # so we need to tear it down before creating a new one
  1846. self.finish()
  1847. assert not hasattr(self, "cached_result")
  1848. fixturefunc = self.func
  1849. if self.unittest:
  1850. if request.instance is not None:
  1851. # bind the unbound method to the TestCase instance
  1852. fixturefunc = self.func.__get__(request.instance)
  1853. else:
  1854. # the fixture function needs to be bound to the actual
  1855. # request.instance so that code working with "self" behaves
  1856. # as expected.
  1857. if request.instance is not None:
  1858. fixturefunc = getimfunc(self.func)
  1859. if fixturefunc != self.func:
  1860. fixturefunc = fixturefunc.__get__(request.instance)
  1861. try:
  1862. result = call_fixture_func(fixturefunc, request, kwargs,
  1863. self.yieldctx)
  1864. except Exception:
  1865. self.cached_result = (None, my_cache_key, sys.exc_info())
  1866. raise
  1867. self.cached_result = (result, my_cache_key, None)
  1868. return result
  1869. def __repr__(self):
  1870. return ("<FixtureDef name=%r scope=%r baseid=%r >" %
  1871. (self.argname, self.scope, self.baseid))
  1872. def num_mock_patch_args(function):
  1873. """ return number of arguments used up by mock arguments (if any) """
  1874. patchings = getattr(function, "patchings", None)
  1875. if not patchings:
  1876. return 0
  1877. mock = sys.modules.get("mock", sys.modules.get("unittest.mock", None))
  1878. if mock is not None:
  1879. return len([p for p in patchings
  1880. if not p.attribute_name and p.new is mock.DEFAULT])
  1881. return len(patchings)
  1882. def getfuncargnames(function, startindex=None):
  1883. # XXX merge with main.py's varnames
  1884. #assert not isclass(function)
  1885. realfunction = function
  1886. while hasattr(realfunction, "__wrapped__"):
  1887. realfunction = realfunction.__wrapped__
  1888. if startindex is None:
  1889. startindex = inspect.ismethod(function) and 1 or 0
  1890. if realfunction != function:
  1891. startindex += num_mock_patch_args(function)
  1892. function = realfunction
  1893. if isinstance(function, functools.partial):
  1894. argnames = inspect.getargs(_pytest._code.getrawcode(function.func))[0]
  1895. partial = function
  1896. argnames = argnames[len(partial.args):]
  1897. if partial.keywords:
  1898. for kw in partial.keywords:
  1899. argnames.remove(kw)
  1900. else:
  1901. argnames = inspect.getargs(_pytest._code.getrawcode(function))[0]
  1902. defaults = getattr(function, 'func_defaults',
  1903. getattr(function, '__defaults__', None)) or ()
  1904. numdefaults = len(defaults)
  1905. if numdefaults:
  1906. return tuple(argnames[startindex:-numdefaults])
  1907. return tuple(argnames[startindex:])
  1908. # algorithm for sorting on a per-parametrized resource setup basis
  1909. # it is called for scopenum==0 (session) first and performs sorting
  1910. # down to the lower scopes such as to minimize number of "high scope"
  1911. # setups and teardowns
  1912. def reorder_items(items):
  1913. argkeys_cache = {}
  1914. for scopenum in range(0, scopenum_function):
  1915. argkeys_cache[scopenum] = d = {}
  1916. for item in items:
  1917. keys = set(get_parametrized_fixture_keys(item, scopenum))
  1918. if keys:
  1919. d[item] = keys
  1920. return reorder_items_atscope(items, set(), argkeys_cache, 0)
  1921. def reorder_items_atscope(items, ignore, argkeys_cache, scopenum):
  1922. if scopenum >= scopenum_function or len(items) < 3:
  1923. return items
  1924. items_done = []
  1925. while 1:
  1926. items_before, items_same, items_other, newignore = \
  1927. slice_items(items, ignore, argkeys_cache[scopenum])
  1928. items_before = reorder_items_atscope(
  1929. items_before, ignore, argkeys_cache,scopenum+1)
  1930. if items_same is None:
  1931. # nothing to reorder in this scope
  1932. assert items_other is None
  1933. return items_done + items_before
  1934. items_done.extend(items_before)
  1935. items = items_same + items_other
  1936. ignore = newignore
  1937. def slice_items(items, ignore, scoped_argkeys_cache):
  1938. # we pick the first item which uses a fixture instance in the
  1939. # requested scope and which we haven't seen yet. We slice the input
  1940. # items list into a list of items_nomatch, items_same and
  1941. # items_other
  1942. if scoped_argkeys_cache: # do we need to do work at all?
  1943. it = iter(items)
  1944. # first find a slicing key
  1945. for i, item in enumerate(it):
  1946. argkeys = scoped_argkeys_cache.get(item)
  1947. if argkeys is not None:
  1948. argkeys = argkeys.difference(ignore)
  1949. if argkeys: # found a slicing key
  1950. slicing_argkey = argkeys.pop()
  1951. items_before = items[:i]
  1952. items_same = [item]
  1953. items_other = []
  1954. # now slice the remainder of the list
  1955. for item in it:
  1956. argkeys = scoped_argkeys_cache.get(item)
  1957. if argkeys and slicing_argkey in argkeys and \
  1958. slicing_argkey not in ignore:
  1959. items_same.append(item)
  1960. else:
  1961. items_other.append(item)
  1962. newignore = ignore.copy()
  1963. newignore.add(slicing_argkey)
  1964. return (items_before, items_same, items_other, newignore)
  1965. return items, None, None, None
  1966. def get_parametrized_fixture_keys(item, scopenum):
  1967. """ return list of keys for all parametrized arguments which match
  1968. the specified scope. """
  1969. assert scopenum < scopenum_function # function
  1970. try:
  1971. cs = item.callspec
  1972. except AttributeError:
  1973. pass
  1974. else:
  1975. # cs.indictes.items() is random order of argnames but
  1976. # then again different functions (items) can change order of
  1977. # arguments so it doesn't matter much probably
  1978. for argname, param_index in cs.indices.items():
  1979. if cs._arg2scopenum[argname] != scopenum:
  1980. continue
  1981. if scopenum == 0: # session
  1982. key = (argname, param_index)
  1983. elif scopenum == 1: # module
  1984. key = (argname, param_index, item.fspath)
  1985. elif scopenum == 2: # class
  1986. key = (argname, param_index, item.fspath, item.cls)
  1987. yield key
  1988. def xunitsetup(obj, name):
  1989. meth = getattr(obj, name, None)
  1990. if getfixturemarker(meth) is None:
  1991. return meth
  1992. def getfixturemarker(obj):
  1993. """ return fixturemarker or None if it doesn't exist or raised
  1994. exceptions."""
  1995. try:
  1996. return getattr(obj, "_pytestfixturefunction", None)
  1997. except KeyboardInterrupt:
  1998. raise
  1999. except Exception:
  2000. # some objects raise errors like request (from flask import request)
  2001. # we don't expect them to be fixture functions
  2002. return None
  2003. scopename2class = {
  2004. 'class': Class,
  2005. 'module': Module,
  2006. 'function': pytest.Item,
  2007. }
  2008. def get_scope_node(node, scope):
  2009. cls = scopename2class.get(scope)
  2010. if cls is None:
  2011. if scope == "session":
  2012. return node.session
  2013. raise ValueError("unknown scope")
  2014. return node.getparent(cls)