mirror of
https://github.com/python/cpython.git
synced 2024-11-23 18:04:37 +08:00
Issue #15783: Except for the number methods, the C version of decimal now
supports all None default values present in decimal.py. These values were largely undocumented.
This commit is contained in:
parent
618c2e13ca
commit
040e311826
@ -459,7 +459,7 @@ Decimal objects
|
||||
a :class:`Decimal` instance is always canonical, so this operation returns
|
||||
its argument unchanged.
|
||||
|
||||
.. method:: compare(other[, context])
|
||||
.. method:: compare(other, context=None)
|
||||
|
||||
Compare the values of two Decimal instances. :meth:`compare` returns a
|
||||
Decimal instance, and if either operand is a NaN then the result is a
|
||||
@ -470,13 +470,13 @@ Decimal objects
|
||||
a == b ==> Decimal('0')
|
||||
a > b ==> Decimal('1')
|
||||
|
||||
.. method:: compare_signal(other[, context])
|
||||
.. method:: compare_signal(other, context=None)
|
||||
|
||||
This operation is identical to the :meth:`compare` method, except that all
|
||||
NaNs signal. That is, if neither operand is a signaling NaN then any
|
||||
quiet NaN operand is treated as though it were a signaling NaN.
|
||||
|
||||
.. method:: compare_total(other)
|
||||
.. method:: compare_total(other, context=None)
|
||||
|
||||
Compare two operands using their abstract representation rather than their
|
||||
numerical value. Similar to the :meth:`compare` method, but the result
|
||||
@ -494,13 +494,21 @@ Decimal objects
|
||||
higher in the total order than the second operand. See the specification
|
||||
for details of the total order.
|
||||
|
||||
.. method:: compare_total_mag(other)
|
||||
This operation is unaffected by context and is quiet: no flags are changed
|
||||
and no rounding is performed. As an exception, the C version may raise
|
||||
InvalidOperation if the second operand cannot be converted exactly.
|
||||
|
||||
.. method:: compare_total_mag(other, context=None)
|
||||
|
||||
Compare two operands using their abstract representation rather than their
|
||||
value as in :meth:`compare_total`, but ignoring the sign of each operand.
|
||||
``x.compare_total_mag(y)`` is equivalent to
|
||||
``x.copy_abs().compare_total(y.copy_abs())``.
|
||||
|
||||
This operation is unaffected by context and is quiet: no flags are changed
|
||||
and no rounding is performed. As an exception, the C version may raise
|
||||
InvalidOperation if the second operand cannot be converted exactly.
|
||||
|
||||
.. method:: conjugate()
|
||||
|
||||
Just returns self, this method is only to comply with the Decimal
|
||||
@ -517,7 +525,7 @@ Decimal objects
|
||||
Return the negation of the argument. This operation is unaffected by the
|
||||
context and is quiet: no flags are changed and no rounding is performed.
|
||||
|
||||
.. method:: copy_sign(other)
|
||||
.. method:: copy_sign(other, context=None)
|
||||
|
||||
Return a copy of the first operand with the sign set to be the same as the
|
||||
sign of the second operand. For example:
|
||||
@ -525,10 +533,11 @@ Decimal objects
|
||||
>>> Decimal('2.3').copy_sign(Decimal('-1.5'))
|
||||
Decimal('-2.3')
|
||||
|
||||
This operation is unaffected by the context and is quiet: no flags are
|
||||
changed and no rounding is performed.
|
||||
This operation is unaffected by context and is quiet: no flags are changed
|
||||
and no rounding is performed. As an exception, the C version may raise
|
||||
InvalidOperation if the second operand cannot be converted exactly.
|
||||
|
||||
.. method:: exp([context])
|
||||
.. method:: exp(context=None)
|
||||
|
||||
Return the value of the (natural) exponential function ``e**x`` at the
|
||||
given number. The result is correctly rounded using the
|
||||
@ -565,7 +574,7 @@ Decimal objects
|
||||
|
||||
.. versionadded:: 3.1
|
||||
|
||||
.. method:: fma(other, third[, context])
|
||||
.. method:: fma(other, third, context=None)
|
||||
|
||||
Fused multiply-add. Return self*other+third with no rounding of the
|
||||
intermediate product self*other.
|
||||
@ -594,7 +603,7 @@ Decimal objects
|
||||
Return :const:`True` if the argument is a (quiet or signaling) NaN and
|
||||
:const:`False` otherwise.
|
||||
|
||||
.. method:: is_normal()
|
||||
.. method:: is_normal(context=None)
|
||||
|
||||
Return :const:`True` if the argument is a *normal* finite number. Return
|
||||
:const:`False` if the argument is zero, subnormal, infinite or a NaN.
|
||||
@ -614,7 +623,7 @@ Decimal objects
|
||||
Return :const:`True` if the argument is a signaling NaN and :const:`False`
|
||||
otherwise.
|
||||
|
||||
.. method:: is_subnormal()
|
||||
.. method:: is_subnormal(context=None)
|
||||
|
||||
Return :const:`True` if the argument is subnormal, and :const:`False`
|
||||
otherwise.
|
||||
@ -624,17 +633,17 @@ Decimal objects
|
||||
Return :const:`True` if the argument is a (positive or negative) zero and
|
||||
:const:`False` otherwise.
|
||||
|
||||
.. method:: ln([context])
|
||||
.. method:: ln(context=None)
|
||||
|
||||
Return the natural (base e) logarithm of the operand. The result is
|
||||
correctly rounded using the :const:`ROUND_HALF_EVEN` rounding mode.
|
||||
|
||||
.. method:: log10([context])
|
||||
.. method:: log10(context=None)
|
||||
|
||||
Return the base ten logarithm of the operand. The result is correctly
|
||||
rounded using the :const:`ROUND_HALF_EVEN` rounding mode.
|
||||
|
||||
.. method:: logb([context])
|
||||
.. method:: logb(context=None)
|
||||
|
||||
For a nonzero number, return the adjusted exponent of its operand as a
|
||||
:class:`Decimal` instance. If the operand is a zero then
|
||||
@ -642,73 +651,73 @@ Decimal objects
|
||||
is raised. If the operand is an infinity then ``Decimal('Infinity')`` is
|
||||
returned.
|
||||
|
||||
.. method:: logical_and(other[, context])
|
||||
.. method:: logical_and(other, context=None)
|
||||
|
||||
:meth:`logical_and` is a logical operation which takes two *logical
|
||||
operands* (see :ref:`logical_operands_label`). The result is the
|
||||
digit-wise ``and`` of the two operands.
|
||||
|
||||
.. method:: logical_invert([context])
|
||||
.. method:: logical_invert(context=None)
|
||||
|
||||
:meth:`logical_invert` is a logical operation. The
|
||||
result is the digit-wise inversion of the operand.
|
||||
|
||||
.. method:: logical_or(other[, context])
|
||||
.. method:: logical_or(other, context=None)
|
||||
|
||||
:meth:`logical_or` is a logical operation which takes two *logical
|
||||
operands* (see :ref:`logical_operands_label`). The result is the
|
||||
digit-wise ``or`` of the two operands.
|
||||
|
||||
.. method:: logical_xor(other[, context])
|
||||
.. method:: logical_xor(other, context=None)
|
||||
|
||||
:meth:`logical_xor` is a logical operation which takes two *logical
|
||||
operands* (see :ref:`logical_operands_label`). The result is the
|
||||
digit-wise exclusive or of the two operands.
|
||||
|
||||
.. method:: max(other[, context])
|
||||
.. method:: max(other, context=None)
|
||||
|
||||
Like ``max(self, other)`` except that the context rounding rule is applied
|
||||
before returning and that :const:`NaN` values are either signaled or
|
||||
ignored (depending on the context and whether they are signaling or
|
||||
quiet).
|
||||
|
||||
.. method:: max_mag(other[, context])
|
||||
.. method:: max_mag(other, context=None)
|
||||
|
||||
Similar to the :meth:`.max` method, but the comparison is done using the
|
||||
absolute values of the operands.
|
||||
|
||||
.. method:: min(other[, context])
|
||||
.. method:: min(other, context=None)
|
||||
|
||||
Like ``min(self, other)`` except that the context rounding rule is applied
|
||||
before returning and that :const:`NaN` values are either signaled or
|
||||
ignored (depending on the context and whether they are signaling or
|
||||
quiet).
|
||||
|
||||
.. method:: min_mag(other[, context])
|
||||
.. method:: min_mag(other, context=None)
|
||||
|
||||
Similar to the :meth:`.min` method, but the comparison is done using the
|
||||
absolute values of the operands.
|
||||
|
||||
.. method:: next_minus([context])
|
||||
.. method:: next_minus(context=None)
|
||||
|
||||
Return the largest number representable in the given context (or in the
|
||||
current thread's context if no context is given) that is smaller than the
|
||||
given operand.
|
||||
|
||||
.. method:: next_plus([context])
|
||||
.. method:: next_plus(context=None)
|
||||
|
||||
Return the smallest number representable in the given context (or in the
|
||||
current thread's context if no context is given) that is larger than the
|
||||
given operand.
|
||||
|
||||
.. method:: next_toward(other[, context])
|
||||
.. method:: next_toward(other, context=None)
|
||||
|
||||
If the two operands are unequal, return the number closest to the first
|
||||
operand in the direction of the second operand. If both operands are
|
||||
numerically equal, return a copy of the first operand with the sign set to
|
||||
be the same as the sign of the second operand.
|
||||
|
||||
.. method:: normalize([context])
|
||||
.. method:: normalize(context=None)
|
||||
|
||||
Normalize the number by stripping the rightmost trailing zeros and
|
||||
converting any result equal to :const:`Decimal('0')` to
|
||||
@ -717,7 +726,7 @@ Decimal objects
|
||||
``Decimal('0.321000e+2')`` both normalize to the equivalent value
|
||||
``Decimal('32.1')``.
|
||||
|
||||
.. method:: number_class([context])
|
||||
.. method:: number_class(context=None)
|
||||
|
||||
Return a string describing the *class* of the operand. The returned value
|
||||
is one of the following ten strings.
|
||||
@ -733,7 +742,7 @@ Decimal objects
|
||||
* ``"NaN"``, indicating that the operand is a quiet NaN (Not a Number).
|
||||
* ``"sNaN"``, indicating that the operand is a signaling NaN.
|
||||
|
||||
.. method:: quantize(exp[, rounding[, context[, watchexp]]])
|
||||
.. method:: quantize(exp, rounding=None, context=None, watchexp=True)
|
||||
|
||||
Return a value equal to the first operand after rounding and having the
|
||||
exponent of the second operand.
|
||||
@ -771,7 +780,7 @@ Decimal objects
|
||||
class does all its arithmetic. Included for compatibility with the
|
||||
specification.
|
||||
|
||||
.. method:: remainder_near(other[, context])
|
||||
.. method:: remainder_near(other, context=None)
|
||||
|
||||
Return the remainder from dividing *self* by *other*. This differs from
|
||||
``self % other`` in that the sign of the remainder is chosen so as to
|
||||
@ -789,7 +798,7 @@ Decimal objects
|
||||
>>> Decimal(35).remainder_near(Decimal(10))
|
||||
Decimal('-5')
|
||||
|
||||
.. method:: rotate(other[, context])
|
||||
.. method:: rotate(other, context=None)
|
||||
|
||||
Return the result of rotating the digits of the first operand by an amount
|
||||
specified by the second operand. The second operand must be an integer in
|
||||
@ -800,18 +809,22 @@ Decimal objects
|
||||
length precision if necessary. The sign and exponent of the first operand
|
||||
are unchanged.
|
||||
|
||||
.. method:: same_quantum(other[, context])
|
||||
.. method:: same_quantum(other, context=None)
|
||||
|
||||
Test whether self and other have the same exponent or whether both are
|
||||
:const:`NaN`.
|
||||
|
||||
.. method:: scaleb(other[, context])
|
||||
This operation is unaffected by context and is quiet: no flags are changed
|
||||
and no rounding is performed. As an exception, the C version may raise
|
||||
InvalidOperation if the second operand cannot be converted exactly.
|
||||
|
||||
.. method:: scaleb(other, context=None)
|
||||
|
||||
Return the first operand with exponent adjusted by the second.
|
||||
Equivalently, return the first operand multiplied by ``10**other``. The
|
||||
second operand must be an integer.
|
||||
|
||||
.. method:: shift(other[, context])
|
||||
.. method:: shift(other, context=None)
|
||||
|
||||
Return the result of shifting the digits of the first operand by an amount
|
||||
specified by the second operand. The second operand must be an integer in
|
||||
@ -821,12 +834,12 @@ Decimal objects
|
||||
right. Digits shifted into the coefficient are zeros. The sign and
|
||||
exponent of the first operand are unchanged.
|
||||
|
||||
.. method:: sqrt([context])
|
||||
.. method:: sqrt(context=None)
|
||||
|
||||
Return the square root of the argument to full precision.
|
||||
|
||||
|
||||
.. method:: to_eng_string([context])
|
||||
.. method:: to_eng_string(context=None)
|
||||
|
||||
Convert to an engineering-type string.
|
||||
|
||||
@ -834,12 +847,12 @@ Decimal objects
|
||||
are up to 3 digits left of the decimal place. For example, converts
|
||||
``Decimal('123E+1')`` to ``Decimal('1.23E+3')``
|
||||
|
||||
.. method:: to_integral([rounding[, context]])
|
||||
.. method:: to_integral(rounding=None, context=None)
|
||||
|
||||
Identical to the :meth:`to_integral_value` method. The ``to_integral``
|
||||
name has been kept for compatibility with older versions.
|
||||
|
||||
.. method:: to_integral_exact([rounding[, context]])
|
||||
.. method:: to_integral_exact(rounding=None, context=None)
|
||||
|
||||
Round to the nearest integer, signaling :const:`Inexact` or
|
||||
:const:`Rounded` as appropriate if rounding occurs. The rounding mode is
|
||||
@ -847,7 +860,7 @@ Decimal objects
|
||||
``context``. If neither parameter is given then the rounding mode of the
|
||||
current context is used.
|
||||
|
||||
.. method:: to_integral_value([rounding[, context]])
|
||||
.. method:: to_integral_value(rounding=None, context=None)
|
||||
|
||||
Round to the nearest integer without signaling :const:`Inexact` or
|
||||
:const:`Rounded`. If given, applies *rounding*; otherwise, uses the
|
||||
@ -893,10 +906,10 @@ Each thread has its own current context which is accessed or changed using the
|
||||
You can also use the :keyword:`with` statement and the :func:`localcontext`
|
||||
function to temporarily change the active context.
|
||||
|
||||
.. function:: localcontext([c])
|
||||
.. function:: localcontext(ctx=None)
|
||||
|
||||
Return a context manager that will set the current context for the active thread
|
||||
to a copy of *c* on entry to the with-statement and restore the previous context
|
||||
to a copy of *ctx* on entry to the with-statement and restore the previous context
|
||||
when exiting the with-statement. If no context is specified, a copy of the
|
||||
current context is used.
|
||||
|
||||
@ -1315,7 +1328,7 @@ In addition to the three supplied contexts, new contexts can be created with the
|
||||
identity operation.
|
||||
|
||||
|
||||
.. method:: power(x, y[, modulo])
|
||||
.. method:: power(x, y, modulo=None)
|
||||
|
||||
Return ``x`` to the power of ``y``, reduced modulo ``modulo`` if given.
|
||||
|
||||
|
@ -2596,7 +2596,7 @@ class Decimal(object):
|
||||
ans = ans._fix(context)
|
||||
return ans
|
||||
|
||||
def same_quantum(self, other):
|
||||
def same_quantum(self, other, context=None):
|
||||
"""Return True if self and other have the same exponent; otherwise
|
||||
return False.
|
||||
|
||||
@ -2914,7 +2914,7 @@ class Decimal(object):
|
||||
except TypeError:
|
||||
return 0
|
||||
|
||||
def canonical(self, context=None):
|
||||
def canonical(self):
|
||||
"""Returns the same Decimal object.
|
||||
|
||||
As we do not have different encodings for the same number, the
|
||||
@ -2934,7 +2934,7 @@ class Decimal(object):
|
||||
return ans
|
||||
return self.compare(other, context=context)
|
||||
|
||||
def compare_total(self, other):
|
||||
def compare_total(self, other, context=None):
|
||||
"""Compares self to other using the abstract representations.
|
||||
|
||||
This is not like the standard compare, which use their numerical
|
||||
@ -3007,7 +3007,7 @@ class Decimal(object):
|
||||
return _Zero
|
||||
|
||||
|
||||
def compare_total_mag(self, other):
|
||||
def compare_total_mag(self, other, context=None):
|
||||
"""Compares self to other using abstract repr., ignoring sign.
|
||||
|
||||
Like compare_total, but with operand's sign ignored and assumed to be 0.
|
||||
@ -3029,7 +3029,7 @@ class Decimal(object):
|
||||
else:
|
||||
return _dec_from_triple(1, self._int, self._exp, self._is_special)
|
||||
|
||||
def copy_sign(self, other):
|
||||
def copy_sign(self, other, context=None):
|
||||
"""Returns self with the sign of other."""
|
||||
other = _convert_other(other, raiseit=True)
|
||||
return _dec_from_triple(other._sign, self._int,
|
||||
@ -4182,7 +4182,7 @@ class Context(object):
|
||||
"""
|
||||
if not isinstance(a, Decimal):
|
||||
raise TypeError("canonical requires a Decimal as an argument.")
|
||||
return a.canonical(context=self)
|
||||
return a.canonical()
|
||||
|
||||
def compare(self, a, b):
|
||||
"""Compares values numerically.
|
||||
|
@ -2089,6 +2089,248 @@ class UsabilityTest(unittest.TestCase):
|
||||
self.assertEqual(str(Decimal(0).sqrt()),
|
||||
str(c.sqrt(Decimal(0))))
|
||||
|
||||
def test_none_args(self):
|
||||
Decimal = self.decimal.Decimal
|
||||
Context = self.decimal.Context
|
||||
localcontext = self.decimal.localcontext
|
||||
InvalidOperation = self.decimal.InvalidOperation
|
||||
DivisionByZero = self.decimal.DivisionByZero
|
||||
Overflow = self.decimal.Overflow
|
||||
Underflow = self.decimal.Underflow
|
||||
Subnormal = self.decimal.Subnormal
|
||||
Inexact = self.decimal.Inexact
|
||||
Rounded = self.decimal.Rounded
|
||||
Clamped = self.decimal.Clamped
|
||||
ROUND_HALF_EVEN = self.decimal.ROUND_HALF_EVEN
|
||||
ROUND_DOWN = self.decimal.ROUND_DOWN
|
||||
ROUND_UP = self.decimal.ROUND_UP
|
||||
|
||||
with localcontext(Context()) as c:
|
||||
c.prec = 7
|
||||
c.Emax = 999
|
||||
c.Emin = -999
|
||||
|
||||
x = Decimal("111")
|
||||
y = Decimal("1e9999")
|
||||
z = Decimal("1e-9999")
|
||||
|
||||
##### Unary functions
|
||||
c.clear_flags()
|
||||
self.assertEqual(str(x.exp(context=None)), '1.609487E+48')
|
||||
self.assertTrue(c.flags[Inexact])
|
||||
self.assertTrue(c.flags[Rounded])
|
||||
c.clear_flags()
|
||||
self.assertRaises(Overflow, y.exp, context=None)
|
||||
self.assertTrue(c.flags[Overflow])
|
||||
|
||||
self.assertIs(z.is_normal(context=None), False)
|
||||
self.assertIs(z.is_subnormal(context=None), True)
|
||||
|
||||
c.clear_flags()
|
||||
self.assertEqual(str(x.ln(context=None)), '4.709530')
|
||||
self.assertTrue(c.flags[Inexact])
|
||||
self.assertTrue(c.flags[Rounded])
|
||||
c.clear_flags()
|
||||
self.assertRaises(InvalidOperation, Decimal(-1).ln, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
self.assertEqual(str(x.log10(context=None)), '2.045323')
|
||||
self.assertTrue(c.flags[Inexact])
|
||||
self.assertTrue(c.flags[Rounded])
|
||||
c.clear_flags()
|
||||
self.assertRaises(InvalidOperation, Decimal(-1).log10, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
self.assertEqual(str(x.logb(context=None)), '2')
|
||||
self.assertRaises(DivisionByZero, Decimal(0).logb, context=None)
|
||||
self.assertTrue(c.flags[DivisionByZero])
|
||||
|
||||
c.clear_flags()
|
||||
self.assertEqual(str(x.logical_invert(context=None)), '1111000')
|
||||
self.assertRaises(InvalidOperation, y.logical_invert, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
self.assertEqual(str(y.next_minus(context=None)), '9.999999E+999')
|
||||
self.assertRaises(InvalidOperation, Decimal('sNaN').next_minus, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
self.assertEqual(str(y.next_plus(context=None)), 'Infinity')
|
||||
self.assertRaises(InvalidOperation, Decimal('sNaN').next_plus, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
self.assertEqual(str(z.normalize(context=None)), '0')
|
||||
self.assertRaises(Overflow, y.normalize, context=None)
|
||||
self.assertTrue(c.flags[Overflow])
|
||||
|
||||
self.assertEqual(str(z.number_class(context=None)), '+Subnormal')
|
||||
|
||||
c.clear_flags()
|
||||
self.assertEqual(str(z.sqrt(context=None)), '0E-1005')
|
||||
self.assertTrue(c.flags[Clamped])
|
||||
self.assertTrue(c.flags[Inexact])
|
||||
self.assertTrue(c.flags[Rounded])
|
||||
self.assertTrue(c.flags[Subnormal])
|
||||
self.assertTrue(c.flags[Underflow])
|
||||
c.clear_flags()
|
||||
self.assertRaises(Overflow, y.sqrt, context=None)
|
||||
self.assertTrue(c.flags[Overflow])
|
||||
|
||||
c.capitals = 0
|
||||
self.assertEqual(str(z.to_eng_string(context=None)), '1e-9999')
|
||||
c.capitals = 1
|
||||
|
||||
|
||||
##### Binary functions
|
||||
c.clear_flags()
|
||||
ans = str(x.compare(Decimal('Nan891287828'), context=None))
|
||||
self.assertEqual(ans, 'NaN1287828')
|
||||
self.assertRaises(InvalidOperation, x.compare, Decimal('sNaN'), context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.compare_signal(8224, context=None))
|
||||
self.assertEqual(ans, '-1')
|
||||
self.assertRaises(InvalidOperation, x.compare_signal, Decimal('NaN'), context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.logical_and(101, context=None))
|
||||
self.assertEqual(ans, '101')
|
||||
self.assertRaises(InvalidOperation, x.logical_and, 123, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.logical_or(101, context=None))
|
||||
self.assertEqual(ans, '111')
|
||||
self.assertRaises(InvalidOperation, x.logical_or, 123, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.logical_xor(101, context=None))
|
||||
self.assertEqual(ans, '10')
|
||||
self.assertRaises(InvalidOperation, x.logical_xor, 123, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.max(101, context=None))
|
||||
self.assertEqual(ans, '111')
|
||||
self.assertRaises(InvalidOperation, x.max, Decimal('sNaN'), context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.max_mag(101, context=None))
|
||||
self.assertEqual(ans, '111')
|
||||
self.assertRaises(InvalidOperation, x.max_mag, Decimal('sNaN'), context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.min(101, context=None))
|
||||
self.assertEqual(ans, '101')
|
||||
self.assertRaises(InvalidOperation, x.min, Decimal('sNaN'), context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.min_mag(101, context=None))
|
||||
self.assertEqual(ans, '101')
|
||||
self.assertRaises(InvalidOperation, x.min_mag, Decimal('sNaN'), context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.remainder_near(101, context=None))
|
||||
self.assertEqual(ans, '10')
|
||||
self.assertRaises(InvalidOperation, y.remainder_near, 101, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.rotate(2, context=None))
|
||||
self.assertEqual(ans, '11100')
|
||||
self.assertRaises(InvalidOperation, x.rotate, 101, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.scaleb(7, context=None))
|
||||
self.assertEqual(ans, '1.11E+9')
|
||||
self.assertRaises(InvalidOperation, x.scaleb, 10000, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.clear_flags()
|
||||
ans = str(x.shift(2, context=None))
|
||||
self.assertEqual(ans, '11100')
|
||||
self.assertRaises(InvalidOperation, x.shift, 10000, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
|
||||
##### Ternary functions
|
||||
c.clear_flags()
|
||||
ans = str(x.fma(2, 3, context=None))
|
||||
self.assertEqual(ans, '225')
|
||||
self.assertRaises(Overflow, x.fma, Decimal('1e9999'), 3, context=None)
|
||||
self.assertTrue(c.flags[Overflow])
|
||||
|
||||
|
||||
##### Special cases
|
||||
c.rounding = ROUND_HALF_EVEN
|
||||
ans = str(Decimal('1.5').to_integral(rounding=None, context=None))
|
||||
self.assertEqual(ans, '2')
|
||||
c.rounding = ROUND_DOWN
|
||||
ans = str(Decimal('1.5').to_integral(rounding=None, context=None))
|
||||
self.assertEqual(ans, '1')
|
||||
ans = str(Decimal('1.5').to_integral(rounding=ROUND_UP, context=None))
|
||||
self.assertEqual(ans, '2')
|
||||
c.clear_flags()
|
||||
self.assertRaises(InvalidOperation, Decimal('sNaN').to_integral, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.rounding = ROUND_HALF_EVEN
|
||||
ans = str(Decimal('1.5').to_integral_value(rounding=None, context=None))
|
||||
self.assertEqual(ans, '2')
|
||||
c.rounding = ROUND_DOWN
|
||||
ans = str(Decimal('1.5').to_integral_value(rounding=None, context=None))
|
||||
self.assertEqual(ans, '1')
|
||||
ans = str(Decimal('1.5').to_integral_value(rounding=ROUND_UP, context=None))
|
||||
self.assertEqual(ans, '2')
|
||||
c.clear_flags()
|
||||
self.assertRaises(InvalidOperation, Decimal('sNaN').to_integral_value, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.rounding = ROUND_HALF_EVEN
|
||||
ans = str(Decimal('1.5').to_integral_exact(rounding=None, context=None))
|
||||
self.assertEqual(ans, '2')
|
||||
c.rounding = ROUND_DOWN
|
||||
ans = str(Decimal('1.5').to_integral_exact(rounding=None, context=None))
|
||||
self.assertEqual(ans, '1')
|
||||
ans = str(Decimal('1.5').to_integral_exact(rounding=ROUND_UP, context=None))
|
||||
self.assertEqual(ans, '2')
|
||||
c.clear_flags()
|
||||
self.assertRaises(InvalidOperation, Decimal('sNaN').to_integral_exact, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
c.rounding = ROUND_UP
|
||||
ans = str(Decimal('1.50001').quantize(exp=Decimal('1e-3'), rounding=None, context=None))
|
||||
self.assertEqual(ans, '1.501')
|
||||
c.rounding = ROUND_DOWN
|
||||
ans = str(Decimal('1.50001').quantize(exp=Decimal('1e-3'), rounding=None, context=None))
|
||||
self.assertEqual(ans, '1.500')
|
||||
ans = str(Decimal('1.50001').quantize(exp=Decimal('1e-3'), rounding=ROUND_UP, context=None))
|
||||
self.assertEqual(ans, '1.501')
|
||||
c.clear_flags()
|
||||
self.assertRaises(InvalidOperation, y.quantize, Decimal('1e-10'), rounding=ROUND_UP, context=None)
|
||||
self.assertTrue(c.flags[InvalidOperation])
|
||||
|
||||
with localcontext(Context()) as context:
|
||||
context.prec = 7
|
||||
context.Emax = 999
|
||||
context.Emin = -999
|
||||
with localcontext(ctx=None) as c:
|
||||
self.assertEqual(c.prec, 7)
|
||||
self.assertEqual(c.Emax, 999)
|
||||
self.assertEqual(c.Emin, -999)
|
||||
|
||||
def test_conversions_from_int(self):
|
||||
# Check that methods taking a second Decimal argument will
|
||||
# always accept an integer in place of a Decimal.
|
||||
@ -2423,14 +2665,11 @@ class PythonAPItests(unittest.TestCase):
|
||||
self.assertRaises(TypeError, D.from_float, 1.1, context=xc)
|
||||
self.assertRaises(TypeError, D(0).as_tuple, context=xc)
|
||||
|
||||
if (self.decimal == C):
|
||||
self.assertRaises(TypeError, D(1).canonical, context=xc)
|
||||
self.assertEqual(D("-1").copy_abs(context=xc), 1)
|
||||
self.assertEqual(D("1").copy_negate(context=xc), -1)
|
||||
else:
|
||||
self.assertEqual(D(1).canonical(context=xc), 1)
|
||||
self.assertRaises(TypeError, D("-1").copy_abs, context=xc)
|
||||
self.assertRaises(TypeError, D("-1").copy_negate, context=xc)
|
||||
self.assertEqual(D(1).canonical(), 1)
|
||||
self.assertRaises(TypeError, D("-1").copy_abs, context=xc)
|
||||
self.assertRaises(TypeError, D("-1").copy_negate, context=xc)
|
||||
self.assertRaises(TypeError, D(1).canonical, context="x")
|
||||
self.assertRaises(TypeError, D(1).canonical, xyz="x")
|
||||
|
||||
def test_exception_hierarchy(self):
|
||||
|
||||
@ -4593,6 +4832,9 @@ class CWhitebox(unittest.TestCase):
|
||||
# Invalid local context
|
||||
self.assertRaises(TypeError, exec, 'with localcontext("xyz"): pass',
|
||||
locals())
|
||||
self.assertRaises(TypeError, exec,
|
||||
'with localcontext(context=getcontext()): pass',
|
||||
locals())
|
||||
|
||||
# setcontext
|
||||
saved_context = getcontext()
|
||||
@ -4826,6 +5068,50 @@ class CWhitebox(unittest.TestCase):
|
||||
c.prec = 2
|
||||
self.assertRaises(InvalidOperation, pow, Decimal(1000), 1, 501)
|
||||
|
||||
def test_va_args_exceptions(self):
|
||||
Decimal = C.Decimal
|
||||
Context = C.Context
|
||||
|
||||
x = Decimal("10001111111")
|
||||
|
||||
for attr in ['exp', 'is_normal', 'is_subnormal', 'ln', 'log10',
|
||||
'logb', 'logical_invert', 'next_minus', 'next_plus',
|
||||
'normalize', 'number_class', 'sqrt', 'to_eng_string']:
|
||||
func = getattr(x, attr)
|
||||
self.assertRaises(TypeError, func, context="x")
|
||||
self.assertRaises(TypeError, func, "x", context=None)
|
||||
|
||||
for attr in ['compare', 'compare_signal', 'logical_and',
|
||||
'logical_or', 'max', 'max_mag', 'min', 'min_mag',
|
||||
'remainder_near', 'rotate', 'scaleb', 'shift']:
|
||||
func = getattr(x, attr)
|
||||
self.assertRaises(TypeError, func, context="x")
|
||||
self.assertRaises(TypeError, func, "x", context=None)
|
||||
|
||||
self.assertRaises(TypeError, x.to_integral, rounding=None, context=[])
|
||||
self.assertRaises(TypeError, x.to_integral, rounding={}, context=[])
|
||||
self.assertRaises(TypeError, x.to_integral, [], [])
|
||||
|
||||
self.assertRaises(TypeError, x.to_integral_value, rounding=None, context=[])
|
||||
self.assertRaises(TypeError, x.to_integral_value, rounding={}, context=[])
|
||||
self.assertRaises(TypeError, x.to_integral_value, [], [])
|
||||
|
||||
self.assertRaises(TypeError, x.to_integral_exact, rounding=None, context=[])
|
||||
self.assertRaises(TypeError, x.to_integral_exact, rounding={}, context=[])
|
||||
self.assertRaises(TypeError, x.to_integral_exact, [], [])
|
||||
|
||||
self.assertRaises(TypeError, x.fma, 1, 2, context="x")
|
||||
self.assertRaises(TypeError, x.fma, 1, 2, "x", context=None)
|
||||
|
||||
self.assertRaises(TypeError, x.quantize, 1, [], context=None)
|
||||
self.assertRaises(TypeError, x.quantize, 1, [], rounding=None)
|
||||
self.assertRaises(TypeError, x.quantize, 1, [], [])
|
||||
|
||||
c = Context()
|
||||
self.assertRaises(TypeError, c.power, 1, 2, mod="x")
|
||||
self.assertRaises(TypeError, c.power, 1, "x", mod=None)
|
||||
self.assertRaises(TypeError, c.power, "x", 2, mod=None)
|
||||
|
||||
@requires_extra_functionality
|
||||
def test_c_context_templates(self):
|
||||
self.assertEqual(
|
||||
|
@ -108,6 +108,10 @@ Core and Builtins
|
||||
Library
|
||||
-------
|
||||
|
||||
- Issue #15783: Except for the number methods, the C version of decimal now
|
||||
supports all None default values present in decimal.py. These values were
|
||||
largely undocumented.
|
||||
|
||||
- Issue #16298: In HTTPResponse.read(), close the socket when there is no
|
||||
Content-Length and the incoming stream is finished. Patch by Eran
|
||||
Rundstein.
|
||||
|
@ -1486,7 +1486,10 @@ static PyGetSetDef context_getsets [] =
|
||||
}
|
||||
|
||||
#define CONTEXT_CHECK_VA(obj) \
|
||||
if (!PyDecContext_Check(obj)) { \
|
||||
if (obj == Py_None) { \
|
||||
CURRENT_CONTEXT(obj); \
|
||||
} \
|
||||
else if (!PyDecContext_Check(obj)) { \
|
||||
PyErr_SetString(PyExc_TypeError, \
|
||||
"optional argument must be a context"); \
|
||||
return NULL; \
|
||||
@ -1715,18 +1718,25 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
|
||||
* owns one reference to the global (outer) context and one
|
||||
* to the local (inner) context. */
|
||||
static PyObject *
|
||||
ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args)
|
||||
ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"ctx", NULL};
|
||||
PyDecContextManagerObject *self;
|
||||
PyObject *local;
|
||||
PyObject *local = Py_None;
|
||||
PyObject *global;
|
||||
|
||||
CURRENT_CONTEXT(global);
|
||||
local = global;
|
||||
if (!PyArg_ParseTuple(args, "|O", &local)) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &local)) {
|
||||
return NULL;
|
||||
}
|
||||
if (local == Py_None) {
|
||||
local = global;
|
||||
}
|
||||
else if (!PyDecContext_Check(local)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"optional argument must be a context");
|
||||
return NULL;
|
||||
}
|
||||
CONTEXT_CHECK_VA(local);
|
||||
|
||||
self = PyObject_New(PyDecContextManagerObject,
|
||||
&PyDecContextManager_Type);
|
||||
@ -2749,9 +2759,8 @@ dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"value", "context", NULL};
|
||||
PyObject *v = NULL;
|
||||
PyObject *context;
|
||||
PyObject *context = Py_None;
|
||||
|
||||
CURRENT_CONTEXT(context);
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
|
||||
&v, &context)) {
|
||||
return NULL;
|
||||
@ -3315,20 +3324,23 @@ PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"rounding", "context", NULL};
|
||||
PyObject *result;
|
||||
PyObject *context;
|
||||
PyObject *rounding = Py_None;
|
||||
PyObject *context = Py_None;
|
||||
uint32_t status = 0;
|
||||
mpd_context_t workctx;
|
||||
int round = -1;
|
||||
|
||||
CURRENT_CONTEXT(context);
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist,
|
||||
&round, &context)) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
|
||||
&rounding, &context)) {
|
||||
return NULL;
|
||||
}
|
||||
CONTEXT_CHECK_VA(context);
|
||||
|
||||
workctx = *CTX(context);
|
||||
if (round >= 0) {
|
||||
if (rounding != Py_None) {
|
||||
int round = getround(rounding);
|
||||
if (round < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (!mpd_qsetround(&workctx, round)) {
|
||||
return type_error_ptr(invalid_rounding_err);
|
||||
}
|
||||
@ -3353,20 +3365,23 @@ PyDec_ToIntegralExact(PyObject *dec, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"rounding", "context", NULL};
|
||||
PyObject *result;
|
||||
PyObject *context;
|
||||
PyObject *rounding = Py_None;
|
||||
PyObject *context = Py_None;
|
||||
uint32_t status = 0;
|
||||
mpd_context_t workctx;
|
||||
int round = -1;
|
||||
|
||||
CURRENT_CONTEXT(context);
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist,
|
||||
&round, &context)) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
|
||||
&rounding, &context)) {
|
||||
return NULL;
|
||||
}
|
||||
CONTEXT_CHECK_VA(context);
|
||||
|
||||
workctx = *CTX(context);
|
||||
if (round >= 0) {
|
||||
if (rounding != Py_None) {
|
||||
int round = getround(rounding);
|
||||
if (round < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (!mpd_qsetround(&workctx, round)) {
|
||||
return type_error_ptr(invalid_rounding_err);
|
||||
}
|
||||
@ -3633,9 +3648,8 @@ static PyObject * \
|
||||
dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
|
||||
{ \
|
||||
static char *kwlist[] = {"context", NULL}; \
|
||||
PyObject *context; \
|
||||
PyObject *context = Py_None; \
|
||||
\
|
||||
CURRENT_CONTEXT(context); \
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
|
||||
&context)) { \
|
||||
return NULL; \
|
||||
@ -3652,10 +3666,9 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
|
||||
{ \
|
||||
static char *kwlist[] = {"context", NULL}; \
|
||||
PyObject *result; \
|
||||
PyObject *context; \
|
||||
PyObject *context = Py_None; \
|
||||
uint32_t status = 0; \
|
||||
\
|
||||
CURRENT_CONTEXT(context); \
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
|
||||
&context)) { \
|
||||
return NULL; \
|
||||
@ -3675,49 +3688,18 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
|
||||
return result; \
|
||||
}
|
||||
|
||||
/* Unary function with an optional context arg. The actual MPDFUNC
|
||||
only takes a status parameter. */
|
||||
#define Dec_UnaryFuncVA_NO_CTX(MPDFUNC) \
|
||||
static PyObject * \
|
||||
dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
|
||||
{ \
|
||||
static char *kwlist[] = {"context", NULL}; \
|
||||
PyObject *result; \
|
||||
PyObject *context; \
|
||||
uint32_t status = 0; \
|
||||
\
|
||||
CURRENT_CONTEXT(context); \
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
|
||||
&context)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
CONTEXT_CHECK_VA(context); \
|
||||
\
|
||||
if ((result = dec_alloc()) == NULL) { \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
MPDFUNC(MPD(result), MPD(self), &status); \
|
||||
if (dec_addstatus(context, status)) { \
|
||||
Py_DECREF(result); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
return result; \
|
||||
}
|
||||
|
||||
/* Binary function with an optional context arg. */
|
||||
#define Dec_BinaryFuncVA(MPDFUNC) \
|
||||
static PyObject * \
|
||||
dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
|
||||
{ \
|
||||
static char *kwlist[] = {"other", "context", NULL}; \
|
||||
PyObject *other, *context; \
|
||||
PyObject *other; \
|
||||
PyObject *a, *b; \
|
||||
PyObject *result; \
|
||||
PyObject *context = Py_None; \
|
||||
uint32_t status = 0; \
|
||||
\
|
||||
CURRENT_CONTEXT(context); \
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \
|
||||
&other, &context)) { \
|
||||
return NULL; \
|
||||
@ -3750,11 +3732,11 @@ static PyObject * \
|
||||
dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
|
||||
{ \
|
||||
static char *kwlist[] = {"other", "context", NULL}; \
|
||||
PyObject *other, *context; \
|
||||
PyObject *context = Py_None; \
|
||||
PyObject *other; \
|
||||
PyObject *a, *b; \
|
||||
PyObject *result; \
|
||||
\
|
||||
CURRENT_CONTEXT(context); \
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \
|
||||
&other, &context)) { \
|
||||
return NULL; \
|
||||
@ -3781,12 +3763,12 @@ static PyObject * \
|
||||
dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
|
||||
{ \
|
||||
static char *kwlist[] = {"other", "third", "context", NULL}; \
|
||||
PyObject *other, *third, *context; \
|
||||
PyObject *other, *third; \
|
||||
PyObject *a, *b, *c; \
|
||||
PyObject *result; \
|
||||
PyObject *context = Py_None; \
|
||||
uint32_t status = 0; \
|
||||
\
|
||||
CURRENT_CONTEXT(context); \
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist, \
|
||||
&other, &third, &context)) { \
|
||||
return NULL; \
|
||||
@ -4019,9 +4001,45 @@ dec_mpd_radix(PyObject *self UNUSED, PyObject *dummy UNUSED)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Unary functions, optional context arg for conversion errors */
|
||||
Dec_UnaryFuncVA_NO_CTX(mpd_qcopy_abs)
|
||||
Dec_UnaryFuncVA_NO_CTX(mpd_qcopy_negate)
|
||||
static PyObject *
|
||||
dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy UNUSED)
|
||||
{
|
||||
PyObject *result;
|
||||
uint32_t status = 0;
|
||||
|
||||
if ((result = dec_alloc()) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mpd_qcopy_abs(MPD(result), MPD(self), &status);
|
||||
if (status & MPD_Malloc_error) {
|
||||
Py_DECREF(result);
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
dec_mpd_qcopy_negate(PyObject *self, PyObject *dummy UNUSED)
|
||||
{
|
||||
PyObject *result;
|
||||
uint32_t status = 0;
|
||||
|
||||
if ((result = dec_alloc()) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mpd_qcopy_negate(MPD(result), MPD(self), &status);
|
||||
if (status & MPD_Malloc_error) {
|
||||
Py_DECREF(result);
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Unary functions, optional context arg */
|
||||
Dec_UnaryFuncVA(mpd_qinvert)
|
||||
@ -4031,10 +4049,9 @@ static PyObject *
|
||||
dec_mpd_class(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"context", NULL};
|
||||
PyObject *context;
|
||||
PyObject *context = Py_None;
|
||||
const char *cp;
|
||||
|
||||
CURRENT_CONTEXT(context);
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,
|
||||
&context)) {
|
||||
return NULL;
|
||||
@ -4050,11 +4067,10 @@ dec_mpd_to_eng(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"context", NULL};
|
||||
PyObject *result;
|
||||
PyObject *context;
|
||||
PyObject *context = Py_None;
|
||||
mpd_ssize_t size;
|
||||
char *s;
|
||||
|
||||
CURRENT_CONTEXT(context);
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,
|
||||
&context)) {
|
||||
return NULL;
|
||||
@ -4081,12 +4097,12 @@ static PyObject *
|
||||
dec_mpd_qcopy_sign(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"other", "context", NULL};
|
||||
PyObject *other, *context;
|
||||
PyObject *other;
|
||||
PyObject *a, *b;
|
||||
PyObject *result;
|
||||
PyObject *context = Py_None;
|
||||
uint32_t status = 0;
|
||||
|
||||
CURRENT_CONTEXT(context);
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
|
||||
&other, &context)) {
|
||||
return NULL;
|
||||
@ -4116,11 +4132,11 @@ static PyObject *
|
||||
dec_mpd_same_quantum(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"other", "context", NULL};
|
||||
PyObject *other, *context;
|
||||
PyObject *other;
|
||||
PyObject *a, *b;
|
||||
PyObject *result;
|
||||
PyObject *context = Py_None;
|
||||
|
||||
CURRENT_CONTEXT(context);
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
|
||||
&other, &context)) {
|
||||
return NULL;
|
||||
@ -4148,22 +4164,25 @@ static PyObject *
|
||||
dec_mpd_qquantize(PyObject *v, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"exp", "rounding", "context", NULL};
|
||||
PyObject *w, *context;
|
||||
PyObject *a, *b;
|
||||
PyObject *rounding = Py_None;
|
||||
PyObject *context = Py_None;
|
||||
PyObject *w, *a, *b;
|
||||
PyObject *result;
|
||||
uint32_t status = 0;
|
||||
mpd_context_t workctx;
|
||||
int round = -1;
|
||||
|
||||
CURRENT_CONTEXT(context);
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iO", kwlist,
|
||||
&w, &round, &context)) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist,
|
||||
&w, &rounding, &context)) {
|
||||
return NULL;
|
||||
}
|
||||
CONTEXT_CHECK_VA(context);
|
||||
|
||||
workctx = *CTX(context);
|
||||
if (round >= 0) {
|
||||
if (rounding != Py_None) {
|
||||
int round = getround(rounding);
|
||||
if (round < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (!mpd_qsetround(&workctx, round)) {
|
||||
return type_error_ptr(invalid_rounding_err);
|
||||
}
|
||||
@ -4585,8 +4604,8 @@ static PyMethodDef dec_methods [] =
|
||||
{ "radix", dec_mpd_radix, METH_NOARGS, doc_radix },
|
||||
|
||||
/* Unary functions, optional context arg for conversion errors */
|
||||
{ "copy_abs", (PyCFunction)dec_mpd_qcopy_abs, METH_VARARGS|METH_KEYWORDS, doc_copy_abs },
|
||||
{ "copy_negate", (PyCFunction)dec_mpd_qcopy_negate, METH_VARARGS|METH_KEYWORDS, doc_copy_negate },
|
||||
{ "copy_abs", dec_mpd_qcopy_abs, METH_NOARGS, doc_copy_abs },
|
||||
{ "copy_negate", dec_mpd_qcopy_negate, METH_NOARGS, doc_copy_negate },
|
||||
|
||||
/* Unary functions, optional context arg */
|
||||
{ "logb", (PyCFunction)dec_mpd_qlogb, METH_VARARGS|METH_KEYWORDS, doc_logb },
|
||||
@ -4916,7 +4935,7 @@ static PyObject *
|
||||
ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"a", "b", "modulo", NULL};
|
||||
PyObject *base, *exp, *mod = NULL;
|
||||
PyObject *base, *exp, *mod = Py_None;
|
||||
PyObject *a, *b, *c = NULL;
|
||||
PyObject *result;
|
||||
uint32_t status = 0;
|
||||
@ -4928,7 +4947,7 @@ ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds)
|
||||
|
||||
CONVERT_BINOP_RAISE(&a, &b, base, exp, context);
|
||||
|
||||
if (mod != NULL) {
|
||||
if (mod != Py_None) {
|
||||
if (!convert_op(TYPE_ERR, &c, mod, context)) {
|
||||
Py_DECREF(a);
|
||||
Py_DECREF(b);
|
||||
@ -5361,7 +5380,7 @@ static PyMethodDef _decimal_methods [] =
|
||||
{
|
||||
{ "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext},
|
||||
{ "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext},
|
||||
{ "localcontext", (PyCFunction)ctxmanager_new, METH_VARARGS, doc_localcontext},
|
||||
{ "localcontext", (PyCFunction)ctxmanager_new, METH_VARARGS|METH_KEYWORDS, doc_localcontext},
|
||||
#ifdef EXTRA_FUNCTIONALITY
|
||||
{ "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context},
|
||||
#endif
|
||||
|
@ -28,10 +28,10 @@ setcontext(c) - Set a new default context.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_localcontext,"\n\
|
||||
localcontext(c) - Return a context manager that will set the default context\n\
|
||||
to a copy of c on entry to the with-statement and restore the previous default\n\
|
||||
context when exiting the with-statement. If no context is specified, a copy of\n\
|
||||
the current default context is used.\n\
|
||||
localcontext(ctx=None) - Return a context manager that will set the default\n\
|
||||
context to a copy of ctx on entry to the with-statement and restore the\n\
|
||||
previous default context when exiting the with-statement. If no context is\n\
|
||||
specified, a copy of the current default context is used.\n\
|
||||
\n");
|
||||
|
||||
#ifdef EXTRA_FUNCTIONALITY
|
||||
@ -49,8 +49,7 @@ DECIMAL32, DECIMAL64 and DECIMAL128 are provided.\n\
|
||||
/******************************************************************************/
|
||||
|
||||
PyDoc_STRVAR(doc_decimal,"\n\
|
||||
Decimal([value[, context]]): Construct a new Decimal object from value.\n\
|
||||
\n\
|
||||
Decimal(value=\"0\", context=None): Construct a new Decimal object.\n\
|
||||
value can be an integer, string, tuple, or another Decimal object.\n\
|
||||
If no value is given, return Decimal('0'). The context does not affect\n\
|
||||
the conversion and is only passed to determine if the InvalidOperation\n\
|
||||
@ -74,7 +73,7 @@ returns its argument unchanged.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_compare,"\n\
|
||||
compare(other[, context]) - Compare self to other. Return a decimal value:\n\
|
||||
compare(other, context=None) - Compare self to other. Return a decimal value:\n\
|
||||
\n\
|
||||
a or b is a NaN ==> Decimal('NaN')\n\
|
||||
a < b ==> Decimal('-1')\n\
|
||||
@ -83,16 +82,16 @@ compare(other[, context]) - Compare self to other. Return a decimal value:\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_compare_signal,"\n\
|
||||
compare_signal(other[, context]) - Identical to compare, except that\n\
|
||||
compare_signal(other, context=None) - Identical to compare, except that\n\
|
||||
all NaNs signal.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_compare_total,"\n\
|
||||
compare_total(other) - Compare two operands using their abstract representation\n\
|
||||
rather than their numerical value. Similar to the compare() method, but the\n\
|
||||
result gives a total ordering on Decimal instances. Two Decimal instances with\n\
|
||||
the same numeric value but different representations compare unequal in this\n\
|
||||
ordering:\n\
|
||||
compare_total(other, context=None) - Compare two operands using their\n\
|
||||
abstract representation rather than their numerical value. Similar to the\n\
|
||||
compare() method, but the result gives a total ordering on Decimal instances.\n\
|
||||
Two Decimal instances with the same numeric value but different representations\n\
|
||||
compare unequal in this ordering:\n\
|
||||
\n\
|
||||
>>> Decimal('12.0').compare_total(Decimal('12'))\n\
|
||||
Decimal('-1')\n\
|
||||
@ -102,13 +101,21 @@ of this function is Decimal('0') if both operands have the same representation,\
|
||||
Decimal('-1') if the first operand is lower in the total order than the second,\n\
|
||||
and Decimal('1') if the first operand is higher in the total order than the\n\
|
||||
second operand. See the specification for details of the total order.\n\
|
||||
\n\
|
||||
This operation is unaffected by context and is quiet: no flags are changed\n\
|
||||
and no rounding is performed. As an exception, the C version may raise\n\
|
||||
InvalidOperation if the second operand cannot be converted exactly.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_compare_total_mag,"\n\
|
||||
compare_total_mag(other) - Compare two operands using their abstract\n\
|
||||
representation rather than their value as in compare_total(), but\n\
|
||||
ignoring the sign of each operand. x.compare_total_mag(y) is\n\
|
||||
equivalent to x.copy_abs().compare_total(y.copy_abs()).\n\
|
||||
compare_total_mag(other, context=None) - Compare two operands using their\n\
|
||||
abstract representation rather than their value as in compare_total(), but\n\
|
||||
ignoring the sign of each operand. x.compare_total_mag(y) is equivalent to\n\
|
||||
x.copy_abs().compare_total(y.copy_abs()).\n\
|
||||
\n\
|
||||
This operation is unaffected by context and is quiet: no flags are changed\n\
|
||||
and no rounding is performed. As an exception, the C version may raise\n\
|
||||
InvalidOperation if the second operand cannot be converted exactly.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_conjugate,"\n\
|
||||
@ -117,31 +124,32 @@ conjugate() - Return self.\n\
|
||||
|
||||
PyDoc_STRVAR(doc_copy_abs,"\n\
|
||||
copy_abs() - Return the absolute value of the argument. This operation\n\
|
||||
is unaffected by the context and is quiet: no flags are changed and no\n\
|
||||
rounding is performed.\n\
|
||||
is unaffected by context and is quiet: no flags are changed and no rounding\n\
|
||||
is performed.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_copy_negate,"\n\
|
||||
copy_negate() - Return the negation of the argument. This operation is\n\
|
||||
unaffected by the context and is quiet: no flags are changed and no\n\
|
||||
rounding is performed.\n\
|
||||
unaffected by context and is quiet: no flags are changed and no rounding\n\
|
||||
is performed.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_copy_sign,"\n\
|
||||
copy_sign(other) - Return a copy of the first operand with the sign set\n\
|
||||
to be the same as the sign of the second operand. For example:\n\
|
||||
copy_sign(other, context=None) - Return a copy of the first operand with\n\
|
||||
the sign set to be the same as the sign of the second operand. For example:\n\
|
||||
\n\
|
||||
>>> Decimal('2.3').copy_sign(Decimal('-1.5'))\n\
|
||||
Decimal('-2.3')\n\
|
||||
\n\
|
||||
This operation is unaffected by the context and is quiet: no flags are\n\
|
||||
changed and no rounding is performed.\n\
|
||||
This operation is unaffected by context and is quiet: no flags are changed\n\
|
||||
and no rounding is performed. As an exception, the C version may raise\n\
|
||||
InvalidOperation if the second operand cannot be converted exactly.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_exp,"\n\
|
||||
exp([context]) - Return the value of the (natural) exponential function e**x\n\
|
||||
at the given number. The function always uses the ROUND_HALF_EVEN mode and\n\
|
||||
the result is correctly rounded.\n\
|
||||
exp(context=None) - Return the value of the (natural) exponential function\n\
|
||||
e**x at the given number. The function always uses the ROUND_HALF_EVEN mode\n\
|
||||
and the result is correctly rounded.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_from_float,"\n\
|
||||
@ -161,7 +169,7 @@ Decimal.from_float(0.1) is not the same as Decimal('0.1').\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_fma,"\n\
|
||||
fma(other, third[, context]) - Fused multiply-add. Return self*other+third\n\
|
||||
fma(other, third, context=None) - Fused multiply-add. Return self*other+third\n\
|
||||
with no rounding of the intermediate product self*other.\n\
|
||||
\n\
|
||||
>>> Decimal(2).fma(3, 5)\n\
|
||||
@ -191,9 +199,9 @@ False otherwise.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_is_normal,"\n\
|
||||
is_normal([context]) - Return True if the argument is a normal finite non-zero\n\
|
||||
number with an adjusted exponent greater than or equal to Emin. Return False\n\
|
||||
if the argument is zero, subnormal, infinite or a NaN.\n\
|
||||
is_normal(context=None) - Return True if the argument is a normal finite\n\
|
||||
non-zero number with an adjusted exponent greater than or equal to Emin.\n\
|
||||
Return False if the argument is zero, subnormal, infinite or a NaN.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_is_qnan,"\n\
|
||||
@ -210,8 +218,8 @@ is_snan() - Return True if the argument is a signaling NaN and False otherwise.\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_is_subnormal,"\n\
|
||||
is_subnormal([context]) - Return True if the argument is subnormal, and False\n\
|
||||
otherwise. A number is subnormal if it is non-zero, finite, and has an\n\
|
||||
is_subnormal(context=None) - Return True if the argument is subnormal, and\n\
|
||||
False otherwise. A number is subnormal if it is non-zero, finite, and has an\n\
|
||||
adjusted exponent less than Emin.\n\
|
||||
\n");
|
||||
|
||||
@ -221,94 +229,94 @@ False otherwise.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_ln,"\n\
|
||||
ln([context]) - Return the natural (base e) logarithm of the operand.\n\
|
||||
ln(context=None) - Return the natural (base e) logarithm of the operand.\n\
|
||||
The function always uses the ROUND_HALF_EVEN mode and the result is\n\
|
||||
correctly rounded.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_log10,"\n\
|
||||
log10([context]) - Return the base ten logarithm of the operand.\n\
|
||||
log10(context=None) - Return the base ten logarithm of the operand.\n\
|
||||
The function always uses the ROUND_HALF_EVEN mode and the result is\n\
|
||||
correctly rounded.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_logb,"\n\
|
||||
logb([context]) - For a non-zero number, return the adjusted exponent\n\
|
||||
logb(context=None) - For a non-zero number, return the adjusted exponent\n\
|
||||
of the operand as a Decimal instance. If the operand is a zero, then\n\
|
||||
Decimal('-Infinity') is returned and the DivisionByZero condition is\n\
|
||||
raised. If the operand is an infinity then Decimal('Infinity') is returned.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_logical_and,"\n\
|
||||
logical_and(other[, context]) - Return the digit-wise and of the two\n\
|
||||
logical_and(other, context=None) - Return the digit-wise and of the two\n\
|
||||
(logical) operands.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_logical_invert,"\n\
|
||||
logical_invert([context]) - Return the digit-wise inversion of the\n\
|
||||
logical_invert(context=None) - Return the digit-wise inversion of the\n\
|
||||
(logical) operand.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_logical_or,"\n\
|
||||
logical_or(other[, context]) - Return the digit-wise or of the two\n\
|
||||
logical_or(other, context=None) - Return the digit-wise or of the two\n\
|
||||
(logical) operands.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_logical_xor,"\n\
|
||||
logical_xor(other[, context]) - Return the digit-wise exclusive or of the\n\
|
||||
logical_xor(other, context=None) - Return the digit-wise exclusive or of the\n\
|
||||
two (logical) operands.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_max,"\n\
|
||||
max(other[, context]) - Maximum of self and other. If one operand is a quiet\n\
|
||||
NaN and the other is numeric, the numeric operand is returned.\n\
|
||||
max(other, context=None) - Maximum of self and other. If one operand is a\n\
|
||||
quiet NaN and the other is numeric, the numeric operand is returned.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_max_mag,"\n\
|
||||
max_mag(other[, context]) - Similar to the max() method, but the comparison is\n\
|
||||
done using the absolute values of the operands.\n\
|
||||
max_mag(other, context=None) - Similar to the max() method, but the\n\
|
||||
comparison is done using the absolute values of the operands.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_min,"\n\
|
||||
min(other[, context]) - Minimum of self and other. If one operand is a quiet\n\
|
||||
NaN and the other is numeric, the numeric operand is returned.\n\
|
||||
min(other, context=None) - Minimum of self and other. If one operand is a\n\
|
||||
quiet NaN and the other is numeric, the numeric operand is returned.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_min_mag,"\n\
|
||||
min_mag(other[, context]) - Similar to the min() method, but the comparison is\n\
|
||||
done using the absolute values of the operands.\n\
|
||||
min_mag(other, context=None) - Similar to the min() method, but the\n\
|
||||
comparison is done using the absolute values of the operands.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_next_minus,"\n\
|
||||
next_minus([context]) - Return the largest number representable in the given\n\
|
||||
context (or in the current default context if no context is given) that is\n\
|
||||
smaller than the given operand.\n\
|
||||
next_minus(context=None) - Return the largest number representable in the\n\
|
||||
given context (or in the current default context if no context is given) that\n\
|
||||
is smaller than the given operand.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_next_plus,"\n\
|
||||
next_plus([context]) - Return the smallest number representable in the given\n\
|
||||
context (or in the current default context if no context is given) that is\n\
|
||||
larger than the given operand.\n\
|
||||
next_plus(context=None) - Return the smallest number representable in the\n\
|
||||
given context (or in the current default context if no context is given) that\n\
|
||||
is larger than the given operand.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_next_toward,"\n\
|
||||
next_toward(other[, context]) - If the two operands are unequal, return the\n\
|
||||
number closest to the first operand in the direction of the second operand.\n\
|
||||
next_toward(other, context=None) - If the two operands are unequal, return\n\
|
||||
the number closest to the first operand in the direction of the second operand.\n\
|
||||
If both operands are numerically equal, return a copy of the first operand\n\
|
||||
with the sign set to be the same as the sign of the second operand.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_normalize,"\n\
|
||||
normalize([context]) - Normalize the number by stripping the rightmost trailing\n\
|
||||
zeros and converting any result equal to Decimal('0') to Decimal('0e0'). Used\n\
|
||||
for producing canonical values for members of an equivalence class. For example,\n\
|
||||
Decimal('32.100') and Decimal('0.321000e+2') both normalize to the equivalent\n\
|
||||
value Decimal('32.1').\n\
|
||||
normalize(context=None) - Normalize the number by stripping the rightmost\n\
|
||||
trailing zeros and converting any result equal to Decimal('0') to Decimal('0e0').\n\
|
||||
Used for producing canonical values for members of an equivalence class. For\n\
|
||||
example, Decimal('32.100') and Decimal('0.321000e+2') both normalize to the\n\
|
||||
equivalent value Decimal('32.1').\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_number_class,"\n\
|
||||
number_class([context]) - Return a string describing the class of the operand.\n\
|
||||
The returned value is one of the following ten strings:\n\
|
||||
number_class(context=None) - Return a string describing the class of the\n\
|
||||
operand. The returned value is one of the following ten strings:\n\
|
||||
\n\
|
||||
* '-Infinity', indicating that the operand is negative infinity.\n\
|
||||
* '-Normal', indicating that the operand is a negative normal number.\n\
|
||||
@ -324,8 +332,8 @@ The returned value is one of the following ten strings:\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_quantize,"\n\
|
||||
quantize(exp[, rounding[, context]]) - Return a value equal to the first\n\
|
||||
operand after rounding and having the exponent of the second operand.\n\
|
||||
quantize(exp, rounding=None, context=None) - Return a value equal to the\n\
|
||||
first operand after rounding and having the exponent of the second operand.\n\
|
||||
\n\
|
||||
>>> Decimal('1.41421356').quantize(Decimal('1.000'))\n\
|
||||
Decimal('1.414')\n\
|
||||
@ -350,16 +358,18 @@ all its arithmetic. Included for compatibility with the specification.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_remainder_near,"\n\
|
||||
remainder_near(other[, context]) - Compute the modulo as either a positive\n\
|
||||
or negative value depending on which is closest to zero. For instance,\n\
|
||||
Decimal(10).remainder_near(6) returns Decimal('-2'), which is closer to zero\n\
|
||||
than Decimal('4').\n\
|
||||
remainder_near(other, context=None) - Return the remainder from dividing\n\
|
||||
self by other. This differs from self % other in that the sign of the\n\
|
||||
remainder is chosen so as to minimize its absolute value. More precisely, the\n\
|
||||
return value is self - n * other where n is the integer nearest to the exact\n\
|
||||
value of self / other, and if two integers are equally near then the even one\n\
|
||||
is chosen.\n\
|
||||
\n\
|
||||
If both are equally close, the one chosen will have the same sign as self.\n\
|
||||
If the result is zero then its sign will be the sign of self.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_rotate,"\n\
|
||||
rotate(other[, context]) - Return the result of rotating the digits of the\n\
|
||||
rotate(other, context=None) - Return the result of rotating the digits of the\n\
|
||||
first operand by an amount specified by the second operand. The second operand\n\
|
||||
must be an integer in the range -precision through precision. The absolute\n\
|
||||
value of the second operand gives the number of places to rotate. If the second\n\
|
||||
@ -370,18 +380,22 @@ unchanged.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_same_quantum,"\n\
|
||||
same_quantum(other[, context]) - Test whether self and other have the\n\
|
||||
same_quantum(other, context=None) - Test whether self and other have the\n\
|
||||
same exponent or whether both are NaN.\n\
|
||||
\n\
|
||||
This operation is unaffected by context and is quiet: no flags are changed\n\
|
||||
and no rounding is performed. As an exception, the C version may raise\n\
|
||||
InvalidOperation if the second operand cannot be converted exactly.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_scaleb,"\n\
|
||||
scaleb(other[, context]) - Return the first operand with the exponent adjusted\n\
|
||||
the second. Equivalently, return the first operand multiplied by 10**other.\n\
|
||||
The second operand must be an integer.\n\
|
||||
scaleb(other, context=None) - Return the first operand with the exponent\n\
|
||||
adjusted the second. Equivalently, return the first operand multiplied by\n\
|
||||
10**other. The second operand must be an integer.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_shift,"\n\
|
||||
shift(other[, context]) - Return the result of shifting the digits of\n\
|
||||
shift(other, context=None) - Return the result of shifting the digits of\n\
|
||||
the first operand by an amount specified by the second operand. The second\n\
|
||||
operand must be an integer in the range -precision through precision. The\n\
|
||||
absolute value of the second operand gives the number of places to shift.\n\
|
||||
@ -391,36 +405,40 @@ The sign and exponent of the first operand are unchanged.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_sqrt,"\n\
|
||||
sqrt([context]) - Return the square root of the argument to full precision.\n\
|
||||
sqrt(context=None) - Return the square root of the argument to full precision.\n\
|
||||
The result is correctly rounded using the ROUND_HALF_EVEN rounding mode.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_to_eng_string,"\n\
|
||||
to_eng_string([context]) - Convert to an engineering-type string.\n\
|
||||
Engineering notation has an exponent which is a multiple of 3, so\n\
|
||||
there are up to 3 digits left of the decimal place. For example,\n\
|
||||
Decimal('123E+1') is converted to Decimal('1.23E+3')\n\
|
||||
to_eng_string(context=None) - Convert to an engineering-type string.\n\
|
||||
Engineering notation has an exponent which is a multiple of 3, so there\n\
|
||||
are up to 3 digits left of the decimal place. For example, Decimal('123E+1')\n\
|
||||
is converted to Decimal('1.23E+3').\n\
|
||||
\n\
|
||||
The value of context.capitals determines whether the exponent sign is lower\n\
|
||||
or upper case. Otherwise, the context does not affect the operation.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_to_integral,"\n\
|
||||
to_integral([rounding[, context]]) - Identical to the to_integral_value()\n\
|
||||
method. The to_integral name has been kept for compatibility with older\n\
|
||||
versions.\n\
|
||||
to_integral(rounding=None, context=None) - Identical to the\n\
|
||||
to_integral_value() method. The to_integral() name has been kept\n\
|
||||
for compatibility with older versions.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_to_integral_exact,"\n\
|
||||
to_integral_exact([rounding[, context]]) - Round to the nearest integer,\n\
|
||||
signaling Inexact or Rounded as appropriate if rounding occurs. The rounding\n\
|
||||
mode is determined by the rounding parameter if given, else by the given\n\
|
||||
context. If neither parameter is given, then the rounding mode of the current\n\
|
||||
default context is used.\n\
|
||||
to_integral_exact(rounding=None, context=None) - Round to the nearest\n\
|
||||
integer, signaling Inexact or Rounded as appropriate if rounding occurs.\n\
|
||||
The rounding mode is determined by the rounding parameter if given, else\n\
|
||||
by the given context. If neither parameter is given, then the rounding mode\n\
|
||||
of the current default context is used.\n\
|
||||
\n");
|
||||
|
||||
PyDoc_STRVAR(doc_to_integral_value,"\n\
|
||||
to_integral_value([rounding[, context]]) - Round to the nearest integer without\n\
|
||||
signaling Inexact or Rounded. The rounding mode is determined by the rounding\n\
|
||||
parameter if given, else by the given context. If neither parameter is given,\n\
|
||||
then the rounding mode of the current default context is used.\n\
|
||||
to_integral_value(rounding=None, context=None) - Round to the nearest\n\
|
||||
integer without signaling Inexact or Rounded. The rounding mode is determined\n\
|
||||
by the rounding parameter if given, else by the given context. If neither\n\
|
||||
parameter is given, then the rounding mode of the current default context is\n\
|
||||
used.\n\
|
||||
\n");
|
||||
|
||||
|
||||
|
@ -36,6 +36,7 @@ from copy import copy
|
||||
from collections import defaultdict
|
||||
from test.support import import_fresh_module
|
||||
from randdec import randfloat, all_unary, all_binary, all_ternary
|
||||
from randdec import unary_optarg, binary_optarg, ternary_optarg
|
||||
from formathelper import rand_format, rand_locale
|
||||
|
||||
C = import_fresh_module('decimal', fresh=['_decimal'])
|
||||
@ -834,6 +835,17 @@ def test_unary(method, prec, exp_range, restricted_range, itr, stat):
|
||||
except VerifyError as err:
|
||||
log(err)
|
||||
|
||||
if not method.startswith('__'):
|
||||
for op in unary_optarg(prec, exp_range, itr):
|
||||
t = TestSet(method, op)
|
||||
try:
|
||||
if not convert(t):
|
||||
continue
|
||||
callfuncs(t)
|
||||
verify(t, stat)
|
||||
except VerifyError as err:
|
||||
log(err)
|
||||
|
||||
def test_binary(method, prec, exp_range, restricted_range, itr, stat):
|
||||
"""Iterate a binary function through many test cases."""
|
||||
if method in BinaryRestricted:
|
||||
@ -848,6 +860,17 @@ def test_binary(method, prec, exp_range, restricted_range, itr, stat):
|
||||
except VerifyError as err:
|
||||
log(err)
|
||||
|
||||
if not method.startswith('__'):
|
||||
for op in binary_optarg(prec, exp_range, itr):
|
||||
t = TestSet(method, op)
|
||||
try:
|
||||
if not convert(t):
|
||||
continue
|
||||
callfuncs(t)
|
||||
verify(t, stat)
|
||||
except VerifyError as err:
|
||||
log(err)
|
||||
|
||||
def test_ternary(method, prec, exp_range, restricted_range, itr, stat):
|
||||
"""Iterate a ternary function through many test cases."""
|
||||
if method in TernaryRestricted:
|
||||
@ -862,6 +885,17 @@ def test_ternary(method, prec, exp_range, restricted_range, itr, stat):
|
||||
except VerifyError as err:
|
||||
log(err)
|
||||
|
||||
if not method.startswith('__'):
|
||||
for op in ternary_optarg(prec, exp_range, itr):
|
||||
t = TestSet(method, op)
|
||||
try:
|
||||
if not convert(t):
|
||||
continue
|
||||
callfuncs(t)
|
||||
verify(t, stat)
|
||||
except VerifyError as err:
|
||||
log(err)
|
||||
|
||||
def test_format(method, prec, exp_range, restricted_range, itr, stat):
|
||||
"""Iterate the __format__ method through many test cases."""
|
||||
for op in all_unary(prec, exp_range, itr):
|
||||
|
@ -527,6 +527,11 @@ def all_unary(prec, exp_range, itr):
|
||||
for _ in range(100):
|
||||
yield (randtuple(prec, exp_range),)
|
||||
|
||||
def unary_optarg(prec, exp_range, itr):
|
||||
for _ in range(100):
|
||||
yield randdec(prec, exp_range), None
|
||||
yield randdec(prec, exp_range), None, None
|
||||
|
||||
def all_binary(prec, exp_range, itr):
|
||||
for a, b in bin_close_to_pow10(prec, exp_range, itr):
|
||||
yield a, b
|
||||
@ -543,6 +548,11 @@ def all_binary(prec, exp_range, itr):
|
||||
for _ in range(100):
|
||||
yield randdec(prec, exp_range), randdec(prec, exp_range)
|
||||
|
||||
def binary_optarg(prec, exp_range, itr):
|
||||
for _ in range(100):
|
||||
yield randdec(prec, exp_range), randdec(prec, exp_range), None
|
||||
yield randdec(prec, exp_range), randdec(prec, exp_range), None, None
|
||||
|
||||
def all_ternary(prec, exp_range, itr):
|
||||
for a, b, c in tern_close_numbers(prec, exp_range, -exp_range, itr):
|
||||
yield a, b, c
|
||||
@ -557,3 +567,11 @@ def all_ternary(prec, exp_range, itr):
|
||||
b = randdec(prec, 2*exp_range)
|
||||
c = randdec(prec, 2*exp_range)
|
||||
yield a, b, c
|
||||
|
||||
def ternary_optarg(prec, exp_range, itr):
|
||||
for _ in range(100):
|
||||
a = randdec(prec, 2*exp_range)
|
||||
b = randdec(prec, 2*exp_range)
|
||||
c = randdec(prec, 2*exp_range)
|
||||
yield a, b, c, None
|
||||
yield a, b, c, None, None
|
||||
|
Loading…
Reference in New Issue
Block a user