A class used to parse strings containing doctest examples.
| 580 | ###################################################################### |
| 581 | |
| 582 | class DocTestParser: |
| 583 | """ |
| 584 | A class used to parse strings containing doctest examples. |
| 585 | """ |
| 586 | # This regular expression is used to find doctest examples in a |
| 587 | # string. It defines three groups: `source` is the source code |
| 588 | # (including leading indentation and prompts); `indent` is the |
| 589 | # indentation of the first (PS1) line of the source code; and |
| 590 | # `want` is the expected output (including leading indentation). |
| 591 | _EXAMPLE_RE = re.compile(r''' |
| 592 | # Source consists of a PS1 line followed by zero or more PS2 lines. |
| 593 | (?P<source> |
| 594 | (?:^(?P<indent> [ ]*) >>> .*) # PS1 line |
| 595 | (?:\n [ ]* \.\.\. .*)*) # PS2 lines |
| 596 | \n? |
| 597 | # Want consists of any non-blank lines that do not start with PS1. |
| 598 | (?P<want> (?:(?![ ]*$) # Not a blank line |
| 599 | (?![ ]*>>>) # Not a line starting with PS1 |
| 600 | .+$\n? # But any other line |
| 601 | )*) |
| 602 | ''', re.MULTILINE | re.VERBOSE) |
| 603 | |
| 604 | # A regular expression for handling `want` strings that contain |
| 605 | # expected exceptions. It divides `want` into three pieces: |
| 606 | # - the traceback header line (`hdr`) |
| 607 | # - the traceback stack (`stack`) |
| 608 | # - the exception message (`msg`), as generated by |
| 609 | # traceback.format_exception_only() |
| 610 | # `msg` may have multiple lines. We assume/require that the |
| 611 | # exception message is the first non-indented line starting with a word |
| 612 | # character following the traceback header line. |
| 613 | _EXCEPTION_RE = re.compile(r""" |
| 614 | # Grab the traceback header. Different versions of Python have |
| 615 | # said different things on the first traceback line. |
| 616 | ^(?P<hdr> Traceback\ \( |
| 617 | (?: most\ recent\ call\ last |
| 618 | | innermost\ last |
| 619 | ) \) : |
| 620 | ) |
| 621 | \s* $ # toss trailing whitespace on the header. |
| 622 | (?P<stack> .*?) # don't blink: absorb stuff until... |
| 623 | ^ (?P<msg> \w+ .*) # a line *starts* with alphanum. |
| 624 | """, re.VERBOSE | re.MULTILINE | re.DOTALL) |
| 625 | |
| 626 | # A callable returning a true value iff its argument is a blank line |
| 627 | # or contains a single comment. |
| 628 | _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match |
| 629 | |
| 630 | def parse(self, string, name='<string>'): |
| 631 | """ |
| 632 | Divide the given string into examples and intervening text, |
| 633 | and return them as a list of alternating Examples and strings. |
| 634 | Line numbers for the Examples are 0-based. The optional |
| 635 | argument `name` is a name identifying this string, and is only |
| 636 | used for error messages. |
| 637 | """ |
| 638 | string = string.expandtabs() |
| 639 | # If all lines begin with the same indentation, then strip it. |