Classes involved in doctesting¶
This module controls the various classes involved in doctesting.
AUTHORS:
- David Roe (2012-03-27) – initial version, based on Robert Bradshaw’s code. 
- class sage.doctest.control.DocTestController(options, args)[source]¶
- Bases: - SageObject- This class controls doctesting of files. - After creating it with appropriate options, call the - run()method to run the doctests.- add_files()[source]¶
- Check for the flags ‘–all’ and ‘–new’. - For each one present, this function adds the appropriate directories and files to the todo list. - EXAMPLES: - sage: from sage.doctest.control import (DocTestDefaults, ....: DocTestController) sage: from sage.env import SAGE_SRC sage: import tempfile sage: with tempfile.NamedTemporaryFile() as f: ....: DD = DocTestDefaults(all=True, logfile=f.name) ....: DC = DocTestController(DD, []) ....: DC.add_files() Doctesting ... sage: os.path.join(SAGE_SRC, 'sage') in DC.files True - >>> from sage.all import * >>> from sage.doctest.control import (DocTestDefaults, ... DocTestController) >>> from sage.env import SAGE_SRC >>> import tempfile >>> with tempfile.NamedTemporaryFile() as f: ... DD = DocTestDefaults(all=True, logfile=f.name) ... DC = DocTestController(DD, []) ... DC.add_files() Doctesting ... >>> os.path.join(SAGE_SRC, 'sage') in DC.files True - sage: DD = DocTestDefaults(new = True) sage: DC = DocTestController(DD, []) sage: DC.add_files() Doctesting ... - >>> from sage.all import * >>> DD = DocTestDefaults(new = True) >>> DC = DocTestController(DD, []) >>> DC.add_files() Doctesting ... 
 - cleanup(final=True)[source]¶
