U
    ~fht                  <   @  s  U d Z ddlm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	Z	ddl
mZ ddl
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mZm Z m!Z!m"Z"m#Z#m$Z$ ddl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- dd	l.m/Z/ dd
l0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6m7Z7m8Z8m9Z9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@mAZAmBZB ddlCmDZD ddlEmFZF ddlGmHZH ddlImJZJ ddlKmLZL ddlMmNZNmOZO ddlPmQZQ ddlRmSZS erddlTmUZU ddlVmWZWmXZX zddlYmZZZ dZ[W n e\k
r   dZ[Y nX ddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWg<Z]dXZ^dYZ_dZZ`d[Zad\Zbd]Zcd^Zdd_Zed`ZfdaZgdbZhdcZiddZjdeZkdfZldgZmdhZndiZodjZpdkZqdlZresdmjtZuesdnjvZwesdnjtZxesdojtZyesdpjtZzesdqjtZ{drdsdtdudLZ|dvdwdxdydzd{Z}drdrdvdrdrdrd|d}d~dZ~drdrdvdddddZdrdrdvdrdrdrdd}ddZdrdrdvdvddrddddZdrdvdvd|dddZdrdrdvdvddrddddZdrdrdvdvddwddddZdrdrdvdvddrddddZdrdrdvdrdrdrdd}ddZdrdrdvdrdrdrdd}ddZdrdrdvdvddrddddZdrdrdvdvddwddddZdrdrdvdvddwddddZdrdrdvdrddrddddZdrdrdvdvddwddddZdrdrdvdrdrdrdd}ddZdrdrdvdrdrdrdd}ddZdrdrdvdrdrdrdd}ddZee^eee_eee`eeeaeeebeeecdd eedeeeeeeefeeegdd eeheeeieeejeeekeeeleeeme~eeneeeoeeepeeeqdd eerdd iZded< e[rdUdrdrdvdvddddddÄZndVdrdrdvdvddddddÄZe!deeef dƍZdWdrdvdvdddddȜddʄZdXdrdrdvdvddrddrd˜dd̈́ZdrdddМdd҄Ze[reZjZesdmjZesdnjZesdojZesdpjZesdqjZeddԄ edՃD ZddלddMZdddۜdd݄Zdddۜdd߄ZdwddۜddZdddrdrddddZdddrdrddddZddrddddddZdd'ddddddZddddddddZddwdrdrddddZdd"drdrddddZdddrdddddZdd/drdrddddZdddrdrddddZdddrdrddddZddWdrdrddd dZddrdrdrdڐdddZdڐddrdrddddZdd$drddddd	Zddvdrdrddd
dZddrdrdrddddZddrdrdrddddZdd(drdrddddZddrdrdrdڐdddZddrdrdrdڐdddZeeeeejee8eeeeeeeeeeeeeedee	jee,eeDee/ee<eeFeeHeeJeeLeeNeeOeeQee>eejeiZi ZeD ]"ZeeŐd	ree eej< 	qeddԄ eD ZȐdYddrdddddڐdddZdrdrdddڐdddZʐdZdrddddڐddd Ze[
r0eZjZe̐d!Zde1fd"dddڐd#d$dNZe$d[d%d&d'd(d)dOZe$d%ddϐd(d*dOZϐd\d%d+d,d(d-dOZϐd%dΐd.dМd/d0Ze[
reZjZe$d]d%d&d1d(d2dPZe$d%dΐd.d(d3dPZѐd^d%d+d4d(d5dPZdrdrddϐd6d7d8ZҐd9ddtd:d;Ze[r~eZjZdrd&d<d=d>Zdrddrd.d?d@dAZe$d_dڐd&dBd(dCdQZe$ddΐdDd(dEdQZ֐d`dڐd+dFd(dGdQZe$dadHd&dBdIdJdRZe$dHdΐdDdIdKdRZאdbdHd+dFdIdLdRZdddMdNdSZG dOdT dTeZddלdPdUZڐd&dלdQdRZeedSrejeېdT dS (c  av  BSON (Binary JSON) encoding and decoding.

The mapping from Python types to BSON types is as follows:

=======================================  =============  ===================
Python Type                              BSON Type      Supported Direction
=======================================  =============  ===================
None                                     null           both
bool                                     boolean        both
int [#int]_                              int32 / int64  py -> bson
:class:`bson.int64.Int64`                int64          both
float                                    number (real)  both
str                                      string         both
list                                     array          both
dict                                     object         both
:class:`~bson.son.SON`                   object         both
:py:class:`~collections.abc.Mapping`     object         py -> bson
:class:`~bson.raw_bson.RawBSONDocument`  object         both [#raw]_
datetime.datetime [#dt]_ [#dt2]_         UTC datetime   both
:class:`~bson.datetime_ms.DatetimeMS`    UTC datetime   both [#dt3]_
:class:`~bson.regex.Regex`               regex          both
compiled re [#re]_                       regex          py -> bson
:class:`~bson.binary.Binary`             binary         both
:py:class:`uuid.UUID` [#uuid]_           binary         both
:class:`~bson.objectid.ObjectId`         oid            both
:class:`~bson.dbref.DBRef`               dbref          both
:class:`~bson.dbref.DBRef`               dbpointer      bson -> py
None                                     undefined      bson -> py
:class:`~bson.code.Code`                 code           both
str                                      symbol         bson -> py
bytes [#bytes]_                          binary         both
:class:`~bson.timestamp.Timestamp`       timestamp      both
:class:`~bson.decimal128.Decimal128`     decimal128     both
:class:`~bson.min_key.MinKey`            min key        both
:class:`~bson.max_key.MaxKey`            max key        both
=======================================  =============  ===================

.. [#int] A Python int will be saved as a BSON int32 or BSON int64 depending
   on its size. A BSON int32 will always decode to a Python int. A BSON
   int64 will always decode to a :class:`~bson.int64.Int64`.
.. [#raw] Decoding a bson object to :class:`~bson.raw_bson.RawBSONDocument` can be
   optionally configured via :attr:`~bson.codec_options.CodecOptions.document_class`.
.. [#dt] datetime.datetime instances are encoded with millisecond precision so
   the microsecond field is truncated.
.. [#dt2] all datetime.datetime instances are encoded as UTC. By default, they
   are decoded as *naive* but timezone aware datetimes are also supported.
   See :doc:`/examples/datetimes` for examples.
.. [#dt3] To enable decoding a bson UTC datetime to a :class:`~bson.datetime_ms.DatetimeMS`
   instance see :ref:`handling-out-of-range-datetimes`.
.. [#uuid] For :py:class:`uuid.UUID` encoding and decoding behavior see :doc:`/examples/uuid`.
.. [#re] :class:`~bson.regex.Regex` instances and regular expression
   objects from ``re.compile()`` are both saved as BSON regular expressions.
   BSON regular expressions are decoded as :class:`~bson.regex.Regex`
   instances.
.. [#bytes] The bytes type is encoded as BSON binary with
   subtype 0. It will be decoded back to bytes.
    )annotationsN)utf_8_decode)utf_8_encode)abc)IOTYPE_CHECKINGAnyBinaryIOCallable	GeneratorIteratorMappingMutableMappingNoReturnOptionalSequenceTupleTypeTypeVarUnioncastoverload)ALL_UUID_SUBTYPESCSHARP_LEGACYJAVA_LEGACYOLD_UUID_SUBTYPESTANDARDUUID_SUBTYPEBinaryUuidRepresentation)Code)DEFAULT_CODEC_OPTIONSCodecOptionsDatetimeConversion_raw_document_class)EPOCH_AWAREEPOCH_NAIVE
DatetimeMS_datetime_to_millis_millis_to_datetime)DBRef)
Decimal128)InvalidBSONInvalidDocumentInvalidStringData)Int64MaxKeyMinKeyObjectId)Regex)RE_TYPESON)	Timestamp)utcRawBSONDocument)_DocumentType_ReadableBuffer)_cbsonTFr   r   r   r   r   r   r   r   r    r!   r"   r*   r+   r,   r-   r.   r/   r1   r3   r5   r6   r7   r8   r9   r:   r%   r&   BSONNUMBSONSTRBSONOBJBSONARRBSONBINBSONUNDBSONOIDBSONBOOBSONDATBSONNULBSONRGXBSONREFBSONCODBSONSYMBSONCWSBSONINTBSONTIMBSONLONBSONDECBSONMINBSONMAXget_data_and_viewgen_list_nameencodedecode
decode_alldecode_iterdecode_file_iteris_validBSONhas_cr#   r'                              	   
                                 z<dz<iz<iBz<qz<IIr   zTuple[Any, memoryview])datareturnc                 C  s.   t | ttfr| t| fS t| }| |fS N)
