summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/decimal.py2
-rw-r--r--Lib/numbers.py59
-rw-r--r--Lib/test/test_abstract_numbers.py7
-rw-r--r--Python/compile.c8
-rw-r--r--Python/symtable.c5
5 files changed, 17 insertions, 64 deletions
diff --git a/Lib/decimal.py b/Lib/decimal.py
index b3d84e7..75a1d5e 100644
--- a/Lib/decimal.py
+++ b/Lib/decimal.py
@@ -504,7 +504,7 @@ def localcontext(ctx=None):
##### 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 4217d08..c72a23d 100644
--- a/Lib/numbers.py
+++ b/Lib/numbers.py
@@ -7,10 +7,7 @@ TODO: Fill out more detailed documentation on the operators."""
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 @@ class Real(Complex):
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 317d333..244f87a 100644
--- a/Lib/test/test_abstract_numbers.py
+++ b/Lib/test/test_abstract_numbers.py
@@ -4,7 +4,6 @@ import math
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 @@ class TestNumbers(unittest.TestCase):
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 @@ class TestNumbers(unittest.TestCase):
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 6ad3822..7d5ada6 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 84d0067..b896c52 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;