- Run cleanup activities after actually running doctests. - In particular, saves the stats to disk and closes the logfile. - INPUT: - final– whether to close the logfile
 - EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: from sage.env import SAGE_SRC sage: import os sage: dirname = os.path.join(SAGE_SRC, 'sage', 'rings', 'all.py') sage: DD = DocTestDefaults() sage: DC = DocTestController(DD, [dirname]) sage: DC.expand_files_into_sources() sage: DC.sources.sort(key=lambda s:s.basename) sage: for i, source in enumerate(DC.sources): ....: DC.stats[source.basename] = {'walltime': 0.1r * (i+1)} ....: sage: DC.run() Running doctests with ID ... Doctesting 1 file. sage -t .../rings/all.py [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 0 sage: DC.cleanup() - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> from sage.env import SAGE_SRC >>> import os >>> dirname = os.path.join(SAGE_SRC, 'sage', 'rings', 'all.py') >>> DD = DocTestDefaults() >>> DC = DocTestController(DD, [dirname]) >>> DC.expand_files_into_sources() >>> DC.sources.sort(key=lambda s:s.basename) >>> for i, source in enumerate(DC.sources): ... DC.stats[source.basename] = {'walltime': 0.1 * (i+Integer(1))} ....: >>> DC.run() Running doctests with ID ... Doctesting 1 file. sage -t .../rings/all.py [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 0 >>> DC.cleanup() 
 - create_run_id()[source]¶
- Create the run id. - EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: DC = DocTestController(DocTestDefaults(), []) sage: DC.create_run_id() Running doctests with ID ... - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> DC = DocTestController(DocTestDefaults(), []) >>> DC.create_run_id() Running doctests with ID ... 
 - expand_files_into_sources()[source]¶
- Expand - self.files, which may include directories, into a list of- sage.doctest.FileDocTestSource- This function also handles the optional command line option. - EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: from sage.env import SAGE_SRC sage: import os sage: dirname = os.path.join(SAGE_SRC, 'sage', 'doctest') sage: DD = DocTestDefaults(optional='all') sage: DC = DocTestController(DD, [dirname]) sage: DC.expand_files_into_sources() sage: len(DC.sources) 15 sage: DC.sources[0].options.optional True - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> from sage.env import SAGE_SRC >>> import os >>> dirname = os.path.join(SAGE_SRC, 'sage', 'doctest') >>> DD = DocTestDefaults(optional='all') >>> DC = DocTestController(DD, [dirname]) >>> DC.expand_files_into_sources() >>> len(DC.sources) 15 >>> DC.sources[Integer(0)].options.optional True - sage: DD = DocTestDefaults(optional='magma,guava') sage: DC = DocTestController(DD, [dirname]) sage: DC.expand_files_into_sources() sage: all(t in DC.sources[0].options.optional for t in ['magma','guava']) True - >>> from sage.all import * >>> DD = DocTestDefaults(optional='magma,guava') >>> DC = DocTestController(DD, [dirname]) >>> DC.expand_files_into_sources() >>> all(t in DC.sources[Integer(0)].options.optional for t in ['magma','guava']) True - We check that files are skipped appropriately: - sage: dirname = tmp_dir() sage: filename = os.path.join(dirname, 'not_tested.py') sage: with open(filename, 'w') as f: ....: _ = f.write("#"*80 + "\n\n\n\n## nodoctest\n sage: 1+1\n 4") sage: DC = DocTestController(DD, [dirname]) sage: DC.expand_files_into_sources() sage: DC.sources [] - >>> from sage.all import * >>> dirname = tmp_dir() >>> filename = os.path.join(dirname, 'not_tested.py') >>> with open(filename, 'w') as f: ... _ = f.write("#"*Integer(80) + "\n\n\n\n## nodoctest\n sage: 1+1\n 4") >>> DC = DocTestController(DD, [dirname]) >>> DC.expand_files_into_sources() >>> DC.sources [] - The directory - sage/doctest/testscontains- nodoctest.pybut the files should still be tested when that directory is explicitly given (as opposed to being recursed into):- sage: DC = DocTestController(DD, [os.path.join(SAGE_SRC, 'sage', 'doctest', 'tests')]) sage: DC.expand_files_into_sources() sage: len(DC.sources) >= 10 True - >>> from sage.all import * >>> DC = DocTestController(DD, [os.path.join(SAGE_SRC, 'sage', 'doctest', 'tests')]) >>> DC.expand_files_into_sources() >>> len(DC.sources) >= Integer(10) True 
 - filter_sources()[source]¶
- EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: from sage.env import SAGE_SRC sage: import os sage: dirname = os.path.join(SAGE_SRC, 'sage', 'doctest') sage: DD = DocTestDefaults(failed=True) sage: DC = DocTestController(DD, [dirname]) sage: DC.expand_files_into_sources() sage: for i, source in enumerate(DC.sources): ....: DC.stats[source.basename] = {'walltime': 0.1r * (i+1)} sage: DC.stats['sage.doctest.control'] = {'failed': True, 'walltime': 1.0r} sage: DC.filter_sources() Only doctesting files that failed last test. sage: len(DC.sources) 1 - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> from sage.env import SAGE_SRC >>> import os >>> dirname = os.path.join(SAGE_SRC, 'sage', 'doctest') >>> DD = DocTestDefaults(failed=True) >>> DC = DocTestController(DD, [dirname]) >>> DC.expand_files_into_sources() >>> for i, source in enumerate(DC.sources): ... DC.stats[source.basename] = {'walltime': 0.1 * (i+Integer(1))} >>> DC.stats['sage.doctest.control'] = {'failed': True, 'walltime': 1.0} >>> DC.filter_sources() Only doctesting files that failed last test. >>> len(DC.sources) 1 
 - load_baseline_stats(filename)[source]¶
- Load baseline stats. - This must be a JSON file in the same format that - load_stats()expects.- EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: DC = DocTestController(DocTestDefaults(), []) sage: import json sage: filename = tmp_filename() sage: with open(filename, 'w') as stats_file: ....: json.dump({'sage.doctest.control':{'failed':True}}, stats_file) sage: DC.load_baseline_stats(filename) sage: DC.baseline_stats['sage.doctest.control'] {'failed': True} - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> DC = DocTestController(DocTestDefaults(), []) >>> import json >>> filename = tmp_filename() >>> with open(filename, 'w') as stats_file: ... json.dump({'sage.doctest.control':{'failed':True}}, stats_file) >>> DC.load_baseline_stats(filename) >>> DC.baseline_stats['sage.doctest.control'] {'failed': True} - If the file doesn’t exist, nothing happens. If there is an error, print a message. In any case, leave the stats alone: - sage: d = tmp_dir() sage: DC.load_baseline_stats(os.path.join(d)) # Cannot read a directory Error loading baseline stats from ... sage: DC.load_baseline_stats(os.path.join(d, "no_such_file")) sage: DC.baseline_stats['sage.doctest.control'] {'failed': True} - >>> from sage.all import * >>> d = tmp_dir() >>> DC.load_baseline_stats(os.path.join(d)) # Cannot read a directory Error loading baseline stats from ... >>> DC.load_baseline_stats(os.path.join(d, "no_such_file")) >>> DC.baseline_stats['sage.doctest.control'] {'failed': True} 
 - load_environment()[source]¶
- Return the module that provides the global environment. - EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: DC = DocTestController(DocTestDefaults(), []) sage: 'BipartiteGraph' in DC.load_environment().__dict__ True sage: DC = DocTestController(DocTestDefaults(environment='sage.doctest.all'), []) sage: 'BipartiteGraph' in DC.load_environment().__dict__ False sage: 'run_doctests' in DC.load_environment().__dict__ True - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> DC = DocTestController(DocTestDefaults(), []) >>> 'BipartiteGraph' in DC.load_environment().__dict__ True >>> DC = DocTestController(DocTestDefaults(environment='sage.doctest.all'), []) >>> 'BipartiteGraph' in DC.load_environment().__dict__ False >>> 'run_doctests' in DC.load_environment().__dict__ True 
 - load_stats(filename)[source]¶
- Load stats from the most recent run(s). - Stats are stored as a JSON file, and include information on which files failed tests and the walltime used for execution of the doctests. - EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: DC = DocTestController(DocTestDefaults(), []) sage: import json sage: filename = tmp_filename() sage: with open(filename, 'w') as stats_file: ....: json.dump({'sage.doctest.control': {'walltime': 1.0r}}, stats_file) sage: DC.load_stats(filename) sage: DC.stats['sage.doctest.control'] {'walltime': 1.0} - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> DC = DocTestController(DocTestDefaults(), []) >>> import json >>> filename = tmp_filename() >>> with open(filename, 'w') as stats_file: ... json.dump({'sage.doctest.control': {'walltime': 1.0}}, stats_file) >>> DC.load_stats(filename) >>> DC.stats['sage.doctest.control'] {'walltime': 1.0} - If the file doesn’t exist, nothing happens. If there is an error, print a message. In any case, leave the stats alone: - sage: d = tmp_dir() sage: DC.load_stats(os.path.join(d)) # Cannot read a directory Error loading stats from ... sage: DC.load_stats(os.path.join(d, "no_such_file")) sage: DC.stats['sage.doctest.control'] {'walltime': 1.0} - >>> from sage.all import * >>> d = tmp_dir() >>> DC.load_stats(os.path.join(d)) # Cannot read a directory Error loading stats from ... >>> DC.load_stats(os.path.join(d, "no_such_file")) >>> DC.stats['sage.doctest.control'] {'walltime': 1.0} 
 - log(s, end='\n')[source]¶
- Log the string - s + end(where- endis a newline by default) to the logfile and print it to the standard output.- EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: DD = DocTestDefaults(logfile=tmp_filename()) sage: DC = DocTestController(DD, []) sage: DC.log("hello world") hello world sage: DC.logfile.close() sage: with open(DD.logfile) as f: ....: print(f.read()) hello world - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> DD = DocTestDefaults(logfile=tmp_filename()) >>> DC = DocTestController(DD, []) >>> DC.log("hello world") hello world >>> DC.logfile.close() >>> with open(DD.logfile) as f: ... print(f.read()) hello world - In serial mode, check that logging works even if - stdoutis redirected:- sage: DD = DocTestDefaults(logfile=tmp_filename(), serial=True) sage: DC = DocTestController(DD, []) sage: from sage.doctest.forker import SageSpoofInOut sage: with open(os.devnull, 'w') as devnull: ....: S = SageSpoofInOut(devnull) ....: S.start_spoofing() ....: DC.log("hello world") ....: S.stop_spoofing() hello world sage: DC.logfile.close() sage: with open(DD.logfile) as f: ....: print(f.read()) hello world - >>> from sage.all import * >>> DD = DocTestDefaults(logfile=tmp_filename(), serial=True) >>> DC = DocTestController(DD, []) >>> from sage.doctest.forker import SageSpoofInOut >>> with open(os.devnull, 'w') as devnull: ... S = SageSpoofInOut(devnull) ... S.start_spoofing() ... DC.log("hello world") ... S.stop_spoofing() hello world >>> DC.logfile.close() >>> with open(DD.logfile) as f: ... print(f.read()) hello world - Check that no duplicate logs appear, even when forking (Issue #15244): - sage: DD = DocTestDefaults(logfile=tmp_filename()) sage: DC = DocTestController(DD, []) sage: DC.log("hello world") hello world sage: if os.fork() == 0: ....: DC.logfile.close() ....: os._exit(0) sage: DC.logfile.close() sage: with open(DD.logfile) as f: ....: print(f.read()) hello world - >>> from sage.all import * >>> DD = DocTestDefaults(logfile=tmp_filename()) >>> DC = DocTestController(DD, []) >>> DC.log("hello world") hello world >>> if os.fork() == Integer(0): ... DC.logfile.close() ... os._exit(Integer(0)) >>> DC.logfile.close() >>> with open(DD.logfile) as f: ... print(f.read()) hello world 
 - run()[source]¶
- This function is called after initialization to set up and run all doctests. - EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: from sage.env import SAGE_SRC sage: import os sage: DD = DocTestDefaults() sage: filename = os.path.join(SAGE_SRC, "sage", "sets", "non_negative_integers.py") sage: DC = DocTestController(DD, [filename]) sage: DC.run() Running doctests with ID ... Doctesting 1 file. sage -t .../sage/sets/non_negative_integers.py [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 0 - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> from sage.env import SAGE_SRC >>> import os >>> DD = DocTestDefaults() >>> filename = os.path.join(SAGE_SRC, "sage", "sets", "non_negative_integers.py") >>> DC = DocTestController(DD, [filename]) >>> DC.run() Running doctests with ID ... Doctesting 1 file. sage -t .../sage/sets/non_negative_integers.py [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 0 - We check that Issue #25378 is fixed (testing external packages while providing a logfile does not raise a ValueError: I/O operation on closed file): - sage: logfile = tmp_filename(ext='.log') sage: DD = DocTestDefaults(optional=set(['sage', 'external']), logfile=logfile) sage: filename = tmp_filename(ext='.py') sage: DC = DocTestController(DD, [filename]) sage: DC.run() Running doctests with ID ... Using --optional=external,sage Features to be detected: ... Doctesting 1 file. sage -t ....py [0 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 0 - >>> from sage.all import * >>> logfile = tmp_filename(ext='.log') >>> DD = DocTestDefaults(optional=set(['sage', 'external']), logfile=logfile) >>> filename = tmp_filename(ext='.py') >>> DC = DocTestController(DD, [filename]) >>> DC.run() Running doctests with ID ... Using --optional=external,sage Features to be detected: ... Doctesting 1 file. sage -t ....py [0 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 0 - We test the - --hideoption (Issue #34185):- sage: from sage.doctest.control import test_hide sage: filename = tmp_filename(ext='.py') sage: with open(filename, 'w') as f: ....: f.write(test_hide) ....: f.close() 714 sage: DF = DocTestDefaults(hide='buckygen,all') sage: DC = DocTestController(DF, [filename]) sage: DC.run() Running doctests with ID ... Using --optional=sage... Features to be detected: ... Doctesting 1 file. sage -t ....py [4 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 0 sage: DF = DocTestDefaults(hide='benzene,optional') sage: DC = DocTestController(DF, [filename]) sage: DC.run() Running doctests with ID ... Using --optional=sage Features to be detected: ... Doctesting 1 file. sage -t ....py [4 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 0 - >>> from sage.all import * >>> from sage.doctest.control import test_hide >>> filename = tmp_filename(ext='.py') >>> with open(filename, 'w') as f: ... f.write(test_hide) ... f.close() 714 >>> DF = DocTestDefaults(hide='buckygen,all') >>> DC = DocTestController(DF, [filename]) >>> DC.run() Running doctests with ID ... Using --optional=sage... Features to be detected: ... Doctesting 1 file. sage -t ....py [4 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 0 >>> DF = DocTestDefaults(hide='benzene,optional') >>> DC = DocTestController(DF, [filename]) >>> DC.run() Running doctests with ID ... Using --optional=sage Features to be detected: ... Doctesting 1 file. sage -t ....py [4 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 0 - Test Features that have been hidden message: - sage: DC.run() # optional - meataxe Running doctests with ID ... Using --optional=sage Features to be detected: ... Doctesting 1 file. sage -t ....py [4 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... Features that have been hidden: ...meataxe... 0 - >>> from sage.all import * >>> DC.run() # optional - meataxe Running doctests with ID ... Using --optional=sage Features to be detected: ... Doctesting 1 file. sage -t ....py [4 tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... Features that have been hidden: ...meataxe... 0 
 - run_doctests()[source]¶
- Actually run the doctests. - This function is called by - run().- EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: from sage.env import SAGE_SRC sage: import os sage: dirname = os.path.join(SAGE_SRC, 'sage', 'rings', 'homset.py') sage: DD = DocTestDefaults() sage: DC = DocTestController(DD, [dirname]) sage: DC.expand_files_into_sources() sage: DC.run_doctests() Doctesting 1 file. sage -t .../sage/rings/homset.py [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds... - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> from sage.env import SAGE_SRC >>> import os >>> dirname = os.path.join(SAGE_SRC, 'sage', 'rings', 'homset.py') >>> DD = DocTestDefaults() >>> DC = DocTestController(DD, [dirname]) >>> DC.expand_files_into_sources() >>> DC.run_doctests() Doctesting 1 file. sage -t .../sage/rings/homset.py [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds... 
 - run_val_gdb(testing=False)[source]¶
- Spawns a subprocess to run tests under the control of gdb, lldb, or valgrind. - INPUT: - testing– boolean (default:- False); if- Truethen the command to be run will be printed rather than a subprocess started
 - EXAMPLES: - Note that the command lines include unexpanded environment variables. It is safer to let the shell expand them than to expand them here and risk insufficient quoting. - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: DD = DocTestDefaults(gdb=True) sage: DC = DocTestController(DD, ["hello_world.py"]) sage: DC.run_val_gdb(testing=True) exec gdb --eval-command="run" --args ...python... -m sage.doctest --serial... --timeout=0... hello_world.py - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> DD = DocTestDefaults(gdb=True) >>> DC = DocTestController(DD, ["hello_world.py"]) >>> DC.run_val_gdb(testing=True) exec gdb --eval-command="run" --args ...python... -m sage.doctest --serial... --timeout=0... hello_world.py - sage: DD = DocTestDefaults(valgrind=True, optional='all', timeout=172800) sage: DC = DocTestController(DD, ["hello_world.py"]) sage: DC.run_val_gdb(testing=True) exec valgrind --tool=memcheck --leak-resolution=high --leak-check=full --num-callers=25 --suppressions=.../valgrind/pyalloc.supp --suppressions=.../valgrind/sage.supp --suppressions=.../valgrind/sage-additional.supp --suppressions=.../valgrind/valgrind-python.supp --log-file=.../valgrind/sage-memcheck.%p ...python... -m sage.doctest --serial... --timeout=172800... --optional=all hello_world.py - >>> from sage.all import * >>> DD = DocTestDefaults(valgrind=True, optional='all', timeout=Integer(172800)) >>> DC = DocTestController(DD, ["hello_world.py"]) >>> DC.run_val_gdb(testing=True) exec valgrind --tool=memcheck --leak-resolution=high --leak-check=full --num-callers=25 --suppressions=.../valgrind/pyalloc.supp --suppressions=.../valgrind/sage.supp --suppressions=.../valgrind/sage-additional.supp --suppressions=.../valgrind/valgrind-python.supp --log-file=.../valgrind/sage-memcheck.%p ...python... -m sage.doctest --serial... --timeout=172800... --optional=all hello_world.py 
 - save_stats(filename)[source]¶
- Save stats from the most recent run as a JSON file. - WARNING: This function overwrites the file. - EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: DC = DocTestController(DocTestDefaults(), []) sage: DC.stats['sage.doctest.control'] = {'walltime': 1.0r} sage: filename = tmp_filename() sage: DC.save_stats(filename) sage: import json sage: with open(filename) as f: ....: D = json.load(f) sage: D['sage.doctest.control'] {'walltime': 1.0} - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> DC = DocTestController(DocTestDefaults(), []) >>> DC.stats['sage.doctest.control'] = {'walltime': 1.0} >>> filename = tmp_filename() >>> DC.save_stats(filename) >>> import json >>> with open(filename) as f: ... D = json.load(f) >>> D['sage.doctest.control'] {'walltime': 1.0} 
 - second_on_modern_computer()[source]¶
- Return the wall time equivalent of a second on a modern computer. - OUTPUT: - Float. The wall time on your computer that would be equivalent to one second on a modern computer. Unless you have kick-ass hardware this should always be >= 1.0. This raises a - RuntimeErrorif there are no stored timings to use as benchmark.- EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: DC = DocTestController(DocTestDefaults(), []) sage: DC.second_on_modern_computer() # not tested - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> DC = DocTestController(DocTestDefaults(), []) >>> DC.second_on_modern_computer() # not tested 
 - sort_sources()[source]¶
- This function sorts the sources so that slower doctests are run first. - EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: from sage.env import SAGE_SRC sage: import os sage: dirname = os.path.join(SAGE_SRC, 'sage', 'doctest') sage: DD = DocTestDefaults(nthreads=2) sage: DC = DocTestController(DD, [dirname]) sage: DC.expand_files_into_sources() sage: DC.sources.sort(key=lambda s:s.basename) sage: for i, source in enumerate(DC.sources): ....: DC.stats[source.basename] = {'walltime': 0.1r * (i+1)} sage: DC.sort_sources() Sorting sources by runtime so that slower doctests are run first.... sage: print("\n".join(source.basename for source in DC.sources)) sage.doctest.util sage.doctest.test sage.doctest.sources sage.doctest.rif_tol sage.doctest.reporting sage.doctest.parsing_test sage.doctest.parsing sage.doctest.marked_output sage.doctest.forker sage.doctest.fixtures sage.doctest.external sage.doctest.control sage.doctest.check_tolerance sage.doctest.all sage.doctest - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> from sage.env import SAGE_SRC >>> import os >>> dirname = os.path.join(SAGE_SRC, 'sage', 'doctest') >>> DD = DocTestDefaults(nthreads=Integer(2)) >>> DC = DocTestController(DD, [dirname]) >>> DC.expand_files_into_sources() >>> DC.sources.sort(key=lambda s:s.basename) >>> for i, source in enumerate(DC.sources): ... DC.stats[source.basename] = {'walltime': 0.1 * (i+Integer(1))} >>> DC.sort_sources() Sorting sources by runtime so that slower doctests are run first.... >>> print("\n".join(source.basename for source in DC.sources)) sage.doctest.util sage.doctest.test sage.doctest.sources sage.doctest.rif_tol sage.doctest.reporting sage.doctest.parsing_test sage.doctest.parsing sage.doctest.marked_output sage.doctest.forker sage.doctest.fixtures sage.doctest.external sage.doctest.control sage.doctest.check_tolerance sage.doctest.all sage.doctest 
 - source_baseline(source)[source]¶
- Return the - baseline_statsvalue of- source.- INPUT: - source– a- DocTestSourceinstance
 - OUTPUT: a dictionary - EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults, DocTestController sage: filename = sage.doctest.util.__file__ sage: DD = DocTestDefaults() sage: DC = DocTestController(DD, [filename]) sage: DC.expand_files_into_sources() sage: DC.source_baseline(DC.sources[0]) {} - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults, DocTestController >>> filename = sage.doctest.util.__file__ >>> DD = DocTestDefaults() >>> DC = DocTestController(DD, [filename]) >>> DC.expand_files_into_sources() >>> DC.source_baseline(DC.sources[Integer(0)]) {} 
 
- class sage.doctest.control.DocTestDefaults(runtest_default=False, **kwds)[source]¶
- Bases: - SageObject- This class is used for doctesting the Sage doctest module. - INPUT: - runtest_default– (boolean, default- False); if- True, fills in attribute to be the same as the defaults defined in- sage-runtests. If- False, change defaults in a few places for use in doctests of the doctester, which is mostly to make doctesting more predictable.
- **kwds– attributes to override defaults
 - EXAMPLES: - sage: from sage.doctest.control import DocTestDefaults sage: D = DocTestDefaults(); D DocTestDefaults() sage: D.timeout -1 - >>> from sage.all import * >>> from sage.doctest.control import DocTestDefaults >>> D = DocTestDefaults(); D DocTestDefaults() >>> D.timeout -1 - Keyword arguments become attributes: - sage: D = DocTestDefaults(timeout=100); D DocTestDefaults(timeout=100) sage: D.timeout 100 - >>> from sage.all import * >>> D = DocTestDefaults(timeout=Integer(100)); D DocTestDefaults(timeout=100) >>> D.timeout 100 - The defaults for - sage-runtests:- sage: D = DocTestDefaults(runtest_default=True); D DocTestDefaults(abspath=False, file_iterations=0, global_iterations=0, optional='sage,optional', random_seed=None, stats_path='.../timings2.json') - >>> from sage.all import * >>> D = DocTestDefaults(runtest_default=True); D DocTestDefaults(abspath=False, file_iterations=0, global_iterations=0, optional='sage,optional', random_seed=None, stats_path='.../timings2.json') 
- class sage.doctest.control.Logger(*files)[source]¶
- Bases: - object- File-like object which implements writing to multiple files at once. - EXAMPLES: - sage: from sage.doctest.control import Logger sage: with open(tmp_filename(), "w+") as t: ....: L = Logger(sys.stdout, t) ....: _ = L.write("hello world\n") ....: _ = t.seek(0) ....: t.read() hello world 'hello world\n' - >>> from sage.all import * >>> from sage.doctest.control import Logger >>> with open(tmp_filename(), "w+") as t: ... L = Logger(sys.stdout, t) ... _ = L.write("hello world\n") ... _ = t.seek(Integer(0)) ... t.read() hello world 'hello world\n' 
- sage.doctest.control.run_doctests(module, options=None)[source]¶
- Run the doctests in a given file. - INPUT: - module– a Sage module, a string, or a list of such
- options– a DocTestDefaults object or- None
 - EXAMPLES: - sage: run_doctests(sage.rings.all) Running doctests with ID ... Doctesting 1 file. sage -t .../sage/rings/all.py [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... - >>> from sage.all import * >>> run_doctests(sage.rings.all) Running doctests with ID ... Doctesting 1 file. sage -t .../sage/rings/all.py [... tests, ...s wall] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- Total time for all tests: ... seconds cpu time: ... seconds cumulative wall time: ... seconds Features detected... 
- sage.doctest.control.skipdir(dirname)[source]¶
- Return - Trueif and only if the directory- dirnameshould not be doctested.- EXAMPLES: - sage: from sage.doctest.control import skipdir sage: skipdir(sage.env.SAGE_SRC) False sage: skipdir(os.path.join(sage.env.SAGE_SRC, "sage", "doctest", "tests")) True - >>> from sage.all import * >>> from sage.doctest.control import skipdir >>> skipdir(sage.env.SAGE_SRC) False >>> skipdir(os.path.join(sage.env.SAGE_SRC, "sage", "doctest", "tests")) True 
- sage.doctest.control.skipfile(filename, tested_optional_tags, if_installed, log=False)[source]¶
- Return - Trueif and only if the file- filenameshould not be doctested.- INPUT: - filename– name of a file
- tested_optional_tags– list or tuple or set of optional tags to test, or- False(no optional test) or- True(all optional tests)
- if_installed– boolean (default:- False); whether to skip Python/Cython files that are not installed as modules
- log– function to call with log messages, or- None
 - If - filenamecontains a line of the form- "# sage.doctest: optional - xyz"), then this will return- Falseif “xyz” is in- tested_optional_tags. Otherwise, it returns the matching tag (“optional - xyz”).- EXAMPLES: - sage: from sage.doctest.control import skipfile sage: skipfile("skipme.c") True sage: filename = tmp_filename(ext='.pyx') sage: skipfile(filename) False sage: with open(filename, "w") as f: ....: _ = f.write("# nodoctest") sage: skipfile(filename) True sage: with open(filename, "w") as f: ....: _ = f.write("# sage.doctest: " # broken in two source lines to avoid the pattern ....: "optional - xyz") # of relint (multiline_doctest_comment) sage: skipfile(filename, False) 'optional - xyz' sage: bool(skipfile(filename, False)) True sage: skipfile(filename, ['abc']) 'optional - xyz' sage: skipfile(filename, ['abc', 'xyz']) False sage: skipfile(filename, True) False - >>> from sage.all import * >>> from sage.doctest.control import skipfile >>> skipfile("skipme.c") True >>> filename = tmp_filename(ext='.pyx') >>> skipfile(filename) False >>> with open(filename, "w") as f: ... _ = f.write("# nodoctest") >>> skipfile(filename) True >>> with open(filename, "w") as f: ... _ = f.write("# sage.doctest: " # broken in two source lines to avoid the pattern ... "optional - xyz") # of relint (multiline_doctest_comment) >>> skipfile(filename, False) 'optional - xyz' >>> bool(skipfile(filename, False)) True >>> skipfile(filename, ['abc']) 'optional - xyz' >>> skipfile(filename, ['abc', 'xyz']) False >>> skipfile(filename, True) False