isinstancebytes	bytearray
memoryviewtobytes)rt   view r}   1/tmp/pip-unpacked-wheel-36gvocj8/bson/__init__.pyrU      s    intstrr   )element_typeelement_nameru   c                 C  s   t dt|  |dS )zUnknown type helper.z\Detected unknown BSON type {!r} for fieldname '{}'. Are you using the latest driver version?N)r,   formatchrrW   )r   r   r}   r}   r~   _raise_unknown_type   s    
 r   zTuple[int, int])rt   _viewpositiondummy0dummy1dummy2ru   c                 C  s   t | |d |d fS )z"Decode a BSON int32 to python int.r      )_UNPACK_INT_FROMrt   r   r   r   r   r   r}   r}   r~   _get_int  s    r   CodecOptions[Any]zTuple[str, int])rt   r|   r   optsru   c                 C  s.   |  d|}t||| |jdd |d fS )z'Decode a BSON 'C' string to python str.    Tr      )index_utf_8_decodeunicode_decode_error_handler)rt   r|   r   r   endr}   r}   r~   _get_c_string  s    r   zTuple[float, int]c                 C  s   t | |d |d fS )z%Decode a BSON double to python float.r      )_UNPACK_FLOAT_FROMr   r}   r}   r~   
_get_float  s    r   )rt   r|   r   obj_endr   dummyru   c                 C  st   t | |d }|d7 }|dk s*|| |k r2td|| d }| | dkrRtdt||| |jdd |d fS )z#Decode a BSON string to python str.r   r   r   zinvalid string lengthzinvalid end of stringT)r   r,   r   r   )rt   r|   r   r   r   r   lengthr   r}   r}   r~   _get_string  s    r   )rt   r   r   ru   c              
   C  s   zt | |d }W n2 tjk
