(text: str)
| 113 | return left_part, right_part |
| 114 | |
| 115 | def unquote_quoted_string(text: str) -> Tuple[str, bool]: |
| 116 | # Remove surrounding quotes and unescape escaped backslashes |
| 117 | # and quotes. Escapes are parsed liberally. I think only |
| 118 | # backslashes and quotes can be escaped but we'll allow anything |
| 119 | # to be. |
| 120 | quoted = False |
| 121 | escaped = False |
| 122 | value = "" |
| 123 | for i, c in enumerate(text): |
| 124 | if quoted: |
| 125 | if escaped: |
| 126 | value += c |
| 127 | escaped = False |
| 128 | elif c == '\\': |
| 129 | escaped = True |
| 130 | elif c == '"': |
| 131 | if i != len(text) - 1: |
| 132 | raise EmailSyntaxError("Extra character(s) found after close quote: " |
| 133 | + ", ".join(safe_character_display(c) for c in text[i + 1:])) |
| 134 | break |
| 135 | else: |
| 136 | value += c |
| 137 | elif i == 0 and c == '"': |
| 138 | quoted = True |
| 139 | else: |
| 140 | value += c |
| 141 | |
| 142 | return value, quoted |
| 143 | |
| 144 | # Split the string at the first unquoted @-sign or left angle bracket. |
| 145 | left_part, right_part = split_string_at_unquoted_special(email, ("@", "<")) |
no test coverage detected