o
    mi5                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
mZ d dlmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZmZ d dlm Z m!Z! dd	l"m#Z# dd
l$m%Z%m&Z&m'Z' ddl(m)Z)m*Z*m+Z+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@ ddlAmBZB ejCdkrd dlmDZD nd dlmEZE eEdddZDdZFerddlGmHZH G dd deIZJG dd deIZKdeeL deeeL eeLeLf f fd d!ZM	"d3d#e
eLeLf d$eLdeeL fd%d&ZNG d'd( d(ZOG d)d dZPe@ePe<jQd*G d+d, d,e=ZRG d-d. d.ZSee=eLeLf ZTG d/d0 d0e=ZUG d1d2 d2ZVdS )4    N)deque)MappingSequence)TracebackType)TYPE_CHECKINGAnyAsyncIteratorDequeDictIteratorListOptionalTupleTypeUnioncast)	parse_qslunquote	urlencode)CIMultiDictCIMultiDictProxy   )AbstractStreamWriter)DEFAULT_MAX_DECOMPRESS_SIZEZLibCompressorZLibDecompressor)CONTENT_DISPOSITIONCONTENT_ENCODINGCONTENT_LENGTHCONTENT_TRANSFER_ENCODINGCONTENT_TYPE)CHARTOKENparse_mimetypereify)HeadersParser)BadHttpMessage)internal_logger)JsonPayloadLookupErrorOrderPayloadStringPayloadget_payloadpayload_type)StreamReader)      )Self)TypeVarr2   BodyPartReader)bound)MultipartReaderMultipartWriterr4   BadContentDispositionHeaderBadContentDispositionParamparse_content_dispositioncontent_disposition_filename)ClientResponsec                   @      e Zd ZdS )r8   N__name__
__module____qualname__ rB   rB   O/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/aiohttp/multipart.pyr8   O       r8   c                   @   r=   )r9   Nr>   rB   rB   rB   rC   r9   S   rD   r9   headerreturnc                    s  dt dtfdd dt dtfdd}dt dtf fdd}dt dtfd	d
}dt dtfdd}dttjtddt dt dt fdd}| sJd i fS | d^}} |s`t	t
|  d i fS i }|r[|d}	|	stt	t
|  qbd|	vrt	t
|  d i fS |	dd\}
}|
  }
| }|
|v rt	t
|  d i fS  |
st	t|	 qb||
r||r||dd }n |st	t|	 qbn||
r||r|dd\}}}|pd}nt	t|	 qbzt||d}W n_ ty   t	t|	 Y qbw d}||rd}||dd d}n+ |r$d}n#|rG| d|d  }||rG|d ||dd d}d}|rUt	t
|  d i fS |||
< |se| |fS )NstringrF   c                 S   s   t | o	tt| kS N)boolr"   setrG   rB   rB   rC   is_tokenZ   s   z+parse_content_disposition.<locals>.is_tokenc                 S   s    | d | d   kodkS   S )Nr   "rB   rK   rB   rB   rC   	is_quoted]   s    z,parse_content_disposition.<locals>.is_quotedc                    s    | o
|  ddkS )N'   )countrK   rL   rB   rC   
is_rfc5987`      z-parse_content_disposition.<locals>.is_rfc5987c                 S   s
   |  dS )N*)endswithrK   rB   rB   rC   is_extended_paramc      
z4parse_content_disposition.<locals>.is_extended_paramc                 S   s@   |  dd }|sdS | dr| |d n| |d  }| S )NrV   r   FrM   )findrW   isdigit)rG   pos	substringrB   rB   rC   is_continuous_paramf   s
   "z6parse_content_disposition.<locals>.is_continuous_param )charstextr`   c                S   s   t d| dd| S )Nz\\([z])z\1)resub)ra   r`   rB   rB   rC   unescapem   rU   z+parse_content_disposition.<locals>.unescape;r   =r   rM   rP   rQ   utf-8strictTFz\/)strrI   joinmaprb   escaper!   splitwarningswarnr8   poplowerstriplstripr9   r   UnicodeDecodeError)rE   rO   rT   rX   r^   rd   disptypepartsparamsitemkeyvalueencoding_failed_valuerB   rS   rC   r:   W   s   *






