
    FCf'              	         d Z ddlmZ ddlZddlZddlmZmZmZ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jB                  ejD                  gddZ# ejH                  di e#jK                         Z&e
ejN                  e(e)ee*ee*   e*f   f   Z+ddZ,ddZ- G d d      Z.y)zHTools for working with the BSON decimal128 type.

.. versionadded:: 3.4
    )annotationsN)AnySequenceTupleTypeUnionz<Ql            i   i   i"   l          @ l          ` l          p l               )precroundingEminEmaxcapitalsflagstrapsclampc                 ^    t         j                         } 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    )_CTX_OPTIONScopydecimalContext)optss    O/var/www/highfloat_scraper/venv/lib/python3.12/site-packages/bson/decimal128.pycreate_decimal128_contextr   =   s-     DDM??"T""    c           
        t        j                  t              5 }|j                  |       } ddd       | j	                         r| j                         rt        S t        S | j                         \  }}}| j                         rU|rt        d      | j                         r| j                         rt        S t        S | j                         rt        S t        S t!        dj#                  |D cg c]  }t%        |       c}            }|j'                         }d}d}	t)        t+        d|            D ]  }
|d|
z  z  s|	d|
z  z  }	 t)        d|      D ]  }
|d|
z  z  s|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	|t0        z  }||	fS # 1 sw Y   xY wc c}w )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 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str
bit_lengthrangemin_EXPONENT_BIAS_EXPONENT_MASK_SIGN)valuectxsigndigitsexponentdigitsignificandr4   highlowibiased_exponents               r   _decimal_to_128rE   F   s   
 
		k	* *c""5)* )u4u4"^^-D&(||~FGG==?"__.6:F:)u4u4bggv>es5z>?@K'')JD
C3r:&' !q&!16MC 2z" "!q&!A!b&M!D" /OrzQn$6)b002%%9Q* * ?s   F0-F=0F: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y)
Decimal128a  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   c                   t        |t        t        j                  f      rt	        |      \  | _        | _        y t        |t        t        f      r)t        |      dk7  rt        d      |\  | _        | _        y 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)
isinstancer3   r   DecimalrE   _Decimal128__high_Decimal128__lowlisttuplelenr+   	TypeErrorselfr:   s     r   __init__zDecimal128.__init__   sw    ec7??34&5e&<#DKe}-5zQ   
 ',#DKoeYnEFFr   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        j                  |d            D              }t	        j                   t"              5 }	|	j%                  |||f      cddd       S # 1 sw Y   yxY w)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              3  2   K   | ]  }t        |        y wN)r1   ).0r?   s     r   	<genexpr>z(Decimal128.to_decimal.<locals>.<genexpr>
  s     Oes5zOs   bigN)rO   rP   r9   _SNANr   rN   _NAN_INFr8   r7   	bytearrayr5   rR   r3   r1   
from_bytesr"   r#   r$   )
rV   rA   rB   r<   r>   arrmaskrC   r=   r;   s
             r   
to_decimalzDecimal128.to_decimal   s    {{jjE\q5LU"??D"c?33Tkd"??D"c?33Tkd"??D"c?33>!n4 22r9^KH??D$#9:: 22r9^KHm!r1b! 	ADjrAv!m4CF19D	 "q!R 	ATkA!|4CF19D	 "+"$A Os3>>#u3M/NOO!!+. 	@#%%tVX&>?	@ 	@ 	@s   F66F?c                    t        |t              st        d      t        |      dk7  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   zvalue must be exactly 16 bytesrb   Nr   )rM   bytesrT   rS   r+   
_UNPACK_64)clsr:   s     r   from_bidzDecimal128.from_bid  sb     %'@AAu:=>>JuQRy)!,jr.CA.FGHHr   c                X    t        | j                        t        | j                        z   S )z;The Binary Integer Decimal (BID) encoding of this instance.)_PACK_64rP   rO   rV   s    r   bidzDecimal128.bid  s!     

#ht{{&;;;r   c                Z    | j                         }|j                         ryt        |      S )NNaN)rp   r*   r3   )rV   decs     r   __str__zDecimal128.__str__"  s#    oo::<3xr   c                    d| dS )NzDecimal128('z')r   ry   s    r   __repr__zDecimal128.__repr__)  s    dXR((r   c                "    |\  | _         | _        y re   rO   rP   rU   s     r   __setstate__zDecimal128.__setstate__,  s    "'TZr   c                2    | j                   | j                  fS re   r   ry   s    r   __getstate__zDecimal128.__getstate__/  s    {{DJJ&&r   c                `    t        |t              r| j                  |j                  k(  S t        S re   )rM   rG   rz   NotImplementedrV   others     r   __eq__zDecimal128.__eq__2  s%    eZ(88uyy((r   c                    | |k(   S re   r   r   s     r   __ne__zDecimal128.__ne__7  s    5=  r   N)r:   _VALUE_OPTIONSreturnNone)r   zdecimal.Decimal)ru   zType[Decimal128]r:   rs   r   rG   )r   rs   )r   r3   )r:   Tuple[int, int]r   r   )r   r   )r   r   r   bool)__name__
__module____qualname____doc__	__slots___type_markerrW   rp   classmethodrv   propertyrz   r~   r   r   r   r   r   r   r   r   rG   rG   v   sj    [z $ILG'@R I I < <)('
!r   rG   r   )r   zdecimal.Context)r:   r   r   r   )/r   
__future__r   r   structtypingr   r   r   r   r   Structpackrx   unpackrt   r8   r7   _EXPONENT_MAX_EXPONENT_MIN_MAX_DIGITSrk   rj   ri   r9   r'   r(   r/   r0   r-   r.   ROUND_HALF_EVENInvalidOperationOverflowInexactr   r   r   r#   rN   floatr3   r1   r   r   rE   rG   r   r   r   <module>r      sS   #   4 46==##V]]4 ''
	q	q		q	q	
%-	
 ''&&(8(8'//J	 goo4 1 1 34wsE#x}c:Q4RRS#-`B! B!r   