Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev/0.14.0 #78

Merged
merged 11 commits into from
Aug 26, 2020
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ We are currently working on porting this changelog to the specifications in
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [Version 0.14.0] - Uneleased

### Added
* The REQUIRES directive can now inspect existence or values of environment variables.
* Added top-level `doctest_callable` function, which executes the doctests of a
function or class.
* Support for `NO_COLOR` environment variable.

### Fixed
* `IPython.embed` and `ipdb.launch_ipdb_on_exception` now correctly work from
inside doctests.
* Small incompatibility with `pytest-matrix`. See #82

## [Version 0.13.0] - Released 2020-07-10

### Changed
Expand Down
26 changes: 26 additions & 0 deletions dev/interactive_embed_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@


def interative_test_xdev_embed():
"""
CommandLine:
xdoctest -m dev/interactive_embed_tests.py interative_test_xdev_embed

Example:
>>> interative_test_xdev_embed()
"""
import xdev
with xdev.embed_on_exception_context:
raise Exception


def interative_test_ipdb_embed():
"""
CommandLine:
xdoctest -m dev/interactive_embed_tests.py interative_test_ipdb_embed

Example:
>>> interative_test_ipdb_embed()
"""
import ipdb
with ipdb.launch_ipdb_on_exception():
raise Exception
4 changes: 4 additions & 0 deletions testing/test_binary_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ def test_run_binary_doctests():

CommandLine:
python ~/code/xdoctest/testing/test_binary_ext.py test_run_binary_doctests

Notes:
xdoctest -m $HOME/code/xdoctest/testing/pybind11_test/install/my_ext.cpython-38-x86_64-linux-gnu.so list --analysis=dynamic

"""
extmod_fpath = build_demo_extmod()
print('extmod_fpath = {!r}'.format(extmod_fpath))
Expand Down
78 changes: 78 additions & 0 deletions testing/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,84 @@ def foo():
assert 'SKIPPED' in cap.text


def test_global_exec():
"""
pytest testing/test_runner.py::test_global_exec -s
"""
from xdoctest import runner

source = utils.codeblock(
'''
def foo():
"""
Example:
>>> print(a)
"""
''')

config = {
'global_exec': 'a=1',
}

with utils.TempDir() as temp:
dpath = temp.dpath
modpath = join(dpath, 'test_example_run.py')

with open(modpath, 'w') as file:
file.write(source)

with utils.CaptureStdout() as cap:
runner.doctest_module(modpath, 'foo', argv=[''], config=config)

assert '1 passed' in cap.text


def test_hack_the_sys_argv():
"""
Tests hacky solution to issue #76

pytest testing/test_runner.py::test_global_exec -s

References:
https://github.com/Erotemic/xdoctest/issues/76
"""
from xdoctest import runner

source = utils.codeblock(
'''
def foo():
"""
Example:
>>> # xdoctest: +REQUIRES(--hackedflag)
>>> print('This will run if global_exec specified')
"""
''')

import sys
NEEDS_FIX = '--hackedflag' not in sys.argv

config = {
'global_exec': 'import sys; sys.argv.append("--hackedflag")'
}

with utils.TempDir() as temp:
dpath = temp.dpath
modpath = join(dpath, 'test_example_run.py')

with open(modpath, 'w') as file:
file.write(source)

with utils.CaptureStdout() as cap:
runner.doctest_module(modpath, 'foo', argv=[''], config=config)

if NEEDS_FIX:
# Fix the global state
sys.argv.remove('--hackedflag')

# print(cap.text)
assert '1 passed' in cap.text


if __name__ == '__main__':
"""
CommandLine:
Expand Down
40 changes: 19 additions & 21 deletions xdoctest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,43 +162,39 @@ def fib(n):
.. code:: text