rD } ztt|dW 5 d}~X Y nX || d }||krbtd| | dkrvtd|dkr||krtd||fS )z+Validate and return a BSON document's size.r   Nr   zinvalid object lengthbad eoo)r   structerrorr,   r   )rt   r   r   obj_sizeexcr   r}   r}   r~   _get_object_size(  s     r   zTuple[Any, int]c           	      C  s   t | ||\}}t|jr:|| ||d  ||| fS t| ||d ||}||7 }t|dtrd|krt|dttdfrt|	d|	dd|	dd||fS ||fS )zEDecode a BSON subdocument to opts.document_class or bson.dbref.DBRef.r   r   z$refz$idz$dbN)
r   r$   document_class_elements_to_dictrw   getr   typer*   pop)	rt   r|   r   r   r   r   r   r   objr}   r}   r~   _get_object9  s    
 (r   )rt   r|   r   r   r   r   ru   c                 C  s  t | |d }|| d }| | dkr.td|d7 }|d8 }g }|j}	| j}
t}|jj}||k r| | }|
d|d }z|| | |||||\}}W n tk
r   t|| Y nX |r|	t
|}|dk	r||}|	| qZ||d krtd||d fS )z#Decode a BSON array to python list.r   r   r   r   r   Nzbad array length)r   r,   appendr   _ELEMENT_GETTERtype_registry_decoder_mapKeyErrorr   r   r   )rt   r|   r   r   r   r   sizer   resultr   r   getterZdecoder_mapr   valuecustom_decoderr}   r}   r~   
_get_arrayN  sB         
r   z$Tuple[Union[Binary, uuid.UUID], int])rt   r   r   r   r   r   ru   c                 C  s   t | |\}}|d7 }|dkrLt| |d }|d7 }||d krHtd|}|| }	|dk sd|	|krltd|tkr|j}
t| ||	 |}|
tjks|tkr|
t	ks|t
kr|
t	kr||	fS ||
|	fS |dkr| ||	 }nt| ||	 |}||	fS )z:Decode a BSON binary to bson.binary.Binary or python UUID.      r   r   z,invalid binary (st 2) - lengths don't match!zbad binary object length)_UNPACK_LENGTH_SUBTYPE_FROMr   r,   r   uuid_representationr   r   ZUNSPECIFIEDr   r   r   Zas_uuid)rt   r   r   r   r   r   r   subtypeZlength2r   Zuuid_repZbinary_valuer   r}   r}   r~   _get_binaryx  s<    r   zTuple[ObjectId, int]c                 C  s   |d }t | || |fS )z1Decode a BSON ObjectId to bson.objectid.ObjectId.   r4   rt   r   r   r   r   r   r   r}   r}   r~   _get_oid  s    r   zTuple[bool, int]c                 C  sD   |d }| || }|dkr$d|fS |dkr4d|fS t d| dS )z.Decode a BSON true/false to python True/False.r   r   Fr_   Tzinvalid boolean value: %rN)r,   )rt   r   r   r   r   r   r   Zboolean_byter}   r}   r~   _get_boolean  s    r   z0Tuple[Union[datetime.datetime, DatetimeMS], int])rt   r   r   r   r   r   ru   c                 C  s   t t| |d ||d fS )z3Decode a BSON datetime to python datetime.datetime.r   r   )r)   _UNPACK_LONG_FROM)rt   r   r   r   r   r   r}   r}   r~   	_get_date  s    r   zTuple[Code, int]c                 C  s"   t | |||||\}}t||fS )z%Decode a BSON code to bson.code.Code.)r   r    )rt   r|   r   r   r   r   coder}   r}   r~   	_get_code  s    r   )rt   r|   r   _obj_endr   r   ru   c           	      C  s`   |t | |d  }t| ||d |||\}}t| |||||\}}||krRtdt|||fS )z-Decode a BSON code_w_scope to bson.code.Code.r   r   z+scope outside of javascript code boundaries)r   r   r   r,   r    )	rt   r|   r   r   r   r   Zcode_endr   scoper}   r}   r~   _get_code_w_scope  s    r   zTuple[Regex[Any], int])rt   r|   r   r   r   r   ru   c           	      C  s6   t | |||\}}t | |||\}}t||}||fS )zCDecode a BSON regex to bson.regex.Regex or a python pattern object.)r   r6   )	rt   r|   r   r   r   r   patternZ
bson_flagsZbson_rer}   r}   r~   
_get_regex  s    
r   zTuple[DBRef, int]c                 C  s:   t | |||||\}}t| |||||\}}t|||fS )z7Decode (deprecated) BSON DBPointer to bson.dbref.DBRef.)r   r   r*   )rt   r|   r   r   r   r   
collectionoidr}   r}   r~   _get_ref  s    r   zTuple[Timestamp, int]c                 C  s    t | |\}}t|||d fS )z4Decode a BSON timestamp to bson.timestamp.Timestamp.r   )_UNPACK_TIMESTAMP_FROMr9   )rt   r   r   r   r   r   inc	timestampr}   r}   r~   _get_timestamp  s    r   zTuple[Int64, int]c                 C  s   t t| |d |d fS )z(Decode a BSON int64 to bson.int64.Int64.r   r   )r/   r   r   r}   r}   r~   
_get_int64  s    r   zTuple[Decimal128, int]c                 C  s   |d }t | || |fS )z7Decode a BSON decimal128 to bson.decimal128.Decimal128.   )r+   Zfrom_bidr   r}   r}   r~   _get_decimal128  s    r   c                 C  s   d |fS rv   r}   uvwxyzr}   r}   r~   <lambda>      r   c                 C  s   d |fS rv   r}   r   r}   r}   r~   r     r   c                 C  s
   t  |fS rv   r2   r   r}   r}   r~   r     r   c                 C  s
   t  |fS rv   r0   r   r}   r}   r~   r     r   z)dict[int, Callable[..., Tuple[Any, int]]]r   boolTuple[str, Any, int])rt   r|   r   r   r   	raw_arrayru   c              	   C  s   t dt| ||||S )Nr   )r   r?   _element_to_dict)rt   r|   r   r   r   r   r}   r}   r~   r     s    r   c                 C  s   | | }|d7 }t | |||\}}|r`|ttkr`t| |t| \}}	||||	d  |	d fS zt| | |||||\}
}W n tk
r   t|| Y nX |jj	r|jj	
t|
}|dk	r||
}
||
|fS )z Decode a single key, value pair.r   N)r   ordrC   r   lenr   r   r   r   r   r   r   )rt   r|   r   r   r   r   r   r   _r   r   r   r}   r}   r~   r   '  s,    	     _T)boundzCodecOptions[RawBSONDocument])rt   r   r   r   r   r   ru   c                 C  s(   t | \} }ttt| ||||||dS )Nr   )rU   r   r   r   )rt   r   r   r   r   r   r|   r}   r}   r~   _raw_to_dictH  s
     r   )rt   r|   r   r   r   r   r   ru   c           
      C  sX   |dkr|  }|d }||k rDt| |||||d\}}	}|	||< q||krTtd|S )z#Decode a BSON document into result.Nr   r   bad object or element length)r   r   r,   )
