o Sb' @s>dZddlZddlZddlmZmZmZmZmZe dj Z e dj Z dZdZdZdZd Zd Zd Zd Zd ZeedfZedfZeedfZedfZeedfZedfZeejeedgejejej gddZ!ej"die!#Z$eej%e&e'ee(ee(e(ffZ)dej"fddZ*de)dee(e(ffddZ+Gddde,Z-dS)zHTools for working with the BSON decimal128 type. .. versionadded:: 3.4 N)AnySequenceTupleTypeUnionz@rt|d| >O}qftd|D]} |d| >@r|d| d>O}qz|t} |d ?dkr|d @}|tO}|| d @d >O}n|| d >O}|r|tO}||fS) zConverts a decimal.Decimal to BID (high bits, low bits). :Parameters: - `value`: An instance of decimal.Decimal Nz'NaN with debug payload is not supportedcSsg|]}t|qSrstr.0digitrrr Zsz#_decimal_to_128..r@r1li?/)r localcontext _DEC128_CTXcreate_decimal is_infinite is_signed_NINF_PINFas_tupleis_nan ValueErroris_snan_NSNAN_PSNAN_NNAN_PNANintjoin bit_lengthrangemin_EXPONENT_BIAS_EXPONENT_MASK_SIGN) rctxsigndigitsexponentZ significandr6highlowiZbiased_exponentrrr_decimal_to_128EsB       rCc@seZdZdZdZdZdeddfddZdej fd d Z e d e dde ddfd d Zede fddZdefddZddZdeeefddfddZdeeeffddZdedefddZdedefddZdS) 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 "", line 1, in ... decimal.InvalidOperation: [] >>> >>> Decimal128("1E-6177") Traceback (most recent call last): File "", line 1, in ... decimal.Inexact: [] >>> >>> Decimal128("1E6145") Traceback (most recent call last): File "", line 1, in ... decimal.Overflow: [, ] 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 )Z__highZ__lowrrNcCsdt|ttjfrt|\|_|_dSt|ttfr+t |dkr#t d|\|_|_dSt d|f)NzYInvalid size for creation of Decimal128 from list or tuple. Must have exactly 2 elements.zCannot convert %r to Decimal128) isinstancerrDecimalrC_Decimal128__high_Decimal128__lowlisttuplelenr. TypeErrorselfrrrr__init__s zDecimal128.__init__c Cs|j}|j}|t@r dnd}|t@tkrt|ddfS|t@tkr*t|ddfS|t@tkr8t|ddfS|t@tkrN|d@d?t }t|d |fS|d @d ?t }t d }d }t dddD]}||@d|d>?||<|d>}qbd }t dddD]}||@d|d>?||<|d>}q}d}||@d?|d<t ddt t|dD}tt} | |||fWdS1swYdS)z^Returns an instance of :class:`decimal.Decimal` for this :class:`Decimal128`. rrrNnFlr$)rlr#l0css|]}t|VqdSN)r4rrrr sz(Decimal128.to_decimal..bigN)rIrJr;_SNANrrH_NAN_INFr:r9 bytearrayr7rLrr4 from_bytesr%r&r') rPr@rAr=r?ZarrmaskrBr>r<rrr to_decimals8       $zDecimal128.to_decimalclscCsRt|ts tdt|dkrtd|t|dddt|dddfS)zCreate 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 byteszvalue must be exactly 16 bytesr[Nr)rGbytesrNrMr. _UNPACK_64)rgrrrrfrom_bids  ,zDecimal128.from_bidcCst|jt|jS)z;The Binary Integer Decimal (BID) encoding of this instance.)_PACK_64rJrIrPrrrbidszDecimal128.bidcCs|}|r dSt|S)NNaN)rfr-r)rPdecrrr__str__$szDecimal128.__str__cCsdt|fS)NzDecimal128('%s')rrmrrr__repr__+szDecimal128.__repr__cCs|\|_|_dSr]rIrJrOrrr __setstate__.szDecimal128.__setstate__cCs |j|jfSr]rsrmrrr __getstate__1s zDecimal128.__getstate__othercCst|tr |j|jkStSr])rGrDrnNotImplementedrPrvrrr__eq__4s  zDecimal128.__eq__cCs ||k Sr]rrxrrr__ne__9s zDecimal128.__ne__)__name__ __module__ __qualname____doc__ __slots__Z _type_marker_VALUE_OPTIONSrQrrHrf classmethodrrirkpropertyrnrrqrrrr4rtrurboolryrzrrrrrDvs ^)rDr).r~rstructtypingrrrrrStructpackrlunpackrjr:r9Z _EXPONENT_MAXZ _EXPONENT_MINZ _MAX_DIGITSrbrar`r;r*r+r2r3r0r1ROUND_HALF_EVENInvalidOperationOverflowInexactrrrr&rHfloatrr4rrrCobjectrDrrrrsF       1