xdoctest.doctest_example module¶
This module defines the main class that holds a DocTest example
- class xdoctest.doctest_example.DoctestConfig(*args: Any, **kwargs: Any)[source]¶
Bases:
dictDoctest configuration
Static configuration for collection, execution, and reporting doctests. Note dynamic directives are not managed by DoctestConfig, they use RuntimeState.
- xdoctest.doctest_example._distribution_or_module_exists(name: str) bool[source]¶
Check either installed distribution metadata or importability.
- xdoctest.doctest_example._doctest_requirement_satisfied(requirement_text: str) bool[source]¶
Return True when a doctestplus-style requirement is satisfied.
Bare distribution or module names do not require
packaging. Versioned or otherwise constrained PEP 508 expressions require the optionalpackagingdependency; without it they are treated as unsatisfied and a warning is emitted instead of aborting doctest collection.Example
>>> from xdoctest.doctest_example import _doctest_requirement_satisfied >>> _doctest_requirement_satisfied('os') True >>> _doctest_requirement_satisfied('definitely_missing_package_123456') False
Example
>>> from xdoctest.doctest_example import _doctest_requirement_satisfied >>> _doctest_requirement_satisfied('packaging>=0') True >>> _doctest_requirement_satisfied('packaging>999999') False
Example
>>> from xdoctest.doctest_example import _doctest_requirement_satisfied >>> _doctest_requirement_satisfied('bad requirement') Traceback (most recent call last): ... ValueError: Invalid __doctest_requires__ requirement: 'bad requirement'
- xdoctest.doctest_example._read_static_module_doctest_metadata_cached(modpath: str, mtime_ns: int, ctime_ns: int, size: int) tuple[Any, Any][source]¶
Read static metadata for one immutable file identity.
- xdoctest.doctest_example._static_module_doctest_metadata(modpath: str | PathLike[str]) tuple[Any, Any][source]¶
Read
__doctest_skip__and__doctest_requires__statically.Results are shared by doctests from the same unchanged module. The file’s modification time, change time, and size are part of the cache key, so an edited module is reparsed rather than returning stale metadata.
Example
>>> import tempfile >>> from pathlib import Path >>> dpath = Path(tempfile.mkdtemp()) >>> modpath = dpath / 'demo_metadata.py' >>> _ = modpath.write_text("__doctest_skip__ = ['first']\n") >>> _read_static_module_doctest_metadata_cached.cache_clear() >>> first = _static_module_doctest_metadata(modpath) >>> again = _static_module_doctest_metadata(modpath) >>> again is first True >>> _ = modpath.write_text("__doctest_skip__ = ['second', 'changed']\n") >>> changed = _static_module_doctest_metadata(modpath) >>> changed[0] ['second', 'changed']
- class xdoctest.doctest_example.DocTest(docsrc: str, modpath: str | PathLike[str] | ModuleType | None = None, callname: str | None = None, num: int = 0, lineno: int = 1, fpath: str | PathLike[str] | None = None, block_type: str | None = None, mode: str = 'pytest')[source]¶
Bases:
objectHolds information necessary to execute and verify a doctest
- Variables:
docsrc (str) – doctest source code
modpath (str | PathLike | ModuleType | None) – module the source was read from
callname (str) – name of the function/method/class/module being tested
num (int) – the index of the doctest in the docstring. (i.e. this object refers to the num-th doctest within a docstring)
lineno (int) – The line (starting from 1) in the file that the doctest begins on. (i.e. if you were to go to this line in the file, the first line of the doctest should be on this line).
fpath (PathLike) – Typically the same as modpath, only specified for non-python files (e.g. rst files).
block_type (str | None) – Hint indicating the type of docstring block. Can be (‘Example’, ‘Doctest’, ‘Script’, ‘Benchmark’, ‘zero-arg’, etc..).
mode (str) – Hint at what created / is running this doctest. This impacts how results are presented and what doctests are skipped. Can be “native” or “pytest”. Defaults to “pytest”.
config (DoctestConfig) – configuration for running / checking the doctest
module (ModuleType | None) – a reference to the module that contains the doctest
modname (str) – name of the module that contains the doctest.
failed_tb_lineno (int | None) – Line number a failure occurred on.
exc_info (None | tuple[type[BaseException], BaseException, types.TracebackType] | tuple[None, None, None]) – traceback of a failure if one occurred.
failed_part (None | DoctestPart) – the part containing the failure if one occurred.
warn_list (list) – from
warnings.catch_warnings()logged_evals (OrderedDict) – Mapping from part index to what they evaluated to (if anything)
logged_stdout (OrderedDict) – Mapping from part index to captured stdout.
global_namespace (dict) – globals visible to the doctest
CommandLine
xdoctest -m xdoctest.doctest_example DocTest
Example
>>> from xdoctest import core >>> from xdoctest import doctest_example >>> import os >>> modpath = doctest_example.__file__.replace('.pyc', '.py') >>> modpath = os.path.realpath(modpath) >>> testables = core.parse_doctestables(modpath) >>> for test in testables: >>> if test.callname == 'DocTest': >>> self = test >>> break >>> assert self.num == 0 >>> assert self.modpath == modpath >>> print(self) <DocTest(xdoctest.doctest_example DocTest:0 ln ...)>
- Parameters:
docsrc (str) – the text of the doctest
modpath (str | PathLike | ModuleType | None)
callname (str | None)
num (int)
lineno (int)
fpath (str | None)
block_type (str | None)
mode (str)
- UNKNOWN_MODNAME = '<modname?>'¶
- UNKNOWN_MODPATH = '<modpath?>'¶
- UNKNOWN_CALLNAME = '<callname?>'¶
- UNKNOWN_FPATH = '<fpath?>'¶
- module: types.ModuleType | None¶
- modpath: str | os.PathLike[str]¶
- fpath: str | os.PathLike[str] | None¶
- exc_info: tuple[type[BaseException], BaseException, types.TracebackType] | tuple[None, None, None] | None¶
- is_disabled(pytest=False) bool[source]¶
Checks for comment directives on the first line of the doctest
A doctest is force-disabled if it starts with any of the following patterns
>>> # DISABLE_DOCTEST>>> # SCRIPT>>> # UNSTABLE>>> # FAILING
And if running in pytest, you can also use
>>> import pytest; pytest.skip()
Note
modern versions of xdoctest contain directives like # xdoctest: +SKIP, which are a better way to do this.
Todo
Robustly deprecate these non-standard ways of disabling a doctest. Generate a warning for several versions if they are used, and indicate what the replacement strategy is. Then raise an error for several more versions before finally removing this code.
- Return type:
- format_parts(linenos: bool = True, colored: bool | None = None, want: bool = True, offset_linenos: bool | None = None, prefix: bool = True)[source]¶
Used by
format_src()- Parameters:
linenos (bool) – show line numbers
colored (bool | None) – pygmentize the code
want (bool) – include the want value if it exists
offset_linenos (bool) – if True include the line offset relative to the source file
prefix (bool) – if False, exclude the doctest ``>>> `` prefix
- format_src(linenos: bool = True, colored: bool | None = None, want: bool = True, offset_linenos: bool | None = None, prefix: bool = True) str[source]¶
Adds prefix and line numbers to a doctest
- Parameters:
linenos (bool) – if True, adds line numbers to output
colored (bool) – if True highlight text with ansi colors. Default is specified in the config.
want (bool) – if True includes “want” lines (default False).
offset_linenos (bool) – if True offset line numbers to agree with their position in the source text file (default False).
prefix (bool) – if False, exclude the doctest ``>>> `` prefix
- Returns:
str
Example
>>> from xdoctest.core import * >>> from xdoctest import core >>> testables = parse_doctestables(core.__file__) >>> self = next(testables) >>> self._parse() >>> print(self.format_src()) >>> print(self.format_src(linenos=False, colored=False)) >>> assert not self.is_disabled()
- _parse() None[source]¶
Divide the given string into examples and intervening text.
- Returns:
None
Example
>>> s = 'I am a dummy example with three parts' >>> x = 10 >>> print(s) I am a dummy example with three parts >>> s = 'My purpose it so demonstrate how wants work here' >>> print('The new want applies ONLY to stdout') >>> print('given before the last want') >>> ''' this wont hurt the test at all even though its multiline ''' >>> y = 20 The new want applies ONLY to stdout given before the last want >>> # Parts from previous examples are executed in the same context >>> print(x + y) 30
this is simply text, and doesnt apply to the previous doctest the <BLANKLINE> directive is still in effect.
Example
>>> from xdoctest import parser >>> from xdoctest.docstr import docscrape_google >>> from xdoctest import doctest_example >>> DocTest = doctest_example.DocTest >>> docstr = DocTest._parse.__doc__ >>> blocks = docscrape_google.split_google_docblocks(docstr) >>> doclineno = DocTest._parse.__code__.co_firstlineno >>> key, (docsrc, offset) = blocks[-2] >>> lineno = doclineno + offset >>> self = DocTest(docsrc, doctest_example.__file__, '_parse', 0, >>> lineno) >>> self._parse() >>> assert len(self._parts) >= 3 >>> #p1, p2, p3 = self._parts >>> self.run()
- _part_context(part: DoctestPart, partx: int) AbstractContextManager[object][source]¶
Return a context manager that wraps the execution of one doctest part, applying the runtime warning policy.
When
IGNORE_WARNINGSis active for the part, warnings emitted during execution are silenced. WhenSHOW_WARNINGSis active, warnings are captured and printed asCategory: messagelines into the part’s output so they participate in got/want matching. Both are applied at the runner level — the part’s source is never rewritten, so failure line numbers always point at user code.- Parameters:
part – the
xdoctest.doctest_part.DoctestPartabout to run.partx (int) – the part’s index within
self._parts.
- _import_module() None[source]¶
After this point we are in dynamic analysis mode, in most cases xdoctest should have been in static-analysis-only mode.
- Returns:
None
- static _extract_future_flags(namespace: Mapping) int[source]¶
Return the compiler-flags associated with the future features that have been imported into the given namespace (i.e. globals).
- Returns:
int
- _partfilename_for(partno: int) str[source]¶
Construct a synthetic filename for a specific doctest part.
We can’t use one filename for the entire doctest because traceback frames only record a filename + line number. If every compiled part shares the same filename, then when a traceback points into code defined in an earlier part, we cannot tell which part that line number belongs to.
Giving each part its own pseudo-filename makes traceback ownership unambiguous.
- _apply_module_doctest_metadata(runstate: RuntimeState) str | None[source]¶
Apply module-level doctest metadata and return a concrete skip reason.
Loaded modules are authoritative because their metadata may be computed dynamically. Otherwise the source file is read through the stat-aware static metadata cache. This method is called once for each run, while unchanged file parsing is shared across doctests from the same module.
- _unmet_module_requirement(requires_spec: Any) str | None[source]¶
Return the first applicable unmet module requirement, if any.
- run(verbose: int | None | bool = None, on_error: str | None = None) dict[str, Any][source]¶
Executes the doctest, checks the results, reports the outcome.
- Parameters:
verbose (int) – verbosity level
on_error (str) – can be ‘raise’ or ‘return’
- Returns:
summary
- Return type:
Dict
- _check_or_defer_part_output(part: DoctestPart, got_stdout: str | None, got_eval: Any, runstate: directive.RuntimeState) None[source]¶
Apply the configured output contract for one executed part.
With the default configuration, parts without a local want may defer stdout for later trailing matching, while parts with a local want are checked immediately. The deferred_output_matching knob disables the deferred-trailing behavior. The REQUIRE_WANT runtime directive makes output-producing parts require an explicit local want unless IGNORE_WANT or IGNORE_OUTPUT is active. Either ignore directive is treated as a boundary and does not contribute output to later matching.
- property globs¶
Alias for
global_namespacefor pytest 8.0 compatibility
- property _block_prefix¶
- repr_failure(with_tb: Any = True) list[str][source]¶
Constructs lines detailing information about a failed doctest
- Parameters:
with_tb (bool) – if True include the traceback
- Returns:
List[str]
CommandLine
python -m xdoctest.core DocTest.repr_failure:0 python -m xdoctest.core DocTest.repr_failure:1 python -m xdoctest.core DocTest.repr_failure:2
Example
>>> from xdoctest.core import * >>> docstr = utils.codeblock( ''' >>> x = 1 >>> print(x + 1) 2 >>> print(x + 3) 3 >>> print(x + 100) 101 ''') >>> parsekw = dict(fpath='foo.txt', callname='bar', lineno=42) >>> self = list(parse_docstr_examples(docstr, **parsekw))[0] >>> summary = self.run(on_error='return', verbose=0) >>> print('[res]' + '\n[res]'.join(self.repr_failure()))
Example
>>> from xdoctest.core import * >>> docstr = utils.codeblock( r''' >>> 1 1 >>> print('.▴ .\n.▴ ▴.') # xdoc: -NORMALIZE_WHITESPACE . ▴ . .▴ ▴. ''') >>> parsekw = dict(fpath='foo.txt', callname='bar', lineno=42) >>> self = list(parse_docstr_examples(docstr, **parsekw))[0] >>> summary = self.run(on_error='return', verbose=1) >>> print('[res]' + '\n[res]'.join(self.repr_failure()))
Example
>>> from xdoctest.core import * >>> docstr = utils.codeblock( ''' >>> assert True >>> assert False >>> x = 100 ''') >>> self = list(parse_docstr_examples(docstr))[0] >>> summary = self.run(on_error='return', verbose=0) >>> print('[res]' + '\n[res]'.join(self.repr_failure()))