rt   r|   r   r   r   r   r   r   keyr   r}   r}   r~   r   V  s     
     
r   zCodecOptions[_DocumentType]r=   )rt   r   ru   c                 C  s   t | \} }zDt|jr&|| |W S t| dt| \}}tdt| |d||W S  tk
rf    Y n6 tk
r   t	
 \}}}tt||dY nX dS )z'Decode a BSON string to document_class.r   r=   r   N)rU   r$   r   r   r   r   r   r,   	Exceptionsysexc_infor   with_traceback)rt   r   r|   r   r   	exc_valueexc_tbr}   r}   r~   _bson_to_dictm  s    
r   c                 c  s    | ]}t |d  dV  qdS ) utf8N)r   rW   ).0ir}   r}   r~   	<genexpr>  s     r     zGenerator[bytes, None, None])ru   c                  c  s2   t E dH  td} tt| d dV  qdS )zGenerate "keys" for encoded lists in the sequence
    b"0 ", b"1 ", b"2 ", ...

    The first 1000 keys are returned from a pre-built cache. All
    subsequent keys are generated on the fly.
    Nr   r   r   )_LIST_NAMES	itertoolscountr   nextrW   )counterr}   r}   r~   rV     s    

zUnion[str, bytes]rx   )stringru   c                 C  sz   t | trVd| krtdzt| dd | d W S  tk
rR   td|  dY qvX n d| krftdt| d d S dS )z8Make a 'C' string, checking for embedded NUL characters.r   z;BSON keys / regex patterns must not contain a NUL characterNT,strings in documents must be valid UTF-8: %rr   r   )rw   rx   r-   r   UnicodeErrorr.   _utf_8_encoder   r}   r}   r~   _make_c_string_check  s    


r  c                 C  sZ   t | trFzt| dd | d W S  tk
rB   td|  dY qVX nt| d d S dS )zMake a 'C' string.NTr   r   r   )rw   rx   r   r   r.   r   r   r}   r}   r~   _make_c_string  s    


r  c                 C  s    d| krt dt| d d S )z*Make a 'C' string suitable for a BSON key.r   z*BSON keys must not contain a NUL characterr   r   )r-   r   r   r}   r}   r~   
_make_name  s    r  float)namer   r   r   ru   c                 C  s   d|  t | S )zEncode a float.r_   )_PACK_FLOATr  r   r   r   r}   r}   r~   _encode_float  s    r  c                 C  s   d|  t t| d | S )zEncode a python bytes.rc   r   )	_PACK_INTr   r  r}   r}   r~   _encode_bytes  s    r
  )r  r   