usage: xdoctest [-h] [--version] [-m MODNAME] [-c COMMAND]
[--style {auto,google,freeform}] [--durations DURATIONS]
[--time] [--nocolor] [--offset]
[--style {auto,google,freeform}]
[--analysis {auto,static,dynamic}]
[--durations DURATIONS] [--time] [--nocolor] [--offset]
[--report {none,cdiff,ndiff,udiff,only_first_failure}]
[--options OPTIONS] [--global-exec GLOBAL_EXEC]
[--verbose VERBOSE] [--quiet] [--silent]
[arg [arg ...]]

Xdoctest 0.11.0 - on Python - 3.7.3 (default, Mar 27 2019, 22:11:17) [GCC
7.3.0] - discover and run doctests within a python package
Xdoctest 0.14.0 - on Python - 3.8.3 (default, Jul 2 2020, 16:21:59) [GCC 7.3.0] - discover and run doctests within a python package

positional arguments:
arg Ignored if optional arguments are specified,
otherwise: Defaults --modname to arg.pop(0). Defaults
--command to arg.pop(0).
arg Ignored if optional arguments are specified, otherwise: Defaults --modname to arg.pop(0). Defaults --command
to arg.pop(0).

optional arguments:
-h, --help show this help message and exit
--version display version info and quit
-m MODNAME, --modname MODNAME
module name or path. If specified positional modules
are ignored
module name or path. If specified positional modules are ignored
-c COMMAND, --command COMMAND
a doctest name or a command (list|all|<callname>).
Defaults to all
a doctest name or a command (list|all|<callname>). Defaults to all
--style {auto,google,freeform}
choose your style
choose the style of doctests that will be parsed
--analysis {auto,static,dynamic}
How doctests are collected
--durations DURATIONS
specify execution times for slowest N tests.N=0 will
show times for all tests
specify execution times for slowest N tests.N=0 will show times for all tests
--time Same as if durations=0
--nocolor Disable ANSI coloration in stdout
--offset if True formated source linenumbers will agree with
their location in the source file. Otherwise they will
--offset if True formatted source linenumbers will agree with their location in the source file. Otherwise they will
be relative to the doctest itself.
--report {none,cdiff,ndiff,udiff,only_first_failure}
choose another output format for diffs on xdoctest
failure
choose another output format for diffs on xdoctest failure
--options OPTIONS default directive flags for doctests
--global-exec GLOBAL_EXEC
exec these lines before every test
Expand All @@ -207,6 +203,7 @@ def fib(n):
--silent sets verbosity to 0



The xdoctest interface can be run programmatically using
``xdoctest.doctest_module(path)``, which can be placed in the ``__main__``
section of any module as such:
Expand Down Expand Up @@ -239,7 +236,7 @@ def fib(n):

'''
# mkinit xdoctest --nomods
__version__ = '0.13.0'
__version__ = '0.14.0'


# TODO:
Expand All @@ -259,10 +256,11 @@ def fib(n):

from xdoctest import utils
from xdoctest import docstr
from xdoctest.runner import (doctest_module,)
from xdoctest.runner import (doctest_module, doctest_callable,)
from xdoctest.exceptions import (DoctestParseError, ExitTestException,
MalformedDocstr,)


__all__ = ['DoctestParseError', 'ExitTestException', 'MalformedDocstr',
'doctest_module', 'utils', 'docstr', '__version__']
'doctest_module', 'doctest_callable', 'utils', 'docstr',
'__version__']
9 changes: 8 additions & 1 deletion xdoctest/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,19 @@ def main(argv=None):
print('{} = {}'.format(key, value))
return 0

# FIXME: default values are reporting incorrectly or are missformated
class RawDescriptionDefaultsHelpFormatter(
argparse.RawDescriptionHelpFormatter,
argparse.ArgumentDefaultsHelpFormatter):
pass

parser = argparse.ArgumentParser(
prog='xdoctest',
description=(
'Xdoctest {xdoc_version} - on Python - {sys_version} - '
'discover and run doctests within a python package'
).format(**version_info)
).format(**version_info),
formatter_class=RawDescriptionDefaultsHelpFormatter,
)
parser.add_argument(
'arg', nargs='*', help=utils.codeblock(
Expand Down
Loading