def parse_lines(self, file, boundary, content_length):
    "Generate parts of\n        ``('begin_form', (headers, name))``\n        ``('begin_file', (headers, name, filename))``\n        ``('cont', bytestring)``\n        ``('end', None)``\n\n        Always obeys the grammar\n        parts = ( begin_form cont* end |\n                  begin_file cont* end )*\n        "
    next_part = ('--' + boundary)
    last_part = (next_part + '--')
    iterator = chain(make_line_iter(file, limit=content_length, buffer_size=self.buffer_size), _empty_string_iter)
    terminator = self._find_terminator(iterator)
    if (terminator != next_part):
        self.fail('Expected boundary at start of multipart data')
    while (terminator != last_part):
        headers = parse_multipart_headers(iterator)
        disposition = headers.get('content-disposition')
        if (disposition is None):
            self.fail('Missing Content-Disposition header')
        (disposition, extra) = parse_options_header(disposition)
        transfer_encoding = self.get_part_encoding(headers)
        name = extra.get('name')
        filename = extra.get('filename')
        if (filename is None):
            (yield (_begin_form, (headers, name)))
        else:
            (yield (_begin_file, (headers, name, filename)))
        buf = ''
        for line in iterator:
            if (not line):
                self.fail('unexpected end of stream')
            if (line[:2] == '--'):
                terminator = line.rstrip()
                if (terminator in (next_part, last_part)):
                    break
            if (transfer_encoding is not None):
                try:
                    line = line.decode(transfer_encoding)
                except Exception:
                    self.fail('could not decode transfer encoded chunk')
            if buf:
                (yield (_cont, buf))
                buf = ''
            if (line[(- 2):] == '\r\n'):
                buf = '\r\n'
                cutoff = (- 2)
            else:
                buf = line[(- 1)]
                cutoff = (- 1)
            (yield (_cont, line[:cutoff]))
        else:
            raise ValueError('unexpected end of part')
        if (buf not in ('', '\r', '\n', '\r\n')):
            (yield (_cont, buf))
        (yield (_end, None))
Generate parts of
``('begin_form', (headers, name))``
``('begin_file', (headers, name, filename))``
``('cont', bytestring)``
``('end', None)``

Always obeys the grammar
parts = ( begin_form cont* end |
          begin_file cont* end )*
def parse_lines(self, file, boundary, content_length):
    "Generate parts of\n        ``('begin_form', (headers, name))``\n        ``('begin_file', (headers, name, filename))``\n        ``('cont', bytestring)``\n        ``('end', None)``\n\n        Always obeys the grammar\n        parts = ( begin_form cont* end |\n                  begin_file cont* end )*\n        "
    next_part = ('--' + boundary)
    last_part = (next_part + '--')
    iterator = chain(make_line_iter(file, limit=content_length, buffer_size=self.buffer_size), _empty_string_iter)
    terminator = self._find_terminator(iterator)
    if (terminator != next_part):
        self.fail('Expected boundary at start of multipart data')
    while (terminator != last_part):
        headers = parse_multipart_headers(iterator)
        disposition = headers.get('content-disposition')
        if (disposition is None):
            self.fail('Missing Content-Disposition header')
        (disposition, extra) = parse_options_header(disposition)
        transfer_encoding = self.get_part_encoding(headers)
        name = extra.get('name')
        filename = extra.get('filename')
        if (filename is None):
            (yield (_begin_form, (headers, name)))
        else:
            (yield (_begin_file, (headers, name, filename)))
        buf = 
        for line in iterator:
            if (not line):
                self.fail('unexpected end of stream')
            if (line[:2] == '--'):
                terminator = line.rstrip()
                if (terminator in (next_part, last_part)):
                    break
            if (transfer_encoding is not None):
                try:
                    line = line.decode(transfer_encoding)
                except Exception:
                    self.fail('could not decode transfer encoded chunk')
            if buf:
                (yield (_cont, buf))
                buf = 
            if (line[(- 2):] == '\r\n'):
                buf = '\r\n'
                cutoff = (- 2)
            else:
                buf = line[(- 1)]
                cutoff = (- 1)
            (yield (_cont, line[:cutoff]))
        else:
            raise ValueError('unexpected end of part')
        if (buf not in (, '\r', '\n', '\r\n')):
            (yield (_cont, buf))
        (yield (_end, None))