Br:   filenamerw   namec           
         s   d|  | sd S  | v r|   S || v r| | S g }t  fdd|  D }t|D ]%\}\}}|dd\}}|drD|d d }|t|krP|| q+ |sUd S d|}d|v rq|dd	\}	}}|	pjd
}	t||	dS |S )Nz%s*c                 3   s&    | ]\}}|  r||fV  qd S rH   )
startswith).0ry   rz   name_sufrB   rC   	<genexpr>   s    
z/content_disposition_filename.<locals>.<genexpr>rV   r   rM   r_   rP   rQ   rg   rh   )	sorteditems	enumeraterm   rW   ri   appendrj   r   )
rw   r   rv   fnparamsnumry   rz   r|   tailr{   rB   r   rC   r;      s4   

r;   c                   @   sp   e Zd ZdZ						ddd	Zdd
dZded fddZdefddZ	de
ed  fddZdddZdS )MultipartResponseWrapperzzWrapper around the MultipartReader.

    It takes care about
    underlying connection and close it when it needs in.
    respr<   streamr6   rF   Nc                 C   s   || _ || _d S rH   )r   r   )selfr   r   rB   rB   rC   __init__   s   
z!MultipartResponseWrapper.__init__c                 C      | S rH   rB   r   rB   rB   rC   	__aiter__      z"MultipartResponseWrapper.__aiter__)r6   r4   c                        |   I d H }|d u rt|S rH   nextStopAsyncIterationr   partrB   rB   rC   	__anext__   
   z"MultipartResponseWrapper.__anext__c                 C   s   | j j S )z2Returns True when all response data had been read.)r   contentat_eofr   rB   rB   rC   r         zMultipartResponseWrapper.at_eofc                    s.   | j  I dH }| j  r|  I dH  |S )z#Emits next multipart reader object.N)r   r   r   releaser   rx   rB   rB   rC   r      s
   
zMultipartResponseWrapper.nextc                    s   | j  I dH  dS )z_Release the connection gracefully.

        All remaining content is read to the void.
        N)r   r   r   rB   rB   rC   r     s   z MultipartResponseWrapper.release)r   r<   r   r6   rF   N)rF   r   rF   N)r?   r@   rA   __doc__r   r   r   r   rI   r   r   r   r   rB   rB   rB   rC   r      s$    




	r   c                   @   s  e Zd ZdZdZddeddeddd	ed
ede	e de
ddfddZdedefddZdefddZde	e fddZdddedefddZefde
defddZde
defdd Zde
defd!d"Zdefd#d$ZdGd%d&Zdd'd(e	e defd)d*Zdd'd(e	e de	eeef  fd+d,Zdd'd(e	e deeeef  fd-d.Zdefd/d0Zd1edefd2d3Zdefd4d5Z d1edefd6d7Z!d1ede"e fd8d9Z#d1edefd:d;Z$d1ede"e fd<d=Z%d1edefd>d?Z&d@edefdAdBZ'e(de	e fdCdDZ)e(de	e fdEdFZ*dS )Hr4   z&Multipart reader for single body part.i    mixedN)subtypedefault_charsetmax_decompress_sizeboundaryheadersCIMultiDictProxy[str]r   r   r   r   rF   c                C   s   || _ || _t|d | _|| _|| _d| _|dk| _| jr d n| j t	d }|d ur/t
|nd | _d| _t | _d | _d| _i | _|| _d S )NrQ   F	form-datar   )r   	_boundarylen_boundary_len_content_default_charset_at_eof_is_form_datagetr   int_length_read_bytesr   _unread_prev_chunk_content_eof_cache_max_decompress_size)r   r   r   r   r   r   r   lengthrB   rB   rC   r     s   


