(self)
| 216 | return retval |
| 217 | |
| 218 | def _parsegen(self): |
| 219 | # Create a new message and start by parsing headers. |
| 220 | self._new_message() |
| 221 | headers = [] |
| 222 | # Collect the headers, searching for a line that doesn't match the RFC |
| 223 | # 2822 header or continuation pattern (including an empty line). |
| 224 | for line in self._input: |
| 225 | if line is NeedMoreData: |
| 226 | yield NeedMoreData |
| 227 | continue |
| 228 | if not headerRE.match(line): |
| 229 | # If we saw the RFC defined header/body separator |
| 230 | # (i.e. newline), just throw it away. Otherwise the line is |
| 231 | # part of the body so push it back. |
| 232 | if not NLCRE.match(line): |
| 233 | defect = errors.MissingHeaderBodySeparatorDefect() |
| 234 | self.policy.handle_defect(self._cur, defect) |
| 235 | self._input.unreadline(line) |
| 236 | break |
| 237 | headers.append(line) |
| 238 | # Done with the headers, so parse them and figure out what we're |
| 239 | # supposed to see in the body of the message. |
| 240 | self._parse_headers(headers) |
| 241 | # Headers-only parsing is a backwards compatibility hack, which was |
| 242 | # necessary in the older parser, which could raise errors. All |
| 243 | # remaining lines in the input are thrown into the message body. |
| 244 | if self._headersonly: |
| 245 | lines = [] |
| 246 | while True: |
| 247 | line = self._input.readline() |
| 248 | if line is NeedMoreData: |
| 249 | yield NeedMoreData |
| 250 | continue |
| 251 | if line == '': |
| 252 | break |
| 253 | lines.append(line) |
| 254 | self._cur.set_payload(EMPTYSTRING.join(lines)) |
| 255 | return |
| 256 | if self._cur.get_content_type() == 'message/delivery-status': |
| 257 | # message/delivery-status contains blocks of headers separated by |
| 258 | # a blank line. We'll represent each header block as a separate |
| 259 | # nested message object, but the processing is a bit different |
| 260 | # than standard message/* types because there is no body for the |
| 261 | # nested messages. A blank line separates the subparts. |
| 262 | while True: |
| 263 | self._input.push_eof_matcher(NLCRE.match) |
| 264 | for retval in self._parsegen(): |
| 265 | if retval is NeedMoreData: |
| 266 | yield NeedMoreData |
| 267 | continue |
| 268 | break |
| 269 | self._pop_message() |
| 270 | # We need to pop the EOF matcher in order to tell if we're at |
| 271 | # the end of the current file, not the end of the last block |
| 272 | # of message headers. |
| 273 | self._input.pop_eof_matcher() |
| 274 | # The input stream must be sitting at the newline or at the |
| 275 | # EOF. We want to see if we're at the end of this subpart, so |
no test coverage detected