r"""Assemble a single line from multiple continued line pieces Continued lines are lines ending in ``\``, and the line following the last ``\`` in the block. For example, this code continues over multiple lines:: if (assign_ix is not None) \ and (len(line) >= assi
(lines, start: Tuple[int, int], end_line: int)
| 132 | return end_line |
| 133 | |
| 134 | def assemble_continued_line(lines, start: Tuple[int, int], end_line: int): |
| 135 | r"""Assemble a single line from multiple continued line pieces |
| 136 | |
| 137 | Continued lines are lines ending in ``\``, and the line following the last |
| 138 | ``\`` in the block. |
| 139 | |
| 140 | For example, this code continues over multiple lines:: |
| 141 | |
| 142 | if (assign_ix is not None) \ |
| 143 | and (len(line) >= assign_ix + 2) \ |
| 144 | and (line[assign_ix+1].string == '%') \ |
| 145 | and (line[assign_ix+2].type == tokenize.NAME): |
| 146 | |
| 147 | This statement contains four continued line pieces. |
| 148 | Assembling these pieces into a single line would give:: |
| 149 | |
| 150 | if (assign_ix is not None) and (len(line) >= assign_ix + 2) and (line[... |
| 151 | |
| 152 | This uses 0-indexed line numbers. *start* is (lineno, colno). |
| 153 | |
| 154 | Used to allow ``%magic`` and ``!system`` commands to be continued over |
| 155 | multiple lines. |
| 156 | """ |
| 157 | parts = [lines[start[0]][start[1]:]] + lines[start[0]+1:end_line+1] |
| 158 | return ' '.join([p.rstrip()[:-1] for p in parts[:-1]] # Strip backslash+newline |
| 159 | + [parts[-1].rstrip()]) # Strip newline from last line |
| 160 | |
| 161 | class TokenTransformBase: |
| 162 | """Base class for transformations which examine tokens. |