check_keysr   ru   c                   sZ   t |rd|  tt|j S d fdd| D }d|  tt|d  | d S )zEncode a mapping type.ra   r   c                   s   g | ]\}}t || qS r}   )_element_to_bson)r   r   valr  r   r}   r~   
<listcomp>  s     z#_encode_mapping.<locals>.<listcomp>r   r   )r$   r   rx   rawjoinitemsr	  r   r  r   r  r   rt   r}   r  r~   _encode_mapping  s    r  c                 C  s   t d|  d }t|d }|td|j||7 }|td|j||7 }|jdk	rb|td|j||7 }|j D ]\}}|t||||7 }ql|d7 }t	t|| |||d < t
|S )	zEncode bson.dbref.DBRef.ra   s       r   s   $ref s   $id Ns   $db r   )ry   r   _name_value_to_bsonr   idZdatabaseZ_DBRef__kwargsr  r  r	  rx   )r  r   r  r   bufbeginr   r  r}   r}   r~   _encode_dbref  s    
r  zSequence[Any]c                   sB   t  d fdd|D }d|  tt|d  | d S )zEncode a list/tuple.r   c                   s   g | ]}t t| qS r}   )r  r   )r   itemr  lnamer   r}   r~   r    s     z _encode_list.<locals>.<listcomp>rb   r   r   )rV   r  r	  r   r  r}   r  r~   _encode_list  s    r  c                 C  s,   t |d }d|  tt|d  | d S )zEncode a python str.r   r`   r   r   )r   r	  r   )r  r   r   r   Zbvaluer}   r}   r~   _encode_text  s    r  c                 C  s8   |j }|dkrtt|| }d|  tt|| | S )zEncode bson.binary.Binary.r   rc   )r   r	  r   _PACK_LENGTH_SUBTYPE)r  r   r   r   r   r}   r}   r~   _encode_binary  s    r   z	uuid.UUID)r  r   r   r   ru   c                 C  s"   |j }tj||d}t| |||S )zEncode uuid.UUID.)r   )r   r   Z	from_uuidr   )r  r   r   r   r   Zbinvalr}   r}   r~   _encode_uuid  s    r!  )r  r   r   r   ru   c                 C  s   d|  |j  S )zEncode bson.objectid.ObjectId.re   )binary)r  r   r   r   r}   r}   r~   _encode_objectid   s    r#  c                 C  s   d|  |rdpd S )z%Encode a python boolean (True/False).rf   r_   r   r}   r  r}   r}   r~   _encode_bool  s    r$  zdatetime.datetimec                 C  s   t |}d|  t| S zEncode datetime.datetime.rg   )r(   
_PACK_LONGr  r   r   r   Zmillisr}   r}   r~   _encode_datetime
  s    r(  c                 C  s   t |}d|  t| S r%  )r   r&  r'  r}   r}   r~   _encode_datetime_ms  s    r)  )r  r   r   r   ru   c                 C  s   d|  S )zEncode python None.rh   r}   r  r   r   r   r}   r}   r~   _encode_none  s    r+  z
Regex[Any]c                 C  s   |j }|tjkr&d|  t|j d S |dkrDd|  t|j d S d}|tj@ rZ|d7 }|tj@ rl|d7 }|tj@ r~|d7 }|tj@ r|d	7 }|tj@ r|d
7 }|tj	@ r|d7 }|d7 }d|  t|j | S dS )z*Encode a python regex or bson.regex.Regex.ri   s   u r   r   r      i   l   m   s   u   xN)
flagsreUNICODEr  r   
IGNORECASELOCALE	MULTILINEDOTALLVERBOSE)r  r   r   r   r2  Zsflagsr}   r}   r~   _encode_regex  s(    






r:  c                 C  sn   t |}t|}|jdkr.d|  t| | S t|jd|d}td| t| }d|  | t| | | S )zEncode bson.code.Code.Nrk   Fr   rm   )r  r   r   r	  _dict_to_bson)r  r   r   r   ZcstringZcstrlenr   Zfull_lengthr}   r}   r~   _encode_code5  s    
r<  c                 C  s`   d|  krdkr(n nd|  t | S zd|  t| W S  tjk
rZ   tddY nX dS )zEncode a python int.i   irn   rp   &BSON can only handle up to 8-byte intsN)r	  r&  r   r   OverflowErrorr  r}   r}   r~   _encode_int@  s    r?  c                 C  s   d|  t |j|j S )z Encode bson.timestamp.Timestamp.ro   )_PACK_TIMESTAMPr   timer  r}   r}   r~   _encode_timestampK  s    rB  c                 C  s8   zd|  t | W S  tjk
r2   tddY nX dS )zEncode a bson.int64.Int64.rp   r=  N)r&  r   r   r>  r  r}   r}   r~   _encode_longP  s    rC  c                 C  s   d|  |j  S )z"Encode bson.decimal128.Decimal128.rq   )bidr  r}   r}   r~   _encode_decimal128X  s    rE  c                 C  s   d|  S )zEncode bson.min_key.MinKey.rr   r}   r*  r}   r}   r~   _encode_minkey]  s    rF  c                 C  s   d|  S )zEncode bson.max_key.MaxKey.rs   r}   r*  r}   r}   r~   _encode_maxkeyb  s    rG  _type_markerc                 c  s   | ]
}|V  qd S rv   r}   )r   tr}   r}   r~   r     s     )r  r   r  r   in_custom_callin_fallback_callru   c                 C  sf  d}zt t| | |||W S  tk
r0   Y n$ tk
rR   t|tsJ d}Y nX t|dd}t|tr|tkrt| }|t t|< || |||S |s|jj	r|jj	
t|}	|	dk	rt| |	|||ddS tD ]8}
|st||
rt |
 }|t t|< || |||  S q|jj}|s<|dk	r<t| ||||ddS |rJtdtd|d	t|dS )
