mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
Drop the excruciating newline requirements on arguments to
Example.__init__. The constructor now adds trailing newlines when needed, and no longer distinguishes between multi- and single-line cases for source.
This commit is contained in:
parent
dd0e475297
commit
bb43147312
2 changed files with 43 additions and 33 deletions
|
@ -493,24 +493,24 @@ class Example:
|
||||||
A single doctest example, consisting of source code and expected
|
A single doctest example, consisting of source code and expected
|
||||||
output. Example defines the following attributes:
|
output. Example defines the following attributes:
|
||||||
|
|
||||||
- source: A single python statement, ending in a newline iff the
|
- source: A single Python statement, always ending with a newline.
|
||||||
statement spans more than one line.
|
The constructor adds a newline if needed.
|
||||||
|
|
||||||
- want: The expected output from running the source code (either
|
- want: The expected output from running the source code (either
|
||||||
from stdout, or a traceback in case of exception). `want`
|
from stdout, or a traceback in case of exception). `want` ends
|
||||||
should always end with a newline, unless no output is expected,
|
with a newline unless it's empty, in which case it's an empty
|
||||||
|
string. The constructor adds a newline if needed.
|
||||||
|
|
||||||
- lineno: The line number within the DocTest string containing
|
- lineno: The line number within the DocTest string containing
|
||||||
this Example where the Example begins. This line number is
|
this Example where the Example begins. This line number is
|
||||||
zero-based, with respect to the beginning of the DocTest.
|
zero-based, with respect to the beginning of the DocTest.
|
||||||
"""
|
"""
|
||||||
def __init__(self, source, want, lineno):
|
def __init__(self, source, want, lineno):
|
||||||
# Check invariants.
|
# Normalize inputs.
|
||||||
if (source[-1:] == '\n') != ('\n' in source[:-1]):
|
if not source.endswith('\n'):
|
||||||
raise AssertionError("source must end with newline iff "
|
source += '\n'
|
||||||
"source contains more than one line")
|
if want and not want.endswith('\n'):
|
||||||
if want and want[-1] != '\n':
|
want += '\n'
|
||||||
raise AssertionError("non-empty want must end with newline")
|
|
||||||
# Store properties.
|
# Store properties.
|
||||||
self.source = source
|
self.source = source
|
||||||
self.want = want
|
self.want = want
|
||||||
|
@ -625,9 +625,9 @@ class Parser:
|
||||||
... '''
|
... '''
|
||||||
>>> for x in Parser('<string>', text).get_examples():
|
>>> for x in Parser('<string>', text).get_examples():
|
||||||
... print (x.source, x.want, x.lineno)
|
... print (x.source, x.want, x.lineno)
|
||||||
('x, y = 2, 3 # no output expected', '', 1)
|
('x, y = 2, 3 # no output expected\\n', '', 1)
|
||||||
('if 1:\\n print x\\n print y\\n', '2\\n3\\n', 2)
|
('if 1:\\n print x\\n print y\\n', '2\\n3\\n', 2)
|
||||||
('x+y', '5\\n', 9)
|
('x+y\\n', '5\\n', 9)
|
||||||
"""
|
"""
|
||||||
examples = []
|
examples = []
|
||||||
charno, lineno = 0, 0
|
charno, lineno = 0, 0
|
||||||
|
@ -1283,7 +1283,7 @@ class DocTestRunner:
|
||||||
# like "if 1: print 2", then compile() requires a
|
# like "if 1: print 2", then compile() requires a
|
||||||
# trailing newline. Rather than analyze that, always
|
# trailing newline. Rather than analyze that, always
|
||||||
# append one (it never hurts).
|
# append one (it never hurts).
|
||||||
exec compile(example.source + '\n', "<string>", "single",
|
exec compile(example.source, "<string>", "single",
|
||||||
compileflags, 1) in test.globs
|
compileflags, 1) in test.globs
|
||||||
exception = None
|
exception = None
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|
|
@ -127,31 +127,41 @@ an expected output string, and a line number (within the docstring):
|
||||||
|
|
||||||
>>> example = doctest.Example('print 1', '1\n', 0)
|
>>> example = doctest.Example('print 1', '1\n', 0)
|
||||||
>>> (example.source, example.want, example.lineno)
|
>>> (example.source, example.want, example.lineno)
|
||||||
('print 1', '1\n', 0)
|
('print 1\n', '1\n', 0)
|
||||||
|
|
||||||
The `source` string should end in a newline iff the source spans more
|
The `source` string ends in a newline:
|
||||||
than one line:
|
|
||||||
|
|
||||||
>>> # Source spans a single line: no terminating newline.
|
Source spans a single line: no terminating newline.
|
||||||
>>> e = doctest.Example('print 1', '1\n', 0)
|
>>> e = doctest.Example('print 1', '1\n', 0)
|
||||||
|
>>> e.source, e.want
|
||||||
|
('print 1\n', '1\n')
|
||||||
|
|
||||||
>>> e = doctest.Example('print 1\n', '1\n', 0)
|
>>> e = doctest.Example('print 1\n', '1\n', 0)
|
||||||
Traceback (most recent call last):
|
>>> e.source, e.want
|
||||||
AssertionError: source must end with newline iff source contains more than one line
|
('print 1\n', '1\n')
|
||||||
|
|
||||||
>>> # Source spans multiple lines: require terminating newline.
|
Source spans multiple lines: require terminating newline.
|
||||||
>>> e = doctest.Example('print 1;\nprint 2\n', '1\n2\n', 0)
|
>>> e = doctest.Example('print 1;\nprint 2\n', '1\n2\n', 0)
|
||||||
>>> e = doctest.Example('print 1;\nprint 2', '1\n2\n', 0)
|
>>> e.source, e.want
|
||||||
Traceback (most recent call last):
|
('print 1;\nprint 2\n', '1\n2\n')
|
||||||
AssertionError: source must end with newline iff source contains more than one line
|
|
||||||
|
|
||||||
The `want` string should be terminated by a newline, unless it's the
|
>>> e = doctest.Example('print 1;\nprint 2', '1\n2\n', 0)
|
||||||
empty string:
|
>>> e.source, e.want
|
||||||
|
('print 1;\nprint 2\n', '1\n2\n')
|
||||||
|
|
||||||
|
The `want` string ends with a newline, unless it's the empty string:
|
||||||
|
|
||||||
>>> e = doctest.Example('print 1', '1\n', 0)
|
>>> e = doctest.Example('print 1', '1\n', 0)
|
||||||
|
>>> e.source, e.want
|
||||||
|
('print 1\n', '1\n')
|
||||||
|
|
||||||
>>> e = doctest.Example('print 1', '1', 0)
|
>>> e = doctest.Example('print 1', '1', 0)
|
||||||
Traceback (most recent call last):
|
>>> e.source, e.want
|
||||||
AssertionError: non-empty want must end with newline
|
('print 1\n', '1\n')
|
||||||
|
|
||||||
>>> e = doctest.Example('print', '', 0)
|
>>> e = doctest.Example('print', '', 0)
|
||||||
|
>>> e.source, e.want
|
||||||
|
('print\n', '')
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_DocTest(): r"""
|
def test_DocTest(): r"""
|
||||||
|
@ -180,9 +190,9 @@ constructor:
|
||||||
2
|
2
|
||||||
>>> e1, e2 = test.examples
|
>>> e1, e2 = test.examples
|
||||||
>>> (e1.source, e1.want, e1.lineno)
|
>>> (e1.source, e1.want, e1.lineno)
|
||||||
('print 12', '12\n', 1)
|
('print 12\n', '12\n', 1)
|
||||||
>>> (e2.source, e2.want, e2.lineno)
|
>>> (e2.source, e2.want, e2.lineno)
|
||||||
("print 'another\\example'", 'another\nexample\n', 6)
|
("print 'another\\example'\n", 'another\nexample\n', 6)
|
||||||
|
|
||||||
Source information (name, filename, and line number) is available as
|
Source information (name, filename, and line number) is available as
|
||||||
attributes on the doctest object:
|
attributes on the doctest object:
|
||||||
|
@ -264,8 +274,8 @@ will return a single test (for that function's docstring):
|
||||||
>>> print tests
|
>>> print tests
|
||||||
[<DocTest sample_func from ...:12 (1 example)>]
|
[<DocTest sample_func from ...:12 (1 example)>]
|
||||||
>>> e = tests[0].examples[0]
|
>>> e = tests[0].examples[0]
|
||||||
>>> print (e.source, e.want, e.lineno)
|
>>> (e.source, e.want, e.lineno)
|
||||||
('print sample_func(22)', '44\n', 3)
|
('print sample_func(22)\n', '44\n', 3)
|
||||||
|
|
||||||
>>> doctest: -ELLIPSIS # Turn ellipsis back off
|
>>> doctest: -ELLIPSIS # Turn ellipsis back off
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue