1919
2020
2121import re
22- from io import BytesIO
22+ from io import BufferedRandom , BytesIO
2323from typing import Iterator , Union , Optional , Tuple , List
2424from urllib .parse import parse_qs
2525from wsgiref .headers import Headers
@@ -164,7 +164,7 @@ class _cached_property:
164164 property. """
165165
166166 def __init__ (self , func ):
167- functools .update_wrapper (self , func )
167+ functools .update_wrapper (self , func ) # type: ignore
168168 self .func = func
169169
170170 def __get__ (self , obj , cls ):
@@ -327,7 +327,7 @@ def __init__(
327327 self ._parsed = 0
328328 self ._fieldcount = 0
329329 self ._buffer = bytearray ()
330- self ._current = None
330+ self ._current = MultipartSegment ( self )
331331 self ._state = _PREAMBLE
332332
333333 #: True if the parser reached the end of the multipart stream, stopped
@@ -406,7 +406,6 @@ def parse(
406406 tail = buffer [next_start - 2 : next_start ]
407407
408408 if tail == b"\r \n " : # Normal delimiter found
409- self ._current = MultipartSegment (self )
410409 self ._state = _HEADER
411410 offset = next_start
412411 continue
@@ -495,7 +494,7 @@ def parse(
495494 self ._parsed += offset
496495 buffer [:] = buffer [offset :]
497496
498- except Exception as err :
497+ except MultipartError as err :
499498 if not self .error :
500499 self .error = err
501500 self .close (check_complete = False )
@@ -510,7 +509,6 @@ def close(self, check_complete=True):
510509 """
511510
512511 self .closed = True
513- self ._current = None
514512 del self ._buffer [:]
515513
516514 if check_complete and self ._state is not _COMPLETE :
@@ -558,16 +556,16 @@ def __init__(self, parser: PushMultipartParser):
558556
559557 self .headerlist = []
560558 self .size = 0
561- self .complete = 0
559+ self .complete = False
562560
563- self .name = None
561+ self .name = None # type: ignore
564562 self .filename = None
565563 self .content_type = None
566564 self .charset = None
567565 self ._clen = - 1
568566 self ._size_limit = parser .max_segment_size
569567
570- def _add_headerline (self , line : bytearray ):
568+ def _add_headerline (self , line : Union [ bytes , bytearray ] ):
571569 assert line and self .name is None
572570 parser = self ._parser
573571
@@ -815,7 +813,7 @@ def __init__(
815813 self ._segment = segment
816814 #: A file-like buffer holding the parts binary content, or None if this
817815 #: part was :meth:`closed <close>`.
818- self .file = BytesIO ()
816+ self .file : Union [ BytesIO , BufferedRandom , None ] = BytesIO ()
819817 #: Part size in bytes.
820818 self .size = 0
821819 #: Part name.
@@ -838,7 +836,7 @@ def headers(self) -> Headers:
838836 @_cached_property
839837 def disposition (self ) -> str :
840838 """ The value of the `Content-Disposition` part header. """
841- return self ._segment .header ("Content-Disposition" )
839+ return self ._segment .header ("Content-Disposition" ) # type: ignore
842840
843841 @_cached_property
844842 def content_type (self ) -> str :
@@ -851,19 +849,19 @@ def content_type(self) -> str:
851849
852850 def _write (self , chunk ):
853851 self .size += len (chunk )
854- self .file .write (chunk )
852+ self .file .write (chunk ) # type: ignore
855853 if self .size > self .memfile_limit :
856854 old = self .file
857855 self .file = tempfile .TemporaryFile ()
858- self .file .write (old .getvalue ())
856+ self .file .write (old .getvalue ()) # type: ignore
859857 self ._write = self ._write_nocheck
860858
861859 def _write_nocheck (self , chunk ):
862860 self .size += len (chunk )
863- self .file .write (chunk )
861+ self .file .write (chunk ) # type: ignore
864862
865863 def _mark_complete (self ):
866- self .file .seek (0 )
864+ self .file .seek (0 ) # type: ignore
867865
868866 def is_buffered (self ):
869867 """ Return true if :attr:`file` is memory-buffered, or false if the part
0 commit comments