Merge branch 'doctest_namespace_inject' into features
This commit is contained in:
commit
4a76b2e9b6
1
AUTHORS
1
AUTHORS
|
@ -59,6 +59,7 @@ Marc Schlaich
|
||||||
Mark Abramowitz
|
Mark Abramowitz
|
||||||
Markus Unterwaditzer
|
Markus Unterwaditzer
|
||||||
Martijn Faassen
|
Martijn Faassen
|
||||||
|
Matt Williams
|
||||||
Michael Aquilina
|
Michael Aquilina
|
||||||
Michael Birtwell
|
Michael Birtwell
|
||||||
Michael Droettboom
|
Michael Droettboom
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
|
|
||||||
**New Features**
|
**New Features**
|
||||||
|
|
||||||
*
|
* New ``doctest_namespace`` fixture for injecting names into the
|
||||||
|
namespace in which your doctests run.
|
||||||
|
Thanks `@milliams`_ for the complete PR (`#1428`_).
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
|
@ -28,6 +30,11 @@
|
||||||
*
|
*
|
||||||
|
|
||||||
|
|
||||||
|
.. _@milliams: https://github.com/milliams
|
||||||
|
|
||||||
|
.. _#1428: https://github.com/pytest-dev/pytest/pull/1428
|
||||||
|
|
||||||
|
|
||||||
2.9.0
|
2.9.0
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,8 @@ class DoctestItem(pytest.Item):
|
||||||
if self.dtest is not None:
|
if self.dtest is not None:
|
||||||
self.fixture_request = _setup_fixtures(self)
|
self.fixture_request = _setup_fixtures(self)
|
||||||
globs = dict(getfixture=self.fixture_request.getfuncargvalue)
|
globs = dict(getfixture=self.fixture_request.getfuncargvalue)
|
||||||
|
for name, value in self.fixture_request.getfuncargvalue('doctest_namespace').items():
|
||||||
|
globs[name] = value
|
||||||
self.dtest.globs.update(globs)
|
self.dtest.globs.update(globs)
|
||||||
|
|
||||||
def runtest(self):
|
def runtest(self):
|
||||||
|
@ -159,6 +161,9 @@ class DoctestTextfile(DoctestItem, pytest.Module):
|
||||||
if '__name__' not in globs:
|
if '__name__' not in globs:
|
||||||
globs['__name__'] = '__main__'
|
globs['__name__'] = '__main__'
|
||||||
|
|
||||||
|
for name, value in fixture_request.getfuncargvalue('doctest_namespace').items():
|
||||||
|
globs[name] = value
|
||||||
|
|
||||||
optionflags = get_optionflags(self)
|
optionflags = get_optionflags(self)
|
||||||
runner = doctest.DebugRunner(verbose=0, optionflags=optionflags,
|
runner = doctest.DebugRunner(verbose=0, optionflags=optionflags,
|
||||||
checker=_get_checker())
|
checker=_get_checker())
|
||||||
|
@ -288,3 +293,11 @@ def _get_allow_bytes_flag():
|
||||||
"""
|
"""
|
||||||
import doctest
|
import doctest
|
||||||
return doctest.register_optionflag('ALLOW_BYTES')
|
return doctest.register_optionflag('ALLOW_BYTES')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='session')
|
||||||
|
def doctest_namespace():
|
||||||
|
"""
|
||||||
|
Inject names into the doctest namespace.
|
||||||
|
"""
|
||||||
|
return dict()
|
||||||
|
|
|
@ -102,4 +102,31 @@ itself::
|
||||||
>>> get_unicode_greeting() # doctest: +ALLOW_UNICODE
|
>>> get_unicode_greeting() # doctest: +ALLOW_UNICODE
|
||||||
'Hello'
|
'Hello'
|
||||||
|
|
||||||
|
The 'doctest_namespace' fixture
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
.. versionadded:: 2.10
|
||||||
|
|
||||||
|
The ``doctest_namespace`` fixture can be used to inject items into the
|
||||||
|
namespace in which your doctests run. It is intended to be used within
|
||||||
|
your own fixtures to provide the tests that use them with context.
|
||||||
|
|
||||||
|
``doctest_namespace`` is a standard ``dict`` object into which you
|
||||||
|
place the objects you want to appear in the doctest namespace::
|
||||||
|
|
||||||
|
# content of conftest.py
|
||||||
|
import numpy
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def add_np(doctest_namespace):
|
||||||
|
doctest_namespace['np'] = numpy
|
||||||
|
|
||||||
|
which can then be used in your doctests directly::
|
||||||
|
|
||||||
|
# content of numpy.py
|
||||||
|
def arange():
|
||||||
|
"""
|
||||||
|
>>> a = np.arange(10)
|
||||||
|
>>> len(a)
|
||||||
|
10
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
|
@ -713,3 +713,53 @@ class TestDoctestAutoUseFixtures:
|
||||||
result = testdir.runpytest('--doctest-modules')
|
result = testdir.runpytest('--doctest-modules')
|
||||||
assert 'FAILURES' not in str(result.stdout.str())
|
assert 'FAILURES' not in str(result.stdout.str())
|
||||||
result.stdout.fnmatch_lines(['*=== 1 passed in *'])
|
result.stdout.fnmatch_lines(['*=== 1 passed in *'])
|
||||||
|
|
||||||
|
|
||||||
|
class TestDoctestNamespaceFixture:
|
||||||
|
|
||||||
|
SCOPES = ['module', 'session', 'class', 'function']
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('scope', SCOPES)
|
||||||
|
def test_namespace_doctestfile(self, testdir, scope):
|
||||||
|
"""
|
||||||
|
Check that inserting something into the namespace works in a
|
||||||
|
simple text file doctest
|
||||||
|
"""
|
||||||
|
testdir.makeconftest("""
|
||||||
|
import pytest
|
||||||
|
import contextlib
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True, scope="{scope}")
|
||||||
|
def add_contextlib(doctest_namespace):
|
||||||
|
doctest_namespace['cl'] = contextlib
|
||||||
|
""".format(scope=scope))
|
||||||
|
p = testdir.maketxtfile("""
|
||||||
|
>>> print(cl.__name__)
|
||||||
|
contextlib
|
||||||
|
""")
|
||||||
|
reprec = testdir.inline_run(p)
|
||||||
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('scope', SCOPES)
|
||||||
|
def test_namespace_pyfile(self, testdir, scope):
|
||||||
|
"""
|
||||||
|
Check that inserting something into the namespace works in a
|
||||||
|
simple Python file docstring doctest
|
||||||
|
"""
|
||||||
|
testdir.makeconftest("""
|
||||||
|
import pytest
|
||||||
|
import contextlib
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True, scope="{scope}")
|
||||||
|
def add_contextlib(doctest_namespace):
|
||||||
|
doctest_namespace['cl'] = contextlib
|
||||||
|
""".format(scope=scope))
|
||||||
|
p = testdir.makepyfile("""
|
||||||
|
def foo():
|
||||||
|
'''
|
||||||
|
>>> print(cl.__name__)
|
||||||
|
contextlib
|
||||||
|
'''
|
||||||
|
""")
|
||||||
|
reprec = testdir.inline_run(p, "--doctest-modules")
|
||||||
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
Loading…
Reference in New Issue