Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions src/sage/doctest/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ def parse_optional_tags(string):
['bar', 'foo']
sage: parse_optional_tags("sage: #optional -- foo.bar, baz")
{'foo.bar'}
sage: parse_optional_tags("sage: #needs foo.bar, baz")
{'foo.bar'}
sage: sorted(list(parse_optional_tags(" sage: factor(10^(10^10) + 1) # LoNg TiME, NoT TeSTED; OptioNAL -- P4cka9e")))
['long time', 'not tested', 'p4cka9e']
sage: parse_optional_tags(" sage: raise RuntimeError # known bug")
Expand Down Expand Up @@ -137,17 +139,18 @@ def parse_optional_tags(string):
# strip_string_literals replaces comments
comment = "#" + (literals[comment]).lower()

optional_regex = re.compile(r'(arb216|arb218|py2|long time|not implemented|not tested|known bug)|([^ a-z]\s*optional\s*[:-]*((\s|\w|[.])*))')
optional_regex = re.compile(r'arb216|arb218|py2|long time|not implemented|not tested|known bug'
r'|[^ a-z]\s*(optional|needs)\s*[:-]*((?:\s|\w|[.])*)')

tags = []
for m in optional_regex.finditer(comment):
cmd = m.group(1)
cmd = m.group(0)
if cmd == 'known bug':
tags.append('bug') # so that such tests will be run by sage -t ... -only-optional=bug
elif m.group(1) is not None:
tags.extend(m.group(2).split() or [""])
elif cmd:
tags.append(cmd)
else:
tags.extend(m.group(3).split() or [""])
return set(tags)


Expand Down Expand Up @@ -522,7 +525,7 @@ def parse(self, string, *args):

- A list consisting of strings and :class:`doctest.Example`
instances. There will be at least one string between
successive examples (exactly one unless or long or optional
successive examples (exactly one unless long or optional
tests are removed), and it will begin and end with a string.

EXAMPLES::
Expand Down Expand Up @@ -571,7 +574,7 @@ def parse(self, string, *args):
of the current line should be joined to the next line. This
feature allows for breaking large integers over multiple lines
but is not standard for Python doctesting. It's not
guaranteed to persist, but works in Sage 5.5::
guaranteed to persist::

sage: n = 1234\
....: 5678
Expand All @@ -587,6 +590,23 @@ def parse(self, string, *args):
sage: print(m)
87654321

Optional tags at the start of an example block persist to the end of
the block (delimited by a blank line)::

sage: # needs sage.rings.number_field, long time
sage: QQbar(I)^10000
1
sage: QQbar(I)^10000 # not tested
I

sage: # needs sage.rings.finite_rings
sage: GF(7)
Finite Field of size 7
sage: GF(10)
Traceback (most recent call last):
...
ValueError: the order of a finite field must be a prime power

Test that :trac:`26575` is resolved::

sage: example3 = 'sage: Zp(5,4,print_mode="digits")(5)\n...00010'
Expand Down Expand Up @@ -630,9 +650,14 @@ def parse(self, string, *args):
string = find_sage_continuation.sub(r"\1...", string)
res = doctest.DocTestParser.parse(self, string, *args)
filtered = []
persistent_optional_tags = []
for item in res:
if isinstance(item, doctest.Example):
optional_tags = parse_optional_tags(item.source)
if item.source.startswith("sage: ") and item.source[6:].lstrip().startswith('#'):
persistent_optional_tags = optional_tags
continue
optional_tags = optional_tags.union(persistent_optional_tags)
if optional_tags:
for tag in optional_tags:
self.optionals[tag] += 1
Expand All @@ -654,6 +679,7 @@ def parse(self, string, *args):
elif self.optional_only:
self.optionals['sage'] += 1
continue

if replace_ellipsis:
item.want = item.want.replace(ellipsis_tag, "...")
if item.exc_msg is not None:
Expand All @@ -664,6 +690,9 @@ def parse(self, string, *args):
if item.sage_source.lstrip().startswith('#'):
continue
item.source = preparse(item.sage_source)
else:
if item == '\n':
persistent_optional_tags = []
filtered.append(item)
return filtered

Expand Down
4 changes: 2 additions & 2 deletions src/sage/dynamics/arithmetic_dynamics/projective_ds.py
Original file line number Diff line number Diff line change
Expand Up @@ -5979,7 +5979,7 @@ def reduced_form(self, **kwds):
sage: f = DynamicalSystem_projective([x^3 + x*y^2, y^3])
sage: m = matrix(QQ, 2, 2, [-201221, -1, 1, 0])
sage: f = f.conjugate(m)
sage: f.reduced_form(prec=50, smallest_coeffs=False) #needs 2 periodic
sage: f.reduced_form(prec=50, smallest_coeffs=False) # this needs 2 periodic
Traceback (most recent call last):
...
ValueError: accuracy of Newton's root not within tolerance(0.000066... > 1e-06), increase precision
Expand All @@ -5997,7 +5997,7 @@ def reduced_form(self, **kwds):
::

sage: PS.<x,y> = ProjectiveSpace(ZZ, 1)
sage: f = DynamicalSystem_projective([x^2+ x*y, y^2]) #needs 3 periodic
sage: f = DynamicalSystem_projective([x^2+ x*y, y^2]) # this needs 3 periodic
sage: m = matrix(QQ, 2, 2, [-221, -1, 1, 0])
sage: f = f.conjugate(m)
sage: f.reduced_form(prec=200, smallest_coeffs=False)
Expand Down