[Python-3000-checkins] r58040 - in python/branches/py3k: Lib/numbers.py Lib/test/test_builtin.py Lib/test/test_complex.py Lib/test/test_descr.py Objects/floatobject.c

jeffrey.yasskin python-3000-checkins at python.org
Fri Sep 7 17:15:49 CEST 2007


Author: jeffrey.yasskin
Date: Fri Sep  7 17:15:49 2007
New Revision: 58040

Modified:
   python/branches/py3k/Lib/numbers.py
   python/branches/py3k/Lib/test/test_builtin.py
   python/branches/py3k/Lib/test/test_complex.py
   python/branches/py3k/Lib/test/test_descr.py
   python/branches/py3k/Objects/floatobject.c
Log:
Check in some documentation tweaks for PEP 3141, add some tests, and implement
the promotion to complex on pow(negative, fraction).


Modified: python/branches/py3k/Lib/numbers.py
==============================================================================
--- python/branches/py3k/Lib/numbers.py	(original)
+++ python/branches/py3k/Lib/numbers.py	Fri Sep  7 17:15:49 2007
@@ -1,7 +1,9 @@
 # Copyright 2007 Google, Inc. All Rights Reserved.
 # Licensed to PSF under a Contributor Agreement.
 
-"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141."""
+"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141.
+
+TODO: Fill out more detailed documentation on the operators."""
 
 from abc import ABCMeta, abstractmethod, abstractproperty
 
@@ -56,10 +58,10 @@
 
     @abstractmethod
     def __complex__(self):
-        """Return a builtin complex instance."""
+        """Return a builtin complex instance. Called for complex(self)."""
 
     def __bool__(self):
-        """True if self != 0."""
+        """True if self != 0. Called for bool(self)."""
         return self != 0
 
     @abstractproperty
@@ -80,53 +82,64 @@
 
     @abstractmethod
     def __add__(self, other):
+        """self + other"""
         raise NotImplementedError
 
     @abstractmethod
     def __radd__(self, other):
+        """other + self"""
         raise NotImplementedError
 
     @abstractmethod
     def __neg__(self):
+        """-self"""
         raise NotImplementedError
 
     def __pos__(self):
+        """+self"""
         return self
 
     def __sub__(self, other):
+        """self - other"""
         return self + -other
 
     def __rsub__(self, other):
+        """other - self"""
         return -self + other
 
     @abstractmethod
     def __mul__(self, other):
+        """self * other"""
         raise NotImplementedError
 
     @abstractmethod
     def __rmul__(self, other):
+        """other * self"""
         raise NotImplementedError
 
     @abstractmethod
     def __div__(self, other):
+        """self / other"""
         raise NotImplementedError
 
     @abstractmethod
     def __rdiv__(self, other):
+        """other / self"""
         raise NotImplementedError
 
     @abstractmethod
     def __pow__(self, exponent):
-        """Like division, a**b should promote to complex when necessary."""
+        """Like division, self**exponent should promote to complex when necessary."""
         raise NotImplementedError
 
     @abstractmethod
     def __rpow__(self, base):
+        """base ** self"""
         raise NotImplementedError
 
     @abstractmethod
     def __abs__(self):
-        """Returns the Real distance from 0."""
+        """Returns the Real distance from 0. Called for abs(self)."""
         raise NotImplementedError
 
     @abstractmethod
@@ -136,9 +149,11 @@
 
     @abstractmethod
     def __eq__(self, other):
+        """self == other"""
         raise NotImplementedError
 
     def __ne__(self, other):
+        """self != other"""
         return not (self == other)
 
 Complex.register(complex)
@@ -155,12 +170,14 @@
 
     @abstractmethod
     def __float__(self):
-        """Any Real can be converted to a native float object."""
+        """Any Real can be converted to a native float object.
+
+        Called for float(self)."""
         raise NotImplementedError
 
     @abstractmethod
     def __trunc__(self):
-        """Truncates self to an Integral.
+        """trunc(self): Truncates self to an Integral.
 
         Returns an Integral i such that:
           * i>0 iff self>0
@@ -169,7 +186,7 @@
         raise NotImplementedError
 
     def __divmod__(self, other):
-        """The pair (self // other, self % other).
+        """divmod(self, other): The pair (self // other, self % other).
 
         Sometimes this can be computed faster than the pair of
         operations.
@@ -177,7 +194,7 @@
         return (self // other, self % other)
 
     def __rdivmod__(self, other):
-        """The pair (self // other, self % other).
+        """divmod(other, self): The pair (self // other, self % other).
 
         Sometimes this can be computed faster than the pair of
         operations.
@@ -186,40 +203,49 @@
 
     @abstractmethod
     def __floordiv__(self, other):
-        """The floor() of self/other."""
+        """self // other: The floor() of self/other."""
         raise NotImplementedError
 
     @abstractmethod
     def __rfloordiv__(self, other):
-        """The floor() of other/self."""
+        """other // self: The floor() of other/self."""
         raise NotImplementedError
 
     @abstractmethod
     def __mod__(self, other):
+        """self % other"""
         raise NotImplementedError
 
     @abstractmethod
     def __rmod__(self, other):
+        """other % self"""
         raise NotImplementedError
 
     @abstractmethod
     def __lt__(self, other):
-        """< on Reals defines a total ordering, except perhaps for NaN."""
+        """self < other
+
+        < on Reals defines a total ordering, except perhaps for NaN."""
         raise NotImplementedError
 
+    @abstractmethod
     def __le__(self, other):
+        """self <= other"""
         raise NotImplementedError
 
     # Concrete implementations of Complex abstract methods.
     def __complex__(self):
+        """complex(self) == complex(float(self), 0)"""
         return complex(float(self))
 
     @property
     def real(self):
+        """Real numbers are their real component."""
         return self
 
     @property
     def imag(self):
+        """Real numbers have no imaginary component."""
         return 0
 
     def conjugate(self):
@@ -242,6 +268,7 @@
 
     # Concrete implementation of Real's conversion to float.
     def __float__(self):
+        """float(self) = self.numerator / self.denominator"""
         return self.numerator / self.denominator
 
 
@@ -250,76 +277,92 @@
 
     @abstractmethod
     def __int__(self):
+        """int(self)"""
         raise NotImplementedError
 
     def __index__(self):
+        """index(self)"""
         return int(self)
 
     @abstractmethod
-    def __pow__(self, exponent, modulus):
+    def __pow__(self, exponent, modulus=None):
         """self ** exponent % modulus, but maybe faster.
 
-        Implement this if you want to support the 3-argument version
-        of pow(). Otherwise, just implement the 2-argument version
-        described in Complex. Raise a TypeError if exponent < 0 or any
-        argument isn't Integral.
+        Accept the modulus argument if you want to support the
+        3-argument version of pow(). Raise a TypeError if exponent < 0
+        or any argument isn't Integral. Otherwise, just implement the
+        2-argument version described in Complex.
         """
         raise NotImplementedError
 
     @abstractmethod
     def __lshift__(self, other):
+        """self << other"""
         raise NotImplementedError
 
     @abstractmethod
     def __rlshift__(self, other):
+        """other << self"""
         raise NotImplementedError
 
     @abstractmethod
     def __rshift__(self, other):
+        """self >> other"""
         raise NotImplementedError
 
     @abstractmethod
     def __rrshift__(self, other):
+        """other >> self"""
         raise NotImplementedError
 
     @abstractmethod
     def __and__(self, other):
+        """self & other"""
         raise NotImplementedError
 
     @abstractmethod
     def __rand__(self, other):
+        """other & self"""
         raise NotImplementedError
 
     @abstractmethod
     def __xor__(self, other):
+        """self ^ other"""
         raise NotImplementedError
 
     @abstractmethod
     def __rxor__(self, other):
+        """other ^ self"""
         raise NotImplementedError
 
     @abstractmethod
     def __or__(self, other):
+        """self | other"""
         raise NotImplementedError
 
     @abstractmethod
     def __ror__(self, other):
+        """other | self"""
         raise NotImplementedError
 
     @abstractmethod
     def __invert__(self):
+        """~self"""
         raise NotImplementedError
 
     # Concrete implementations of Rational and Real abstract methods.
     def __float__(self):
+        """float(self) == float(int(self))"""
         return float(int(self))
 
     @property
     def numerator(self):
+        """Integers are their own numerators."""
         return self
 
     @property
     def denominator(self):
+        """Integers have a denominator of 1."""
         return 1
 
 Integral.register(int)

Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py	(original)
+++ python/branches/py3k/Lib/test/test_builtin.py	Fri Sep  7 17:15:49 2007
@@ -1358,11 +1358,13 @@
                     else:
                         self.assertAlmostEqual(pow(x, y, z), 24.0)
 
+        self.assertAlmostEqual(pow(-1, 0.5), 1j)
+        self.assertAlmostEqual(pow(-1, 1/3), 0.5 + 0.8660254037844386j)
+
         self.assertRaises(TypeError, pow, -1, -2, 3)
         self.assertRaises(ValueError, pow, 1, 2, 0)
         self.assertRaises(TypeError, pow, -1, -2, 3)
         self.assertRaises(ValueError, pow, 1, 2, 0)
-        self.assertRaises(ValueError, pow, -342.43, 0.234)
 
         self.assertRaises(TypeError, pow)
 

Modified: python/branches/py3k/Lib/test/test_complex.py
==============================================================================
--- python/branches/py3k/Lib/test/test_complex.py	(original)
+++ python/branches/py3k/Lib/test/test_complex.py	Fri Sep  7 17:15:49 2007
@@ -1,13 +1,6 @@
 import unittest, os
 from test import test_support
 
-import warnings
-warnings.filterwarnings(
-    "ignore",
-    category=DeprecationWarning,
-    message=".*complex divmod.*are deprecated"
-)
-
 from random import random
 
 # These tests ensure that complex math does the right thing
@@ -108,6 +101,7 @@
         # % is no longer supported on complex numbers
         self.assertRaises(TypeError, (1+1j).__mod__, 0+0j)
         self.assertRaises(TypeError, lambda: (3.33+4.43j) % 0)
+        self.assertRaises(TypeError, (1+1j).__mod__, 4.3j)
 
     def test_divmod(self):
         self.assertRaises(TypeError, divmod, 1+1j, 1+0j)

Modified: python/branches/py3k/Lib/test/test_descr.py
==============================================================================
--- python/branches/py3k/Lib/test/test_descr.py	(original)
+++ python/branches/py3k/Lib/test/test_descr.py	Fri Sep  7 17:15:49 2007
@@ -3,13 +3,8 @@
 from test.test_support import verify, vereq, verbose, TestFailed, TESTFN
 from test.test_support import get_original_stdout
 from copy import deepcopy
-import warnings
 import types
 
-warnings.filterwarnings("ignore",
-         r'complex divmod\(\), // and % are deprecated$',
-         DeprecationWarning, r'(<string>|%s)$' % __name__)
-
 def veris(a, b):
     if a is not b:
         raise TestFailed("%r is %r" % (a, b))

Modified: python/branches/py3k/Objects/floatobject.c
==============================================================================
--- python/branches/py3k/Objects/floatobject.c	(original)
+++ python/branches/py3k/Objects/floatobject.c	Fri Sep  7 17:15:49 2007
@@ -680,9 +680,10 @@
 		 * bugs so we have to figure it out ourselves.
 		 */
 		if (iw != floor(iw)) {
-			PyErr_SetString(PyExc_ValueError, "negative number "
-				"cannot be raised to a fractional power");
-			return NULL;
+			/* Negative numbers raised to fractional powers
+			 * become complex.
+			 */
+			return PyComplex_Type.tp_as_number->nb_power(v, w, z);
 		}
 		/* iw is an exact integer, albeit perhaps a very large one.
 		 * -1 raised to an exact integer should never be exceptional.


More information about the Python-3000-checkins mailing list