f' dZddlmZddlZddlZddlmZmZmZm Z m Z ejdjZ ejdjZdZdZdZd Zd Zd Zd Zd ZdZeezdfZedfZeezdfZedfZeezdfZedfZeej>eedgej@ejBejDgddZ#ejHdie#jKZ&e ejNe(e)ee*ee*e*ffZ+ddZ,ddZ-GddZ.y)zHTools for working with the BSON decimal128 type. .. versionadded:: 3.4 ) annotationsN)AnySequenceTupleTypeUnionzes5z>?@K'')J D C 3r:& ' !q& ! 16MC(2z " !q& ! A!b&M !D#/O rzQn$  6)b00 2%%    9Q**?sF0-F= 0F:c|eZdZdZdZdZddZddZeddZ e ddZ ddZ dd Z dd Zdd Zdd Zdd Zy) 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 "", 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 )__high__lowct|ttjfrt |\|_|_yt|ttfr)t|dk7r td|\|_|_ytd|d)NzYInvalid size for creation of Decimal128 from list or tuple. Must have exactly 2 elements.zCannot convert z to Decimal128) isinstancer3rDecimalrE_Decimal128__high_Decimal128__lowlisttuplelenr+ TypeErrorselfr:s r__init__zDecimal128.__init__sw ec7??3 4&5e&< #DK e} -5zQ   ', #DKoeYnEF Frc |j}|j}|tzrdnd}|tztk(rt j |ddfS|t zt k(rt j |ddfS|tztk(rt j |ddfS|tztk(r'|dzdz tz }t j |d |fS|d zd z tz }td }d }tdddD]}||zd|z dzz ||<|dz}d }tdddD]}||zd|z dzz ||<|dz}d}||zdz |d<tdttj|dD}t j t"5} | j%|||fcdddS#1swYyxYw)z^Returns an instance of :class:`decimal.Decimal` for this :class:`Decimal128`. r rrNnFlr!)rlr l0c32K|]}t|ywN)r1).0r?s r z(Decimal128.to_decimal.. sOes5zOsbigN)rOrPr9_SNANrrN_NAN_INFr8r7 bytearrayr5rRr3r1 from_bytesr"r#r$) rVrArBr<r>arrmaskrCr=r;s r to_decimalzDecimal128.to_decimals{{jjE\q 5LU "??D"c?3 3Tkd "??D"c?3 3Tkd "??D"c?3 3 > !n 4 22r9^KH??D$#9: : 22r9^KHm!r1b!ADjrAv!m4CF19D""q!RATkA!|4CF19D!"+"$AOs3>>#u3M/NOO  ! !+ . @#%%tVX&>? @ @ @s F66F?ct|ts tdt|dk7r t d|t |dddt |dddfS)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 byteszvalue must be exactly 16 bytesrbNr)rMbytesrTrSr+ _UNPACK_64)clsr:s rfrom_bidzDecimal128.from_bidsb%'@A A u: => >JuQRy)!,jr.CA.FGHHrcXt|jt|jzS)z;The Binary Integer Decimal (BID) encoding of this instance.)_PACK_64rPrOrVs rbidzDecimal128.bids! #ht{{&;;;rcZ|j}|jryt|S)NNaN)rpr*r3)rVdecs r__str__zDecimal128.__str__"s#oo ::<3xrcd|dS)Nz Decimal128('z')rrys r__repr__zDecimal128.__repr__)sdXR((rc"|\|_|_yrerOrPrUs r __setstate__zDecimal128.__setstate__,s"' TZrc2|j|jfSrerrys r __getstate__zDecimal128.__getstate__/s{{DJJ&&rc`t|tr|j|jk(StSre)rMrGrzNotImplementedrVothers r__eq__zDecimal128.__eq__2s% eZ (88uyy( (rc||k( Srerrs r__ne__zDecimal128.__ne__7s5=  rN)r:_VALUE_OPTIONSreturnNone)rzdecimal.Decimal)ruzType[Decimal128]r:rsrrG)rrs)rr3)r:Tuple[int, int]rr)rr)rrrbool)__name__ __module__ __qualname____doc__ __slots__ _type_markerrWrp classmethodrvpropertyrzr~rrrrrrrrrGrGvsj[z$IL G'@R I I<<)(' !rrGr)rzdecimal.Context)r:rrr)/r __future__rrstructtypingrrrrrStructpackrxunpackrtr8r7 _EXPONENT_MAX _EXPONENT_MIN _MAX_DIGITSrkrjrir9r'r(r/r0r-r.ROUND_HALF_EVENInvalidOperationOverflowInexactrrrr#rNfloatr3r1rrrErGrrrrsS# 44 6==  # # V]]4 ' '     q q  q q  %-   ''   &&(8(8'// J   goo4 1 1 34 wsE#x}c:Q4RRS#-`B!B!r