z!Encode a single name, value pair.FTrH  N)rJ  )rK  r=  zcannot encode object: z, of type: )	_ENCODERSr   r   r>  rw   r   getattr_MARKERSr   Z_encoder_mapr   r  _BUILT_IN_TYPESZ_fallback_encoderr-   )r  r   r  r   rJ  rK  Zwas_integer_overflowmarkerfuncZcustom_encoderbaseZfallback_encoderr}   r}   r~   r    sR    


        r  )r   r   r  r   ru   c                 C  sd   t | tstd| |rN| dr6td| dd| krNtd| dt| }t||||S )z Encode a single key, value pair.z.documents must have only string keys, key was $zkey z must not start with '$'.z must not contain '.')rw   r   r-   
startswithr  r  )r   r   r  r   r  r}   r}   r~   r    s    

r  )docr  r   	top_levelru   c                 C  s   t | rtt| jS z^g }|r>d| kr>|td| d || |  D ](\}}|rZ|dkrF|t|||| qFW n$ tk
r   t	d| dY nX d
|}tt|d | d S )zEncode a document to BSON.Z_ids   _id z)encoder expected a mapping type but got: Nr   r   r   )r$   r   rx   r  r   r  r  r  AttributeError	TypeErrorr  r	  r   )rV  r  r   rW  elementsr   r   encodedr}   r}   r~   r;    s    
r;  z1codec_options must be an instance of CodecOptionsMapping[str, Any])documentr  codec_optionsru   c                 C  s   t |tstt| ||S )a  Encode a document to BSON.

    A document can be any mapping type (like :class:`dict`).

    Raises :class:`TypeError` if `document` is not a mapping type,
    or contains keys that are not instances of :class:`str`. Raises
    :class:`~bson.errors.InvalidDocument` if `document` cannot be
    converted to :class:`BSON`.

    :param document: mapping type representing a document
    :param check_keys: check if keys start with '$' or
        contain '.', raising :class:`~bson.errors.InvalidDocument` in
        either case
    :param codec_options: An instance of
        :class:`~bson.codec_options.CodecOptions`.

    .. versionadded:: 3.9
    )rw   r"   _CODEC_OPTIONS_TYPE_ERRORr;  )r]  r  r^  r}   r}   r~   rW      s    
r>   Nonedict[str, Any])rt   r^  ru   c                 C  s   d S rv   r}   rt   r^  r}   r}   r~   rX     s    c                 C  s   d S rv   r}   rb  r}   r}   r~   rX   "  s    z%Optional[CodecOptions[_DocumentType]]$Union[dict[str, Any], _DocumentType]c                 C  s&   |pt }t|tsttdt| |S )a  Decode BSON to a document.

    By default, returns a BSON document represented as a Python
    :class:`dict`. To use a different :class:`MutableMapping` class,
    configure a :class:`~bson.codec_options.CodecOptions`::

        >>> import collections  # From Python standard library.
        >>> import bson
        >>> from bson.codec_options import CodecOptions
        >>> data = bson.encode({'a': 1})
        >>> decoded_doc = bson.decode(data)
        <type 'dict'>
        >>> options = CodecOptions(document_class=collections.OrderedDict)
        >>> decoded_doc = bson.decode(data, codec_options=options)
        >>> type(decoded_doc)
        <class 'collections.OrderedDict'>

    :param data: the BSON to decode. Any bytes-like object that implements
        the buffer protocol.
    :param codec_options: An instance of
        :class:`~bson.codec_options.CodecOptions`.

    .. versionadded:: 3.9
    rc  )r!   rw   r"   r_  r   r   )rt   r^  r   r}   r}   r~   rX   '  s    
zlist[_DocumentType]c                 C  s  t | \} }t| }g }d}|d }t|j}z||k rt| |d }|| |k rZtd|| d }	| |	 dkrztd|r||| ||	d  | n|t| ||d |	| ||7 }q0|W S  tk
r    Y n8 tk
r   t	
 \}
}}tt||dY nX dS )z)Decode a BSON data to multiple documents.r   r   zinvalid object sizer   r   N)rU   r   r$   r   r   r,   r   r   r   r   r   r   r   )rt   r   r|   Zdata_lenZdocsr   r   Zuse_rawr   r   r   r   r   r}   r}   r~   _decode_allI  s0    
 
