o
    ?8¾\¹(  ã                	   @   sV  d Z ddlZddlZddlZddlmZmZ ere	j
ZnddlZe	ejfdd„Ze d¡jZe d¡jZdZdZd	Zd
ZdZdZdZdZdZee dfZedfZee dfZedfZee dfZ edfZ!eej"eedg ej#ej$ej%gdœZ&zej'dd� de&d< W n e(yŽ   de&d< Y nw ej'di e& )¡ ¤ŽZ*dd„ Z+dd„ Z,G dd„ de-ƒZ.dS )zƒTools for working with the BSON decimal128 type.

.. versionadded:: 3.4

.. note:: The Decimal128 BSON type requires MongoDB 3.4+.
é    N)ÚPY3Ústring_typec                 C   s   ||| ƒdƒS )z3An implementation of int.from_bytes for python 2.x.é   © )ÚvalueÚdummyÚ_intÚ_hexlifyr   r   úA/var/www/html/env/lib/python3.10/site-packages/bson/decimal128.pyÚ_from_bytes"   s   r   z<Ql            i   i   ièÿÿé"   l          @ l          ` l          p l            é   )ÚprecÚroundingÚEminÚEmaxÚcapitalsÚflagsÚtraps)Úclampr   Ú_clampc                  C   s    t  ¡ } g | d< tjdi | ¤ŽS )z…Returns an instance of :class:`decimal.Context` appropriate
    for working with IEEE-754 128-bit decimal floating point values.
    r   Nr   )Ú_CTX_OPTIONSÚcopyÚdecimalÚContext)Úoptsr   r   r
   Úcreate_decimal128_contextS   s   r   c                 C   sl  t  t¡�}| | ¡} W d  ƒ n1 sw   Y  |  ¡ r&|  ¡ r$tS tS |  ¡ \}}}|  	¡ rK|r7t
dƒ‚|  ¡ rC|  ¡ rAtS tS |  ¡ rItS tS td dd„ |D ƒ¡ƒ}| ¡ }d}d}ttd|ƒƒD ]}	|d|	> @ rt|d|	> O }qftd|ƒD ]}	|d|	> @ rŠ|d|	d > O }qz|t }
|d	? dkr¦|d
@ }|tO }||
d@ d> O }n||
d	> O }|r²|tO }||fS )zConverts a decimal.Decimal to BID (high bits, low bits).

    :Parameters:
      - `value`: An instance of decimal.Decimal
    Nz'NaN with debug payload is not supportedÚ c                 S   s   g | ]}t |ƒ‘qS r   ©Ústr©Ú.0Údigitr   r   r
   Ú
<listcomp>q   s    z#_decimal_to_128.<locals>.<listcomp>r   é@   r   é1   l   ÿÿÿ iÿ?  é/   )r   ÚlocalcontextÚ_DEC128_CTXÚcreate_decimalÚis_infiniteÚ	is_signedÚ_NINFÚ_PINFÚas_tupleÚis_nanÚ
ValueErrorÚis_snanÚ_NSNANÚ_PSNANÚ_NNANÚ_PNANÚintÚjoinÚ
bit_lengthÚrangeÚminÚ_EXPONENT_BIASÚ_EXPONENT_MASKÚ_SIGN)r   ÚctxÚsignÚdigitsÚexponentÚsignificandr8   ÚhighÚlowÚiÚbiased_exponentr   r   r
   Ú_decimal_to_128\   sB   ÿ€€rG   c                   @   sp   e Zd ZdZdZdZdd„ Zdd„ Zedd	„ ƒZ	e
d
d„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )Ú
Decimal128aË  BSON Decimal128 type::

      >>> Decimal128(Decimal("0.0005"))
      Decimal128('0.0005')
      >>> Decimal128("0.0005")
      Decimal128('0.0005')
      >>> Decimal128((3474527112516337664, 5))
      Decimal128('0.0005')

    :Parameters:
      - `value`: An instance of :class:`decimal.Decimal`, string, or tuple of
        (high bits, low bits) from Binary Integer Decimal (BID) format.

    .. note:: :class:`~Decimal128` uses an instance of :class:`decimal.Context`
      configured for IEEE-754 Decimal128 when validating parameters.
      Signals like :class:`decimal.InvalidOperation`, :class:`decimal.Inexact`,
      and :class:`decimal.Overflow` are trapped and raised as exceptions::

        >>> Decimal128(".13.1")
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          ...
        decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]
        >>>
        >>> Decimal128("1E-6177")
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          ...
        decimal.Inexact: [<class 'decimal.Inexact'>]
        >>>
        >>> Decimal128("1E6145")
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          ...
        decimal.Overflow: [<class 'decimal.Overflow'>, <class 'decimal.Rounded'>]

      To ensure the result of a calculation can always be stored as BSON
      Decimal128 use the context returned by
      :func:`create_decimal128_context`::

        >>> import decimal
        >>> decimal128_ctx = create_decimal128_context()
        >>> with decimal.localcontext(decimal128_ctx) as ctx:
        ...     Decimal128(ctx.create_decimal(".13.3"))
        ...
        Decimal128('NaN')
        >>>
        >>> with decimal.localcontext(decimal128_ctx) as ctx:
        ...     Decimal128(ctx.create_decimal("1E-6177"))
        ...
        Decimal128('0E-6176')
        >>>
        >>> with decimal.localcontext(DECIMAL128_CTX) as ctx:
        ...     Decimal128(ctx.create_decimal("1E6145"))
        ...
        Decimal128('Infinity')

      To match the behavior of MongoDB's Decimal128 implementation
      str(Decimal(value)) may not match str(Decimal128(value)) for NaN values::

        >>> Decimal128(Decimal('NaN'))
        Decimal128('NaN')
        >>> Decimal128(Decimal('-NaN'))
        Decimal128('NaN')
        >>> Decimal128(Decimal('sNaN'))
        Decimal128('NaN')
        >>> Decimal128(Decimal('-sNaN'))
        Decimal128('NaN')

      However, :meth:`~Decimal128.to_decimal` will return the exact value::

        >>> Decimal128(Decimal('NaN')).to_decimal()
        Decimal('NaN')
        >>> Decimal128(Decimal('-NaN')).to_decimal()
        Decimal('-NaN')
        >>> Decimal128(Decimal('sNaN')).to_decimal()
        Decimal('sNaN')
        >>> Decimal128(Decimal('-sNaN')).to_decimal()
        Decimal('-sNaN')

      Two instances of :class:`Decimal128` compare equal if their Binary
      Integer Decimal encodings are equal::

        >>> Decimal128('NaN') == Decimal128('NaN')
        True
        >>> Decimal128('NaN').bid == Decimal128('NaN').bid
        True

      This differs from :class:`decimal.Decimal` comparisons for NaN::

        >>> Decimal('NaN') == Decimal('NaN')
        False
    )Ú__highÚ__lowé   c                 C   sd   t |ttjfƒrt|ƒ\| _| _d S t |ttfƒr+t	|ƒdkr#t
dƒ‚|\| _| _d S td|f ƒ‚)Né   zYInvalid size for creation of Decimal128 from list or tuple. Must have exactly 2 elements.zCannot convert %r to Decimal128)Ú
isinstanceÚ_string_typer   ÚDecimalrG   Ú_Decimal128__highÚ_Decimal128__lowÚlistÚtupleÚlenr0   Ú	TypeError©Úselfr   r   r   r
   Ú__init__ï   s   zDecimal128.__init__c           
      C   sŽ  | j }| j}|t@ rdnd}|t@ tkrt |ddf¡S |t@ tkr*t |ddf¡S |t@ tkr8t |ddf¡S |t@ tkrN|d@ d? t	 }t |d	|f¡S |d
@ d? t	 }t
dƒ}d}tdddƒD ]}||@ d| d> ? ||< |d> }qbd}tdddƒD ]}||@ d| d> ? ||< |d> }q}d}||@ d? |d< tdd„ tt|dƒƒD ƒƒ}t t¡�}	|	 |||f¡W  d  ƒ S 1 sÀw   Y  dS )z^Returns an instance of :class:`decimal.Decimal` for this
        :class:`Decimal128`.
        r   r   r   ÚNÚnÚFl         ÿ r&   )r   l         ü r%   é   éÿ   é   é   éÿÿÿÿé   é   l          é0   c                 s   s   � | ]}t |ƒV  qd S ©N)r6   r    r   r   r
   Ú	<genexpr>  s   € 
ÿz(Decimal128.to_decimal.<locals>.<genexpr>ÚbigN)rP   rQ   r=   Ú_SNANr   rO   Ú_NANÚ_INFr<   r;   Ú	bytearrayr9   rS   r   r   r'   r(   r)   )
rW   rC   rD   r?   rA   ÚarrÚmaskrE   r@   r>   r   r   r
   Ú
to_decimalû   s<   

ÿ$ÿzDecimal128.to_decimalc                 C   sR   t |tƒs	tdƒ‚t|ƒdkrtdƒ‚| t|dd… ƒd t|dd… ƒd fƒS )zûCreate an instance of :class:`Decimal128` from Binary Integer
        Decimal string.

        :Parameters:
          - `value`: 16 byte string (128-bit IEEE 754-2008 decimal floating
            point in Binary Integer Decimal (BID) format).
        z"value must be an instance of bytesr   zvalue must be exactly 16 bytesrb   Nr   )rM   ÚbytesrU   rT   r0   Ú
_UNPACK_64)Úclsr   r   r   r
   Úfrom_bid%  s
   
	,zDecimal128.from_bidc                 C   s   t | jƒt | jƒ S )z;The Binary Integer Decimal (BID) encoding of this instance.)Ú_PACK_64rQ   rP   ©rW   r   r   r
   Úbid4  s   zDecimal128.bidc                 C   s   |   ¡ }| ¡ r
dS t|ƒS )NÚNaN)rm   r/   r   )rW   Údecr   r   r
   Ú__str__9  s   zDecimal128.__str__c                 C   s   dt | ƒf S )NzDecimal128('%s')r   rs   r   r   r
   Ú__repr__@  s   zDecimal128.__repr__c                 C   s   |\| _ | _d S rd   ©rP   rQ   rV   r   r   r
   Ú__setstate__C  s   zDecimal128.__setstate__c                 C   s   | j | jfS rd   ry   rs   r   r   r
   Ú__getstate__F  s   zDecimal128.__getstate__c                 C   s   t |tƒr| j|jkS tS rd   )rM   rH   rt   ÚNotImplemented©rW   Úotherr   r   r
   Ú__eq__I  s   
zDecimal128.__eq__c                 C   s
   | |k S rd   r   r}   r   r   r
   Ú__ne__N  s   
zDecimal128.__ne__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__Ú_type_markerrX   rm   Úclassmethodrq   Úpropertyrt   rw   rx   rz   r{   r   r€   r   r   r   r
   rH   �   s     ]*

rH   r   )/r„   r   ÚstructÚsysÚbson.py3compatr   Ú_PY3r   rN   r6   Ú
from_bytesr   ÚbinasciiÚhexlifyÚStructÚpackrr   Úunpackro   r<   r;   Ú_EXPONENT_MAXÚ_EXPONENT_MINÚ_MAX_DIGITSri   rh   rg   r=   r,   r-   r4   r5   r2   r3   ÚROUND_HALF_EVENÚInvalidOperationÚOverflowÚInexactr   r   rU   r   r(   r   rG   ÚobjectrH   r   r   r   r
   Ú<module>   s^   þùþ	1