From 08976cb6967a071682612211579385e35fd68eda Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Sun, 16 Mar 2008 00:32:36 +0000 Subject: Merged revisions 61404-61407 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r61404 | raymond.hettinger | 2008-03-15 21:02:04 +0100 (Sat, 15 Mar 2008) | 17 lines Removed Exact/Inexact after discussion with Yasskin. Unlike Scheme where exactness is implemented as taints, the Python implementation associated exactness with data types. This created inheritance issues (making an exact subclass of floats would result in the subclass having both an explicit Exact registration and an inherited Inexact registration). This was a problem for the decimal module which was designed to span both exact and inexact arithmetic. There was also a question of use cases and no examples were found where ABCs for exactness could be used to improve code. One other issue was having separate tags for both the affirmative and negative cases. This is at odds with the approach taken elsewhere in the Python (i.e. we don't have an ABC both Hashable and Unhashable). ........ r61405 | raymond.hettinger | 2008-03-15 21:37:50 +0100 (Sat, 15 Mar 2008) | 1 line Zap one more use of Exact/Inexact. ........ r61406 | neal.norwitz | 2008-03-15 23:03:18 +0100 (Sat, 15 Mar 2008) | 9 lines Add a warning for code like: assert (0, 'message') An empty tuple does not create a warning. While questionable usage: assert (), 'message' should not display a warning. Tested manually. The warning message could be improved. Feel free to update it. ........ r61407 | neal.norwitz | 2008-03-15 23:36:01 +0100 (Sat, 15 Mar 2008) | 1 line Handle memory allocation failure. Found by Adam Olsen ........ --- Lib/decimal.py | 2 +- Lib/numbers.py | 59 ++++----------------------------------- Lib/test/test_abstract_numbers.py | 7 ----- Python/compile.c | 8 ++++++ Python/symtable.c | 5 ++-- 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; -- cgit v0.12