
    _i`-              	      <   d Z ddlmZ ddlZddlZddlmZ ddlmZmZm	Z	m
Z
mZ ddlmZmZ  ej        d          j        Z ej        d          j        ZdZd	Zd
ZdZdZdZdZdZdZeez   dfZedfZeez   dfZedfZ eez   dfZ!edfZ"eej#        eedg ej$        ej%        ej&        gddZ' ej(        d i e')                                Z*eej        e+e,e	e-ee-         e-f         f         Z. G d de          Z/ G d de          Z0d!dZ1d"dZ2 G d d          Z3dS )#zHTools for working with the BSON decimal128 type.

.. versionadded:: 3.4
    )annotationsNDecimal)AnySequenceTupleTypeUnion)TypeDecoderTypeEncoderz<Ql            i   i   i"   l          @ l          ` l          p l               )precroundingEminEmaxcapitalsflagstrapsclampc                  2    e Zd ZdZed
d            ZddZd	S )DecimalEncodera  Converts Python :class:`decimal.Decimal` to BSON :class:`Decimal128`.

    For example::
        opts = CodecOptions(type_registry=TypeRegistry([DecimalEncoder()]))
        bson.encode({"d": decimal.Decimal('1.0')}, codec_options=opts)

    .. versionadded:: 4.15
    returnType[Decimal]c                    t           S Nr   selfs    2D:\Nbitz\venv\Lib\site-packages\bson/decimal128.pypython_typezDecimalEncoder.python_typeJ   s        valuer   
Decimal128c                     t          |          S r   r#   r   r"   s     r   transform_pythonzDecimalEncoder.transform_pythonN   s    %   r!   N)r   r   )r"   r   r   r#   )__name__
__module____qualname____doc__propertyr    r'    r!   r   r   r   @   sR             X! ! ! ! ! !r!   r   c                  2    e Zd ZdZed
d            ZddZd	S )DecimalDecoderzConverts BSON :class:`Decimal128` to Python :class:`decimal.Decimal`.

    For example::
        opts = CodecOptions(type_registry=TypeRegistry([DecimalDecoder()]))
        bson.decode(data, codec_options=opts)

    .. versionadded:: 4.15
    r   Type[Decimal128]c                    t           S r   r%   r   s    r   	bson_typezDecimalDecoder.bson_type\   s    r!   r"   r   decimal.Decimalc                *    |                                 S r   )
to_decimalr&   s     r   transform_bsonzDecimalDecoder.transform_bson`   s    !!!r!   N)r   r0   )r"   r   r   r3   )r(   r)   r*   r+   r,   r2   r6   r-   r!   r   r/   r/   R   sR             X" " " " " "r!   r/   r   decimal.Contextc                 `    t                                           } g | d<   t          j        di | S )zReturns an instance of :class:`decimal.Context` appropriate
    for working with IEEE-754 128-bit decimal floating point values.
    r   r-   )_CTX_OPTIONScopydecimalContext)optss    r   create_decimal128_contextr>   d   s4     DDM?""T"""r!   r"   _VALUE_OPTIONSTuple[int, int]c                   t          j        t                    5 }|                    |           } ddd           n# 1 swxY w Y   |                                 r"|                                 rt          nt          S |                                 \  }}}| 	                                ri|rt          d          |                                 r"|                                 rt          nt          S |                                 rt          nt          S t!          d                    d |D                                 }|                                }d}d}t'          t)          d|                    D ]}	|d|	z  z  r|d|	z  z  }t'          d|          D ]}	|d|	z  z  r|d|	dz
  z  z  }|t*          z   }
|dz	  dk    r|d	z  }|t,          z  }||
d
z  dz  z  }n||
dz  z  }|r
|t.          z  }||fS )zoConverts a decimal.Decimal to BID (high bits, low bits).

    :param value: An instance of decimal.Decimal
    Nz'NaN with debug payload is not supported c                ,    g | ]}t          |          S r-   )str.0digits     r   
<listcomp>z#_decimal_to_128.<locals>.<listcomp>   s    >>>es5zz>>>r!   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significandr]   highlowibiased_exponents              r   _decimal_to_128rl   m   sT   
 
	k	*	* *c""5))* * * * * * * * * * * * * * *  5))4uuu4"^^--D&(||~~ 5 	HFGGG==?? 	;"__..:66F:))4uuu4bgg>>v>>>??@@K''))JD
C3r:&&''  !q&! 	16MC2z"" " "!q&! 	"A!b&M!D/OrzQn$6)b002%% 9s   <A A c                      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 )$r#   a  BSON Decimal128 type::

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

    :param 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   r"   r?   r   Nonec                D   t          |t          t          j        f          rt	          |          \  | _        | _        d S t          |t          t          f          r3t          |          dk    rt          d          |\  | _        | _        d S t          d|d          )N   zYInvalid size for creation of Decimal128 from list or tuple. Must have exactly 2 elements.zCannot convert z to Decimal128)
isinstancerD   r;   r   rl   _Decimal128__high_Decimal128__lowlisttuplelenrU   	TypeErrorr&   s     r   __init__zDecimal128.__init__   s    ec7?344 	G&5e&<&<#DKe}-- 		G5zzQ    
 ',#DKEeEEEFFFr!   r3   c           	        | j         }| j        }|t          z  rdnd}|t          z  t          k    rt	          j        |ddf          S |t          z  t          k    rt	          j        |ddf          S |t          z  t          k    rt	          j        |ddf          S |t          z  t          k    r'|dz  dz	  t          z
  }t	          j        |d	|f          S |d
z  dz	  t          z
  }t          d          }d}t          ddd          D ]}||z  d|z
  dz  z	  ||<   |dz  }d}t          ddd          D ]}||z  d|z
  dz  z	  ||<   |dz  }d}||z  dz	  |d<   t          d t          t                              |d                    D                       }t	          j        t"                    5 }	|	                    |||f          cddd           S # 1 swxY w Y   dS )z^Returns an instance of :class:`decimal.Decimal` for this
        :class:`Decimal128`.
        r   r   r-   NnFl          rK   )r   l          rJ                     l          0   c              3  4   K   | ]}t          |          V  d S r   )r[   rE   s     r   	<genexpr>z(Decimal128.to_decimal.<locals>.<genexpr>1  s(      OOes5zzOOOOOOr!   bigN)ru   rv   rb   _SNANr;   r   _NAN_INFra   r`   	bytearrayr^   rx   rD   r[   
from_bytesrL   rM   rN   )
r   rh   ri   rd   rf   arrmaskrj   re   rc   s
             r   r5   zDecimal128.to_decimal  s_    {jE\)qq5LU""?D"c?333Tkd""?D"c?333Tkd""?D"c?333>!n44 22r9^KH?D$#9::: 22r9^KHmm!r1b!! 	 	ADjrAv!m4CF19DD!q!R 	 	ATkA!|4CF19DD!+"$A OOs3>>#u3M3M/N/NOOOOO!+.. 	@#%%tVX&>??	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@s   1GGGclsr0   bytesc                4   t          |t                    st          dt          |                     t	          |          dk    rt          d           | t          |dd                   d         t          |dd                   d         f          S )zCreate an instance of :class:`Decimal128` from Binary Integer
        Decimal string.

        :param 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 bytes, not    zvalue must be exactly 16 bytesr   Nr   )rt   r   rz   typery   rU   
_UNPACK_64)r   r"   s     r   from_bidzDecimal128.from_bid6  s     %'' 	VTtE{{TTUUUu::=>>>sJuQRRy))!,jrr.C.CA.FGHHHr!   c                T    t          | j                  t          | j                  z   S )z;The Binary Integer Decimal (BID) encoding of this instance.)_PACK_64rv   ru   r   s    r   bidzDecimal128.bidD  s#     
##ht{&;&;;;r!   rD   c                t    |                                  }|                                rdS t          |          S )NNaN)r5   rT   rD   )r   decs     r   __str__zDecimal128.__str__I  s1    oo::<< 	53xxr!   c                    d| dS )NzDecimal128('z')r-   r   s    r   __repr__zDecimal128.__repr__P  s    (d((((r!   r@   c                $    |\  | _         | _        d S r   ru   rv   r&   s     r   __setstate__zDecimal128.__setstate__S  s    "'TZZZr!   c                    | j         | j        fS r   r   r   s    r   __getstate__zDecimal128.__getstate__V  s    {DJ&&r!   otherr   boolc                Z    t          |t                    r| j        |j        k    S t          S r   )rt   r#   r   NotImplementedr   r   s     r   __eq__zDecimal128.__eq__Y  s)    eZ(( 	)8uy((r!   c                    | |k     S r   r-   r   s     r   __ne__zDecimal128.__ne__^  s    5=  r!   N)r"   r?   r   rq   )r   r3   )r   r0   r"   r   r   r#   )r   r   )r   rD   )r"   r@   r   rq   )r   r@   )r   r   r   r   )r(   r)   r*   r+   	__slots___type_markerr{   r5   classmethodr   r,   r   r   r   r   r   r   r   r-   r!   r   r#   r#      s       [ [z $ILG G G G'@ '@ '@ '@R I I I [I < < < X<   ) ) ) )( ( ( (' ' ' '   
! ! ! ! ! !r!   r#   r-   )r   r7   )r"   r?   r   r@   )4r+   
__future__r   r;   structr   typingr   r   r   r	   r
   bson.codec_optionsr   r   Structpackr   unpackr   ra   r`   _EXPONENT_MAX_EXPONENT_MIN_MAX_DIGITSr   r   r   rb   rQ   rR   rY   rZ   rW   rX   ROUND_HALF_EVENInvalidOperationOverflowInexactr9   r<   r:   rM   floatrD   r[   r?   r   r/   r>   rl   r#   r-   r!   r   <module>r      s^    # " " " " "         4 4 4 4 4 4 4 4 4 4 4 4 4 4 7 7 7 7 7 7 7 76=#V]4  '
	q	q		q	q	
%-	
 '&(8'/J	 	 go44 1 1 3 344wsE#x}c:Q4RRS! ! ! ! ![ ! ! !$" " " " "[ " " "$# # # #- - - -`B! B! B! B! B! B! B! B! B! B!r!   