rd  zlist[dict[str, Any]]c                 C  s   d S rv   r}   rb  r}   r}   r~   rY   k  s    c                 C  s   d S rv   r}   rb  r}   r}   r~   rY   p  s    z0Union[list[dict[str, Any]], list[_DocumentType]]c                 C  s*   |dkrt | tS t|ts tt | |S )a+  Decode BSON data to multiple documents.

    `data` must be a bytes-like object implementing the buffer protocol that
    provides concatenated, valid, BSON-encoded documents.

    :param data: BSON data
    :param codec_options: An instance of
        :class:`~bson.codec_options.CodecOptions`.

    .. versionchanged:: 3.9
       Supports bytes-like objects that implement the buffer protocol.

    .. versionchanged:: 3.0
       Removed `compile_re` option: PyMongo now always represents BSON regular
       expressions as :class:`~bson.regex.Regex` objects. Use
       :meth:`~bson.regex.Regex.try_compile` to attempt to convert from a
       BSON regular expression to a Python regular expression object.

       Replaced `as_class`, `tz_aware`, and `uuid_subtype` options with
       `codec_options`.
    N)rd  r!   rw   r"   r_  rb  r}   r}   r~   rY   w  s
    

)rawdocfieldsr^  ru   c                 C  sv   t |jri }n| }|  D ]P\}}||krh|| dkrRt| j|| ||< qpt||| |||< q |||< q |S )Nr   )r$   r   r  r   r  _decode_selective)re  rf  r^  rV  r   r   r}   r}   r~   rg    s    
  

rg  zUnion[memoryview, bytes]c                 C  s   d}t | }t||t|\}}|d7 }g }|j}||d k r|| dkrT|d7 }q>|d7 }t|||\}}|||||   ||7 }q2||krtdd|S )Nr   r   r   r   r   )rz   r   r   r   r,   r  )rt   r   r|   r   r   buffersr   r   r}   r}   r~   _array_of_documents_to_buffer  s     

ri  )r]  ru   c                 C  sP   |  d}|sdS dD ]4}| |}|s*qt|}|rB|g||< qg ||< qdS )z=Convert raw array of documents to a stream of BSON documents.cursorN)Z
firstBatchZ	nextBatch)r   ri  )r]  rj  r   batchrt   r}   r}   r~   &_convert_raw_document_lists_to_streams  s    

rl  )rt   r^  rf  ru   c                 C  sZ   |j jst| |S |s(t| |jddS ddlm} |j|dd}t| |}t|||gS )aW  Decode BSON data to a single document while using user-provided
    custom decoding logic.

    `data` must be a string representing a valid, BSON-encoded document.

    :param data: BSON data
    :param codec_options: An instance of
        :class:`~bson.codec_options.CodecOptions` with user-specified type
        decoders. If no decoders are found, this method is the same as
        ``decode_all``.
    :param fields: Map of document namespaces where data that needs
        to be custom decoded lives or None. For example, to custom decode a
        list of objects in 'field1.subfield1', the specified value should be
        ``{'field1': {'subfield1': 1}}``. If ``fields``  is an empty map or
        None, this method is the same as ``decode_all``.

    :return: Single-member list containing the decoded document.

    .. versionadded:: 3.8
    N)r   r   r;   )r   r   )r   r   rY   Zwith_optionsbson.raw_bsonr<   r   rg  )rt   r^  rf  r<   Zinternal_codec_options_docr}   r}   r~   _decode_all_selective  s     
 
ro  zIterator[dict[str, Any]]c                 C  s   d S rv   r}   rb  r}   r}   r~   rZ     s    zIterator[_DocumentType]c                 C  s   d S rv   r}   rb  r}   r}   r~   rZ   
  s    z8Union[Iterator[dict[str, Any]], Iterator[_DocumentType]]c                 c  sf   |pt }t|tstd}t| d }||k rbt| |d }| |||  }||7 }t||V  q&dS )a  Decode BSON data to multiple documents as a generator.

    Works similarly to the decode_all function, but yields one document at a
    time.

    `data` must be a string of concatenated, valid, BSON-encoded
    documents.

    :param data: BSON data
    :param codec_options: An instance of
        :class:`~bson.codec_options.CodecOptions`.

    .. versionchanged:: 3.0
       Replaced `as_class`, `tz_aware`, and `uuid_subtype` options with
       `codec_options`.

    .. versionadded:: 2.8
    r   r   N)r!   rw   r"   r_  r   r   r   )rt   r^  r   r   r   r   rZ  r}   r}   r~   rZ     s    