zBodyPartReader.__init__r   c                 C   r   rH   rB   r   rB   rB   rC   r   .  r   zBodyPartReader.__aiter__c                    r   rH   r   r   rB   rB   rC   r   1  s
   zBodyPartReader.__anext__c                    s   |   I d H }|sd S |S rH   )readr   rB   rB   rC   r   7  s
   zBodyPartReader.nextFdecoder   c                   sl   | j rdS t }| j s|| | jI dH  | j r|r4t }| |2 z3 dH W }|| q%6 |S |S )zReads body part data.

        decode: Decodes data following by encoding
                method from Content-Encoding header. If it missed
                data remains untouched
            N)r   	bytearrayextend
read_chunk
chunk_sizedecode_iter)r   r   datadecoded_datadrB   rB   rC   r   =  s   zBodyPartReader.readsizec                    sb  | j rdS | jr| |I dH }n| |I dH }| jt}|r| dkrd|	 }t
|d }|dkr|  sd| }d}| jrW| jd| }| jt
|d | _t
||krl|| jdt
| I dH 7 }|sqd| _ |d|	 7 }||7 }t
|d }|dkr|  r=|  jt
|7  _| j| jkrd| _ | j r| j I dH dkrtd|S )	zWReads body part content chunk of the specified size.

        size: chunk size
        r   Nbase64   r   T   
z3Reader did not read all the data or it is malformed)r   r   _read_chunk_from_length_read_chunk_from_streamr   r   r   rq   rj   rm   r   r   r   r   r   r   readline
ValueError)r   r   chunkr{   stripped_chunk	remainderover_chunk_size
over_chunkrB   rB   rC   r   P  s<   zBodyPartReader.read_chunkc                    sL   | j d us
J dt|| j | j }| j|I d H }| j r$d| _|S )Nz(Content-Length required for chunked readT)r   minr   r   r   r   r   )r   r   r   r   rB   rB   rC   r   |  s   
z&BodyPartReader._read_chunk_from_lengthc                    s  || j ks
J d| jd u }|rd| j|I d H  | _d}t|| j k rQ|| j|I d H 7 }|  jt| j 7  _| jdkrFtd| jrJnt|| j k s&t||krg| j	||d   |d | }| jd usnJ | j| }d| j
 }|r||}n||tdt| jt| }|dkrt  tjdtd | j	||d   W d    n1 sw   Y  | jd | | _|t| j| }|sd	| _| j|rdndd  }|| _|S )
Nz<Chunk size must be greater or equal than boundary length + 2r   r   rQ   zReading after EOFr   ignore)categoryT)r   r   r   r   r   r   r   r   r   unread_datar   rZ   maxrn   catch_warningsfilterwarningsDeprecationWarningr   )r   r   first_chunkr   windowrc   idxresultrB   rB   rC   r     sJ   



 
z&BodyPartReader._read_chunk_from_streamc                    s   | j rdS | jr| j }n| j I dH }|| jr?|d}| j}| jd }||ks2||kr=d| _ | j| dS |S | j I dH }|| jrS|dd }| j| |S )z Reads body part by line by line.r   Nr      --T)	r   r   popleftr   r   r   r   rstripr   )r   linesliner   last_boundary	next_linerB   rB   rC   r     s(   

zBodyPartReader.readlinec                    s2   | j rdS | j s| | jI dH  | j r	dS dS )z0Like read(), but reads all the data to the void.N)r   r   r   r   rB   rB   rC   r     s   zBodyPartReader.release)r{   r{   c                   s.   | j ddI dH }|p| jdd}||S )z;Like read(), but assumes that body part contains text data.Tr   Nrg   default)r   get_charsetr   r   r{   r   rB   rB   rC   ra     s   
zBodyPartReader.textc                   sJ   | j ddI dH }|sdS |p| jdd}ttttf t||S )z<Like read(), but assumes that body parts contains JSON data.Tr   Nrg   r   )	r   r   r   r
   ri   r   jsonloadsr   r   rB   rB   rC   r     s   zBodyPartReader.jsonc                   sr   | j ddI dH }|sg S |dur|}n| jdd}z	| |}W n ty1   td| w t|d|dS )zFLike read(), but assumes that body parts contain form urlencoded data.Tr   Nrg   r   z'data cannot be decoded with %s encoding)keep_blank_valuesr{   )r   r   r   r   rt   r   r   )r   r{   r   real_encodingr   rB   rB   rC   form  s"   zBodyPartReader.formc                 C      | j S )z<Returns True if the boundary was reached or False otherwise.r   r   rB   rB   rC   r        zBodyPartReader.at_eofr   c                 C   s   t | jv r
