Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
sage.doctest: Handle file directives '# sage.doctest: optional - xyz'
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Koeppe committed Feb 18, 2021
1 parent 8453ffb commit b92e036
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
15 changes: 15 additions & 0 deletions src/doc/en/developer/coding_basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,21 @@ framework. Here is a comprehensive list:

sage: SloaneEncyclopedia[60843] # optional - sloane_database

.. NOTE::

If one of the first 10 lines of a file starts with any of
``r""" sage.doctest: optional - keyword``
(or ``""" sage.doctest: optional - keyword``
or ``# sage.doctest: optional - keyword``
or ``% sage.doctest: optional - keyword``
or ``.. sage.doctest: optional - keyword``,
or any of these with different spacing),
then that file will be skipped unless
the ``--optional=keyword`` flag is passed to ``sage -t``.

This does not apply to files which are explicitly given
as command line arguments: those are always tested.

- **internet:** For lines that require an internet connection::

sage: oeis(60843) # optional - internet
Expand Down
33 changes: 31 additions & 2 deletions src/sage/doctest/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@
from .reporting import DocTestReporter
from .util import Timer, count_noun, dict_difference
from .external import external_software, available_software
from .parsing import parse_optional_tags

nodoctest_regex = re.compile(r'\s*(#+|%+|r"+|"+|\.\.)\s*nodoctest')
optionaltag_regex = re.compile(r'^\w+$')
optionalfiledirective_regex = re.compile(r'\s*(#+|%+|r"+|"+|\.\.)\s*sage\.doctest: (.*)')

# Optional tags which are always automatically added

Expand Down Expand Up @@ -202,11 +204,18 @@ def skipdir(dirname):
return True
return False

def skipfile(filename):
def skipfile(filename, tested_optional_tags=False):
"""
Return True if and only if the file ``filename`` should not be
doctested.
INPUT:
- ``filename`` - name of a file
- ``tested_optional_tags`` - a list or tuple or set of optional tags to test,
or ``False`` (no optional test) or ``True`` (all optional tests)
EXAMPLES::
sage: from sage.doctest.control import skipfile
Expand All @@ -219,6 +228,16 @@ def skipfile(filename):
....: _ = f.write("# nodoctest")
sage: skipfile(filename)
True
sage: with open(filename, "w") as f:
....: _ = f.write("# sage.doctest: optional - xyz")
sage: skipfile(filename, False)
True
sage: skipfile(filename, ['abc'])
True
sage: skipfile(filename, ['abc', 'xyz'])
False
sage: skipfile(filename, True)
False
"""
base, ext = os.path.splitext(filename)
if ext not in ('.py', '.pyx', '.pxd', '.pxi', '.sage', '.spyx', '.rst', '.tex'):
Expand All @@ -228,6 +247,16 @@ def skipfile(filename):
for line in F:
if nodoctest_regex.match(line):
return True
if tested_optional_tags is not True:
# Adapted from code in SageDocTestParser.parse
m = optionalfiledirective_regex.match(line)
if m:
if tested_optional_tags is False:
return True
optional_tags = parse_optional_tags('#' + m.group(2))
extra = optional_tags - set(tested_optional_tags)
if extra:
return True
line_count += 1
if line_count >= 10:
break
Expand Down Expand Up @@ -781,7 +810,7 @@ def expand():
if dir[0] == "." or skipdir(os.path.join(root,dir)):
dirs.remove(dir)
for file in files:
if not skipfile(os.path.join(root,file)):
if not skipfile(os.path.join(root, file), self.options.optional):
yield os.path.join(root, file)
else:
# the user input this file explicitly, so we don't skip it
Expand Down

0 comments on commit b92e036

Please sign in to comment.