zUnion[BinaryIO, IO[bytes]])file_objr^  ru   c                 C  s   d S rv   r}   rp  r^  r}   r}   r~   r[   2  s    c                 C  s   d S rv   r}   rq  r}   r}   r~   r[   9  s    c                 c  sf   |pt }| d}|sqbnt|dkr.tdt|dd d }|| td| }t||V  qdS )a  Decode bson data from a file to multiple documents as a generator.

    Works similarly to the decode_all function, but reads from the file object
    in chunks and parses bson in chunks, yielding one document at a time.

    :param file_obj: A file object containing BSON data.
    :param codec_options: An instance of
        :class:`~bson.codec_options.CodecOptions`.

    .. versionchanged:: 3.0
       Replaced `as_class`, `tz_aware`, and `uuid_subtype` options with
       `codec_options`.

    .. versionadded:: 2.8
    r   zcut off in middle of objsizer   N)r!   readr   r,   r   maxr   )rp  r^  r   Z	size_datar   rZ  r}   r}   r~   r[   @  s    
)bsonru   c                 C  s>   t | tstdzt| t W dS  tk
r8   Y dS X dS )a  Check that the given string represents valid :class:`BSON` data.

    Raises :class:`TypeError` if `bson` is not an instance of
    :class:`bytes`. Returns ``True``
    if `bson` is valid :class:`BSON`, ``False`` otherwise.

    :param bson: the data to be validated
    z4BSON data must be an instance of a subclass of bytesTFN)rw   rx   rY  r   r!   r   )rt  r}   r}   r~   r\   `  s    	

c                   @  sD   e Zd ZdZedefddddd ddd	Zefdd
dddZdS )r]   zBSON (Binary JSON) data.

    .. warning:: Using this class to encode and decode BSON adds a performance
       cost. For better performance use the module level functions
       :func:`encode` and :func:`decode` instead.
    Fz
Type[BSON]r\  r   r   )clsr]  r  r^  ru   c                 C  s   | t |||S )a  Encode a document to a new :class:`BSON` instance.

        A document can be any mapping type (like :class:`dict`).

        Raises :class:`TypeError` if `document` is not a mapping type,
        or contains keys that are not instances of
        :class:`str'. Raises :class:`~bson.errors.InvalidDocument`
        if `document` cannot be converted to :class:`BSON`.

        :param document: mapping type representing a document
        :param check_keys: check if keys start with '$' or
            contain '.', raising :class:`~bson.errors.InvalidDocument` in
            either case
        :param codec_options: An instance of
            :class:`~bson.codec_options.CodecOptions`.

        .. versionchanged:: 3.0
           Replaced `uuid_subtype` option with `codec_options`.
        )rW   )ru  r]  r  r^  r}   r}   r~   rW   {  s    zBSON.encodera  )r^  ru   c                 C  s
   t | |S )a  Decode this BSON data.

        By default, returns a BSON document represented as a Python
        :class:`dict`. To use a different :class:`MutableMapping` class,
        configure a :class:`~bson.codec_options.CodecOptions`::

            >>> import collections  # From Python standard library.
            >>> import bson
            >>> from bson.codec_options import CodecOptions
            >>> data = bson.BSON.encode({'a': 1})
            >>> decoded_doc = bson.BSON(data).decode()
            <type 'dict'>
            >>> options = CodecOptions(document_class=collections.OrderedDict)
            >>> decoded_doc = bson.BSON(data).decode(codec_options=options)
            >>> type(decoded_doc)
            <class 'collections.OrderedDict'>

        :param codec_options: An instance of
            :class:`~bson.codec_options.CodecOptions`.

        .. versionchanged:: 3.0
           Removed `compile_re` option: PyMongo now always represents BSON
           regular expressions as :class:`~bson.regex.Regex` objects. Use
           :meth:`~bson.regex.Regex.try_compile` to attempt to convert from a
           BSON regular expression to a Python regular expression object.

           Replaced `as_class`, `tz_aware`, and `uuid_subtype` options with
           `codec_options`.
        )rX   )selfr^  r}   r}   r~   rX     s     zBSON.decodeN)__name__
__module____qualname____doc__classmethodr!   rW   rX   r}   r}   r}   r~   r]   s  s   c                   C  s   t S )zIs the C extension installed?)_USE_Cr}   r}   r}   r~   r^     s    c                   C  s   t j rt j  dS )z!Releases the ObjectID lock child.N)r5   Z	_inc_locklockedreleaser}   r}   r}   r~   _after_fork  s    
r  register_at_fork)after_in_child)F)F)F)NF)FF)T)N)N)N)N)N)N)N)N)rz  
__future__r   datetimer   osr3  r   r   uuidcodecsr   r   r   r   collectionsr   _abctypingr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   Zbson.binaryr   r   r   r   r   r   r   r   Z	bson.coder    Zbson.codec_optionsr!   r"   r#   r$   Zbson.datetime_msr%   r&   r'   r(   r)   Z
bson.dbrefr*   Zbson.decimal128r+   Zbson.errorsr,   r-   r.   Z
bson.int64r/   Zbson.max_keyr1   Zbson.min_keyr3   Zbson.objectidr5   Z
bson.regexr6   Zbson.sonr7   r8   Zbson.timestampr9   Zbson.tz_utilr:   rm  r<   Zbson.typingsr=   r>   rt  r?   r|  ImportError__all__r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   Structunpack_fromr   unpackZ_UNPACK_INTr   r   r   r   rU   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __annotations__r   r   r   r   r   r   packr  r	  r  r&  r@  tupleranger   rV   r  r  r  r  r
  r  r  r  r  r   r!  r#  r$  r(  r)  r+  r:  r<  r?  rB  rC  rE  rF  rG  r   rx   dictr  r   listr   UUIDrL  rN  Z_typhasattrrH  rO  r  r  r;  rY  r_  rW   rX   rd  rY   rg  ri  rl  ro  rZ   r[   r\   r]   r^   r  r  r}   r}   r}   r~   <module>   s  9P(

?*%
	                     	 	                          "D
"""!- #  G