diff --git a/Lib/decimal.py b/Lib/decimal.py index b3d84e734b1..75a1d5ec3f0 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -504,7 +504,7 @@ def sin(x): ##### Decimal class ####################################################### -class Decimal(_numbers.Real, _numbers.Inexact): +class Decimal(_numbers.Real): """Floating point class for decimal arithmetic.""" __slots__ = ('_exp','_int','_sign', '_is_special') diff --git a/Lib/numbers.py b/Lib/numbers.py index 4217d084beb..c72a23df39f 100644 --- a/Lib/numbers.py +++ b/Lib/numbers.py @@ -7,10 +7,7 @@ from abc import ABCMeta, abstractmethod, abstractproperty -__all__ = ["Number", "Exact", "Inexact", - "Complex", "Real", "Rational", "Integral", - ] - +__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] class Number(metaclass=ABCMeta): """All numbers inherit from this class. @@ -20,59 +17,13 @@ class Number(metaclass=ABCMeta): """ -class Exact(Number): - """Operations on instances of this type are exact. - - As long as the result of a homogenous operation is of the same - type, you can assume that it was computed exactly, and there are - no round-off errors. Laws like commutativity and associativity - hold. - """ - -Exact.register(int) - - -class Inexact(Number): - """Operations on instances of this type are inexact. - - Given X, an instance of Inexact, it is possible that (X + -X) + 3 - == 3, but X + (-X + 3) == 0. The exact form this error takes will - vary by type, but it's generally unsafe to compare this type for - equality. - """ - -Inexact.register(complex) -Inexact.register(float) -# Inexact.register(decimal.Decimal) - - ## Notes on Decimal ## ---------------- ## Decimal has all of the methods specified by the Real abc, but it should ## not be registered as a Real because decimals do not interoperate with -## binary floats. -## -## Decimal has some of the characteristics of Integrals. It provides -## logical operations but not as operators. The logical operations only apply -## to a subset of decimals (those that are non-negative, have a zero exponent, -## and have digits that are only 0 or 1). It does provide __long__() and -## a three argument form of __pow__ that includes exactness guarantees. -## It does not provide an __index__() method. -## -## Depending on context, decimal operations may be exact or inexact. -## -## When decimal is run in a context with small precision and automatic rounding, -## it is Inexact. See the "Floating point notes" section of the decimal docs -## for an example of losing the associative and distributive properties of -## addition. -## -## When decimal is used for high precision integer arithmetic, it is Exact. -## When the decimal used as fixed-point, it is Exact. -## When it is run with sufficient precision, it is Exact. -## When the decimal.Inexact trap is set, decimal operations are Exact. -## For an example, see the float_to_decimal() recipe in the "Decimal FAQ" -## section of the docs -- it shows an how traps are used in conjunction -## with variable precision to reliably achieve exact results. +## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But, +## abstract reals are expected to interoperate (i.e. R1 + R2 should be +## expected to work if R1 and R2 are both Reals). class Complex(Number): """Complex defines the operations that work on the builtin complex type. @@ -308,7 +259,7 @@ def conjugate(self): Real.register(float) -class Rational(Real, Exact): +class Rational(Real): """.numerator and .denominator should be in lowest terms.""" @abstractproperty diff --git a/Lib/test/test_abstract_numbers.py b/Lib/test/test_abstract_numbers.py index 317d333d888..244f87ab0f2 100644 --- a/Lib/test/test_abstract_numbers.py +++ b/Lib/test/test_abstract_numbers.py @@ -4,7 +4,6 @@ import operator import unittest from numbers import Complex, Real, Rational, Integral -from numbers import Exact, Inexact from numbers import Number from test import test_support @@ -12,8 +11,6 @@ class TestNumbers(unittest.TestCase): def test_int(self): self.failUnless(issubclass(int, Integral)) self.failUnless(issubclass(int, Complex)) - self.failUnless(issubclass(int, Exact)) - self.failIf(issubclass(int, Inexact)) self.assertEqual(7, int(7).real) self.assertEqual(0, int(7).imag) @@ -24,8 +21,6 @@ def test_int(self): def test_float(self): self.failIf(issubclass(float, Rational)) self.failUnless(issubclass(float, Real)) - self.failIf(issubclass(float, Exact)) - self.failUnless(issubclass(float, Inexact)) self.assertEqual(7.3, float(7.3).real) self.assertEqual(0, float(7.3).imag) @@ -34,8 +29,6 @@ def test_float(self): def test_complex(self): self.failIf(issubclass(complex, Real)) self.failUnless(issubclass(complex, Complex)) - self.failIf(issubclass(complex, Exact)) - self.failUnless(issubclass(complex, Inexact)) c1, c2 = complex(3, 2), complex(4,1) # XXX: This is not ideal, but see the comment in math_trunc(). diff --git a/Python/compile.c b/Python/compile.c index 6ad3822a982..7d5ada62f50 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2223,6 +2223,14 @@ compiler_assert(struct compiler *c, stmt_ty s) if (assertion_error == NULL) return 0; } + if (s->v.Assert.test->kind == Tuple_kind && + asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) { + const char* msg = + "assertion is always true, perhaps remove parentheses?"; + if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, c->c_filename, + c->u->u_lineno, NULL, NULL) == -1) + return 0; + } VISIT(c, expr, s->v.Assert.test); end = compiler_new_block(c); if (end == NULL) diff --git a/Python/symtable.c b/Python/symtable.c index 84d0067b686..b896c525639 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -33,8 +33,9 @@ PySTEntry_New(struct symtable *st, identifier name, _Py_block_ty block, k = PyLong_FromVoidPtr(key); if (k == NULL) goto fail; - ste = (PySTEntryObject *)PyObject_New(PySTEntryObject, - &PySTEntry_Type); + ste = PyObject_New(PySTEntryObject, &PySTEntry_Type); + if (ste == NULL) + goto fail; ste->ste_table = st; ste->ste_id = k; ste->ste_tmpname = 0;