r""" Parses a string into a kind of AST >>> parse('{{x}}') [('expr', (1, 3), 'x')] >>> parse('foo') ['foo'] >>> parse('{{if x}}test{{endif}}') [('cond', (1, 3), ('if', (1, 3), 'x', ['test']))] >>> parse('series->{{for x in y}}x={{x}}{{endf
(s, name=None, line_offset=0, delimiters=None)
| 702 | |
| 703 | |
| 704 | def parse(s, name=None, line_offset=0, delimiters=None): |
| 705 | r""" |
| 706 | Parses a string into a kind of AST |
| 707 | |
| 708 | >>> parse('{{x}}') |
| 709 | [('expr', (1, 3), 'x')] |
| 710 | >>> parse('foo') |
| 711 | ['foo'] |
| 712 | >>> parse('{{if x}}test{{endif}}') |
| 713 | [('cond', (1, 3), ('if', (1, 3), 'x', ['test']))] |
| 714 | >>> parse('series->{{for x in y}}x={{x}}{{endfor}}') |
| 715 | ['series->', ('for', (1, 11), ('x',), 'y', ['x=', ('expr', (1, 27), 'x')])] |
| 716 | >>> parse('{{for x, y in z:}}{{continue}}{{endfor}}') |
| 717 | [('for', (1, 3), ('x', 'y'), 'z', [('continue', (1, 21))])] |
| 718 | >>> parse('{{py:x=1}}') |
| 719 | [('py', (1, 3), 'x=1')] |
| 720 | >>> parse('{{if x}}a{{elif y}}b{{else}}c{{endif}}') |
| 721 | [('cond', (1, 3), ('if', (1, 3), 'x', ['a']), ('elif', (1, 12), 'y', ['b']), ('else', (1, 23), None, ['c']))] |
| 722 | |
| 723 | Some exceptions:: |
| 724 | |
| 725 | >>> parse('{{continue}}') |
| 726 | Traceback (most recent call last): |
| 727 | ... |
| 728 | TemplateError: continue outside of for loop at line 1 column 3 |
| 729 | >>> parse('{{if x}}foo') |
| 730 | Traceback (most recent call last): |
| 731 | ... |
| 732 | TemplateError: No {{endif}} at line 1 column 3 |
| 733 | >>> parse('{{else}}') |
| 734 | Traceback (most recent call last): |
| 735 | ... |
| 736 | TemplateError: else outside of an if block at line 1 column 3 |
| 737 | >>> parse('{{if x}}{{for x in y}}{{endif}}{{endfor}}') |
| 738 | Traceback (most recent call last): |
| 739 | ... |
| 740 | TemplateError: Unexpected endif at line 1 column 25 |
| 741 | >>> parse('{{if}}{{endif}}') |
| 742 | Traceback (most recent call last): |
| 743 | ... |
| 744 | TemplateError: if with no expression at line 1 column 3 |
| 745 | >>> parse('{{for x y}}{{endfor}}') |
| 746 | Traceback (most recent call last): |
| 747 | ... |
| 748 | TemplateError: Bad for (no "in") in 'x y' at line 1 column 3 |
| 749 | >>> parse('{{py:x=1\ny=2}}') |
| 750 | Traceback (most recent call last): |
| 751 | ... |
| 752 | TemplateError: Multi-line py blocks must start with a newline at line 1 column 3 |
| 753 | """ # noqa: E501 |
| 754 | if delimiters is None: |
| 755 | delimiters = ( |
| 756 | Template.default_namespace["start_braces"], |
| 757 | Template.default_namespace["end_braces"], |
| 758 | ) |
| 759 | tokens = lex(s, name=name, line_offset=line_offset, delimiters=delimiters) |
| 760 | result = [] |
| 761 | while tokens: |
no test coverage detected
searching dependent graphs…