| |S |S )z>Apply Content-Transfer-Encoding decoding if header is present.)r   r   _decode_content_transferr   r   rB   rB   rC    _apply_content_transfer_decoding  s   

z/BodyPartReader._apply_content_transfer_decodingc                 C   s   | j  ot| jv S )z5Check if Content-Encoding decoding should be applied.)r   r   r   r   rB   rB   rC   _needs_content_decoding  s   z&BodyPartReader._needs_content_decodingc                 C   s    |  |}|  r| |S |S )a  Decodes data synchronously.

        Decodes data according the specified Content-Encoding
        or Content-Transfer-Encoding headers value.

        Note: For large payloads, consider using decode_iter() instead
        to avoid blocking the event loop during decompression.
        )r   r   _decode_contentr   rB   rB   rC   r   
  s   
	
zBodyPartReader.decodec                 C  sB   |  |}|  r| |2 z	3 dH W }|V  q6 dS |V  dS )a$  Async generator that yields decoded data chunks.

        Decodes data according the specified Content-Encoding
        or Content-Transfer-Encoding headers value.

        This method offloads decompression to an executor for large payloads
        to avoid blocking the event loop.
        N)r   r   _decode_content_async)r   r   r   rB   rB   rC   r     s   
	
zBodyPartReader.decode_iterc                 C   sL   | j td }|dkr|S |dv rt|ddj|| jdS td| Nr_   identity>   gzipdeflateT)r{   suppress_deflate_header)
max_lengthunknown content encoding: )r   r   r   rq   r   decompress_syncr   RuntimeErrorr   r   r{   rB   rB   rC   r   (  s   zBodyPartReader._decode_contentc                 C  sd   | j td }|dkr|V  d S |dv r+t|dd}|j|| jdI d H V  d S td| r   )r   r   r   rq   r   
decompressr   r  )r   r   r{   r   rB   rB   rC   r   4  s   
z$BodyPartReader._decode_content_asyncc                 C   sP   | j td }|dkrt|S |dkrt|S |dv r!|S td| )Nr_   r   quoted-printable)binary8bit7bit#unknown content transfer encoding: )	r   r   r   rq   r   	b64decodebinasciia2b_qpr  r  rB   rB   rC   r   A  s   

z'BodyPartReader._decode_content_transferr   c                 C   s*   | j td}t|}|jd| jp|S )z>Returns charset parameter from Content-Type header or default.r_   charset)r   r   r    r#   
parametersr   )r   r   ctypemimetyperB   rB   rC   r   M  s   zBodyPartReader.get_charsetc                 C      t | jt\}}t|dS )z|Returns name specified in Content-Disposition header.

        If the header is missing or malformed, returns None.
        r   r:   r   r   r   r;   r   r|   rw   rB   rB   rC   r   S     
zBodyPartReader.namec                 C   r  )zReturns filename specified in Content-Disposition header.

        Returns None if the header is missing or malformed.
        r   r  r  rB   rB   rC   r   \  r  zBodyPartReader.filenamer   )+r?   r@   rA   r   r   r   bytesr/   ri   r   r   r   r2   r   r   r   rI   r   r   r   r   r   r   ra   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r$   r   r   rB   rB   rB   rC   r4     s\    	
,
-
(()orderc                       sz   e Zd ZU eed< dedededdf fddZddededefddZddedede	fddZ
deddfddZ  ZS )BodyPartReaderPayloadr~   rz   argskwargsrF   Nc                    sb   t  j|g|R i | i }|jd ur|j|d< |jd ur#|j|d< |r/| jdi | d S d S )Nr   r   
attachmentT)r  T)superr   r   r   set_content_disposition)r   rz   r  r  rw   	__class__rB   rC   r   k  s   



zBodyPartReaderPayload.__init__rg   rh   r{   errorsc                 C   s   t d)NzUnable to decode.	TypeErrorr   r{   r"  rB   rB   rC   r   w  s   zBodyPartReaderPayload.decodec                    s
   t d)aR  Raises TypeError as body parts should be consumed via write().

        This is intentional: BodyPartReader payloads are designed for streaming
        large data (potentially gigabytes) and must be consumed only once via
        the write() method to avoid memory exhaustion. They cannot be buffered
        in memory for reuse.
        z:Unable to read body part as bytes. Use write() to consume.r#  r%  rB   rB   rC   as_bytesz  s   zBodyPartReaderPayload.as_byteswriterc                    sf   | j }|jddI d H  }r1||2 z3 d H W }||I d H  q6 |jddI d H  }sd S d S )Ni   )r   )r~   r   r   write)r   r'  fieldr   r   rB   rB   rC   r(    s   zBodyPartReaderPayload.writerg   rh   )r?   r@   rA   r4   __annotations__r   r   ri   r   r  r&  r   r(  __classcell__rB   rB   r   rC   r  f  s   
 
r  c                   @   sD  e Zd ZU dZeZdZeed   e	d< e
Zddddeeef ded	ed
eddf
ddZdedefddZdeed e
f  fddZedddefddZdefddZdeed e
f  fddZd.ddZded e
f fddZddded e
f fd d!Zdefd"d#Zdefd$d%Zd.d&d'Z d.d(d)Z!d/d*d+Z"d.d,d-Z#dS )0r6   zMultipart body reader.Nmultipart_reader_clsi     max_field_sizemax_headersr   r   r0  r1  rF   c                C   s   t |t | _| jjdksJ dd| jjvrtd|t  || _d|    | _	|| _
d | _d | _|| _|| _d| _d| _g | _d S )N	multipartz!multipart/* content type expectedr   z$boundary missed for Content-Type: %s--FT)r#   r    	_mimetypetyper  r   r   _get_boundaryencoder   r   r   
_last_part_max_field_size_max_headersr   _at_bofr   )r   r   r   r0  r1  rB   rB   rC   r     s    

zMultipartReader.__init__r   c                 C   r   rH   rB   r   rB   rB   rC   r     r   zMultipartReader.__aiter__c                    r   rH   r   r   rB   rB   rC   r     r   zMultipartReader.__anext__responser<   c                 C   s   |  || |j|j}|S )zConstructs reader instance from HTTP response.

        :param response: :class:`~aiohttp.client.ClientResponse` instance
        )response_wrapper_clsr   r   )clsr<  objrB   rB   rC   from_response  s   	zMultipartReader.from_responsec                 C   r   )z@Returns True if the final boundary was reached, false otherwise.r   r   rB   rB   rC   r     r   zMultipartReader.at_eofc                    s   | j rdS |  I dH  | jr|  I dH  d| _n|  I dH  | j r'dS |  I dH }| jdu ro| jjdkrot	|t
rot|jt\}}|ddkro|dI dH }t|dkratd|  | _|  I dH }|| _| jS )	z#Emits the next multipart body part.NFr   r   	_charset_       zInvalid default charset)r   _maybe_release_last_partr;  _read_until_first_boundary_read_boundaryfetch_next_partr8  r4  r   
isinstancer4   r:   r   r   r   r   r   r  rr   r   r   )r   r   r|   rw   r  rB   rB   rC   r     s0   
zMultipartReader.nextc                    s>   | j s|  I dH }|du rdS | I dH  | j rdS dS )z=Reads all the body parts to the void till the final boundary.N)r   r   r   r   rB   rB   rC   r     s   zMultipartReader.releasec                    s   |   I dH }| |S )z"Returns the next body part reader.N)_read_headers_get_part_reader)r   r   rB   rB   rC   rG    s   
zMultipartReader.fetch_next_partr   c                 C   sn   | td}t|}|jdkr(| jdu rt| || jS | j|| j| j| jdS | j| j	|| j| j
j| jdS )zDispatches the response by the `Content-Type` header.

        Returns a suitable reader instance.

        :param dict headers: Response headers
        r_   r2  Nr/  )r   r   )r   r    r#   r5  r-  r   r9  r:  part_reader_clsr   r4  r   r   )r   r   r  r  rB   rB   rC   rJ    s$   


z MultipartReader._get_part_readerc                 C   s(   | j jd }t|dkrtd| |S )Nr   F   z&boundary %r is too long (70 chars max))r4  r  r   r   )r   r   rB   rB   rC   r6    s   zMultipartReader._get_boundaryc                    s"   | j r	| j  S | j I d H S rH   )r   rp   r   r   r   rB   rB   rC   	_readline%  s   
zMultipartReader._readlinec                    sX   	 |   I d H }|dkrtd| j | }|| jkrd S || jd kr+d| _d S q)NTr   z#Could not find starting boundary %rr   )rM  r   r   r   r   r   r   rB   rB   rC   rE  *  s   
z*MultipartReader._read_until_first_boundaryc                    s   |   I d H  }|| jkrd S || jd krCd| _|   I d H }|   I d H }|d d dkr9| j| d S | j||g d S td|d| j)Nr   TrQ   zInvalid boundary z, expected )rM  r   r   r   r   r   r   r   )r   r   epiloguer   rB   rB   rC   rF  8  s   
zMultipartReader._read_boundaryc                    sn   g }	 | j j| jdI d H }|d}|| |snt|| jkr'tdqt| jd}|	|\}}|S )NT)max_line_lengthr   zToo many headers received)r0  )
r   r   r9  r   r   r   r:  r&   r%   parse_headers)r   linesr   parserr   raw_headersrB   rB   rC   rI  O  s   

zMultipartReader._read_headersc                    sD   | j dur | j  s| j  I dH  | j| j j d| _ dS dS )z8Ensures that the last read body part is read completely.N)r8  r   r   r   r   r   rB   rB   rC   rD  ]  s   


z(MultipartReader._maybe_release_last_partr   )rF   r   )$r?   r@   rA   r   r   r=  r-  r   r   r+  r4   rK  r   ri   r/   r   r   r2   r   r   r   classmethodr@  rI   r   r   r   rG  rJ  r6  r  rM  rE  rF  rI  rD  rB   rB   rB   rC   r6     s^   
 




#






r6   c                       s  e Zd ZU dZded< dZd9dedee ddf fd	d
Zd:ddZ	dee
e  dee dee ddfddZdee fddZdefddZdefddZedZedZedefddZedefddZd;dedeeeef  defd d!Zd"edefd#d$Z 	d;dedeeeef  defd%d&Z!	d;de"e#e$eef  eeef f deeeef  defd'd(Z%edee fd)d*Z&d<d-ed.edefd/d0Z'd<d-ed.ede(fd1d2Z)	d=d3e*d4eddfd5d6Z+d>d7d8Z,  Z-S )?r7   zMultipart body writer.Nr~   Tr   r   r   rF   c                    sv   |d ur|nt  j}z|d| _W n ty   tdd w d| d| j }t j	d |d g | _
|dk| _d S )Nasciiz(boundary should contain ASCII only charsz
multipart/z; boundary=)content_typer   )uuiduuid4hexr7  r   UnicodeEncodeErrorr   _boundary_valuer  r   _partsr   )r   r   r   r  r   rB   rC   r   p  s   
zMultipartWriter.__init__c                 C   r   rH   rB   r   rB   rB   rC   	__enter__  r   zMultipartWriter.__enter__exc_typeexc_valexc_tbc                 C   s   d S rH   rB   )r   r_  r`  ra  rB   rB   rC   __exit__  s   zMultipartWriter.__exit__c                 C   
   t | jS rH   )iterr]  r   rB   rB   rC   __iter__  rY   zMultipartWriter.__iter__c                 C   rc  rH   )r   r]  r   rB   rB   rC   __len__  rY   zMultipartWriter.__len__c                 C   s   dS )NTrB   r   rB   rB   rC   __bool__  r   zMultipartWriter.__bool__s   \A[!#$%&'*+\-.^_`|~\w]+\Zs   [\x00-\x08\x0A-\x1F\x7F]c                 C   s^   | j }t| j|r|dS t| j|rtd|dd}|dd}d|d d S )zzWrap boundary parameter value in quotes, if necessary.

        Reads self.boundary and returns a unicode string.
        rV  z*boundary value contains invalid characters   \s   \\   "s   \"rN   )	r   rb   match_valid_tchar_regexr   search_invalid_qdtext_char_regexr   replace)r   rz   quoted_value_contentrB   rB   rC   r\    s   
zMultipartWriter._boundary_valuec                 C   s   | j dS )NrV  )r   r   r   rB   rB   rC   r     r   zMultipartWriter.boundaryr?  r   c                 C   sd   |d u rt  }t|tr|j| | |S zt||d}W n ty,   td| w | |S )Nr   zCannot create payload from %r)	r   rH  r+   r   updateappend_payloadr-   r)   r$  )r   r?  r   payloadrB   rB   rC   r     s   


zMultipartWriter.appendrs  c                 C   s   d}d}| j r(ttth|j @ rJ t|jvr'dt| j }|j	d|d nH|j
td }|r>|dvr>td| |dkrDd}|j
td }|d	vrXtd
| |dkr^d}|j}|durp|sp|spt||jt< | j|||f |S )z)Adds a new body part to multipart writer.Nzsection-r   )r   r_   )r   r   r   r  r   )r_   r   r  r	  r  r	  )r   r   r   r   r   keysr   r   r]  r  r   rq   r  r   ri   r   )r   rs  r{   te_encodingr   r   rB   rB   rC   rr    s4   
zMultipartWriter.append_payloadc                 C   s    |du rt  }| t||dS )zHelper to append JSON part.Nrp  )r   rr  r(   )r   r?  r   rB   rB   rC   append_json  s   zMultipartWriter.append_jsonc                 C   sV   t |ttfs	J |du rt }t |trt| }t|dd}| t||ddS )z&Helper to append form urlencoded part.NT)doseqz!application/x-www-form-urlencoded)r   rW  )	rH  r   r   r   listr   r   rr  r,   )r   r?  r   r   rB   rB   rC   append_form  s   
zMultipartWriter.append_formc                 C   sx   d}| j D ])\}}}|j}|s|s|du r dS |tdt| j d | t|j d 7 }q|dt| j d 7 }|S )zSize of the payload.r   NrQ   r   )r]  r   r   r   r   _binary_headers)r   totalr   r{   ru  	part_sizerB   rB   rC   r     s(   	zMultipartWriter.sizerg   rh   r{   r"  c                    s   d  fddjD S )zReturn string representation of the multipart data.

        WARNING: This method may do blocking I/O if parts contain file payloads.
        It should not be called in the event loop. Use as_bytes().decode() instead.
        r_   c                 3   s:    | ]\}}}d j  d |j  |  V  qdS )r3  z
N)r   rz  r   )r   r   _e_ter{   r"  r   rB   rC   r   +  s    
z)MultipartWriter.decode.<locals>.<genexpr>)rj   r]  r%  rB   r  rC   r   %  s   zMultipartWriter.decodec                    s|   g }| j D ](\}}}|d| j d  ||j |||I dH }|| |d q|d| j d  d|S )zReturn bytes representation of the multipart data.

        This method is async-safe and calls as_bytes on underlying payloads.
        r   r   N   --
r   )r]  r   r   rz  r&  rj   )r   r{   r"  rv   r   r}  r~  
part_bytesrB   rB   rC   r&  4  s   

zMultipartWriter.as_bytesr'  close_boundaryc                    s   | j D ]d\}}}| jrt|jv sJ d|jt v sJ |d| j d I dH  ||jI dH  |s6|rXt|}|rA|| |rH|	| ||I dH  |
 I dH  n||I dH  |dI dH  q|rz|d| j d I dH  dS dS )zWrite body.zname=r   r   Nr  )r]  r   r   r   r(  r   rz  MultipartPayloadWriterenable_compressionenable_encoding	write_eof)r   r'  r  r   r{   ru  wrB   rB   rC   r(  O  s(   

zMultipartWriter.writec                    s   | j rdS d| _ t| jD ]2\}\}}}|js@|js@z	| I dH  W q ty? } ztjd||dd W Y d}~qd}~ww qdS )a  
        Close all part payloads that need explicit closing.

        IMPORTANT: This method must not await anything that might not finish
        immediately, as it may be called during cleanup/cancellation. Schedule
        any long-running operations without awaiting them.
        NTz%Failed to close multipart part %d: %s)exc_info)		_consumedr   r]  	autocloseconsumedclose	Exceptionr'   error)r   r   r   r|   excrB   rB   rC   r  l  s    zMultipartWriter.close)r   N)rF   r7   rH   r*  )Tr   ).r?   r@   rA   r   r+  
_autocloseri   r   r   r^  r   BaseExceptionr   rb  r   _Partre  r   rf  rI   rg  rb   compilerk  rm  propertyr\  r   r   r   r+   r   rr  rv  r   r   r   ry  r   r   r  r&  r   r(  r  r,  rB   rB   r   rC   r7   i  sn   
  




$'


r7   c                   @   sj   e Zd ZdeddfddZdeddfddZ	dded
ee ddfddZ	dddZ
deddfddZdS )r  r'  rF   Nc                 C   s   || _ d | _d | _d | _d S rH   )_writer	_encoding	_compress_encoding_buffer)r   r'  rB   rB   rC   r     s   
zMultipartPayloadWriter.__init__r{   c                 C   s0   |dkr|| _ t | _d S |dkrd| _ d S d S )Nr   r  )r  r   r  )r   r{   rB   rB   rC   r    s   
z&MultipartPayloadWriter.enable_encodingr   strategyc                 C   s   t |d|d| _d S )NT)r{   r  r  )r   r  )r   r{   r  rB   rB   rC   r    s
   z)MultipartPayloadWriter.enable_compressionc                    sf   | j d ur| j  }|rd | _ | |I d H  | jdkr/| jr1| jt| jI d H  d S d S d S )Nr   )r  flushr(  r  r  r  r   	b64encoderN  rB   rB   rC   r    s   


z MultipartPayloadWriter.write_eofr   c                    s   | j d ur|r| j |I d H }|sd S | jdkr[| j}|d us#J || |rWtt|d\}}|d |d  ||d d  }| _|rYt|}| j	
|I d H  d S d S d S | jdkrn| j	
t|I d H  d S | j	
|I d H  d S )Nr   r0   r  )r  compressr  r  r   divmodr   r   r  r  r(  r  b2a_qp)r   r   bufdivmod	enc_chunkb64chunkrB   rB   rC   r(    s*   


$

zMultipartPayloadWriter.write)r   Nr   )r?   r@   rA   r   r   ri   r  r   r   r  r  r  r(  rB   rB   rB   rC   r    s    

	r  )r   )Wr   r  r   rb   sysrX  rn   collectionsr   collections.abcr   r   typesr   typingr   r   r   r	   r
   r   r   r   r   r   r   r   urllib.parser   r   r   	multidictr   r   abcr   compression_utilsr   r   r   hdrsr   r   r   r   r    helpersr!   r"   r#   r$   httpr%   http_exceptionsr&   logr'   rs  r(   r)   r*   r+   r,   r-   r.   streamsr/   version_infor2   r3   __all__client_reqrepr<   RuntimeWarningr8   r9   ri   r:   r;   r   r4   	try_firstr  r6   r  r7   r  rB   rB   rB   rC   <module>   sr    8$	

h

!/  Z$ \  