Some small updates, with Jeffrey's OK.
This commit is contained in:
parent
3a6f48c056
commit
e8400c12a9
85
pep-3141.txt
85
pep-3141.txt
|
@ -60,8 +60,8 @@ numbers are supported by this hierarchy. ::
|
|||
class Complex(Number):
|
||||
"""Complex defines the operations that work on the builtin complex type.
|
||||
|
||||
In short, those are: a conversion to complex, .real, .imag, +, -,
|
||||
*, /, abs(), .conjugate, ==, and !=.
|
||||
In short, those are: conversion to complex, bool(), .real, .imag,
|
||||
+, -, *, /, **, abs(), .conjugate(), ==, and !=.
|
||||
|
||||
If it is given heterogenous arguments, and doesn't have special
|
||||
knowledge about them, it should fall back to the builtin complex
|
||||
|
@ -105,10 +105,7 @@ numbers are supported by this hierarchy. ::
|
|||
raise NotImplementedError
|
||||
|
||||
def __pos__(self):
|
||||
"""+self
|
||||
|
||||
Coerces self to whatever class defines the method.
|
||||
"""
|
||||
"""Coerces self to whatever class defines the method."""
|
||||
raise NotImplementedError
|
||||
|
||||
def __sub__(self, other):
|
||||
|
@ -127,6 +124,7 @@ numbers are supported by this hierarchy. ::
|
|||
|
||||
@abstractmethod
|
||||
def __div__(self, other):
|
||||
"""a/b; should promote to float or complex when necessary."""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
|
@ -135,7 +133,7 @@ numbers are supported by this hierarchy. ::
|
|||
|
||||
@abstractmethod
|
||||
def __pow__(self, exponent):
|
||||
"""Like division, a**b should promote to complex when necessary."""
|
||||
"""a**b; should promote to float or complex when necessary."""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
|
@ -156,8 +154,7 @@ numbers are supported by this hierarchy. ::
|
|||
def __eq__(self, other):
|
||||
raise NotImplementedError
|
||||
|
||||
def __ne__(self, other):
|
||||
return not (self == other)
|
||||
# __ne__ is inherited from object and negates whatever __eq__ does.
|
||||
|
||||
|
||||
The ``Real`` ABC indicates that the value is on the real line, and
|
||||
|
@ -167,12 +164,15 @@ totally ordered except for NaNs (which this PEP basically ignores). ::
|
|||
class Real(Complex):
|
||||
"""To Complex, Real adds the operations that work on real numbers.
|
||||
|
||||
In short, those are: a conversion to float, trunc(), divmod,
|
||||
%, <, <=, >, and >=.
|
||||
In short, those are: conversion to float, trunc(), math.floor(),
|
||||
math.ceil(), round(), divmod(), //, %, <, <=, >, and >=.
|
||||
|
||||
Real also provides defaults for the derived operations.
|
||||
Real also provides defaults for some of the derived operations.
|
||||
"""
|
||||
|
||||
# XXX What to do about the __int__ implementation that's
|
||||
# currently present on float and Decimal? Get rid of it?
|
||||
|
||||
@abstractmethod
|
||||
def __float__(self):
|
||||
"""Any Real can be converted to a native float object."""
|
||||
|
@ -183,10 +183,10 @@ totally ordered except for NaNs (which this PEP basically ignores). ::
|
|||
"""Truncates self to an Integral.
|
||||
|
||||
Returns an Integral i such that:
|
||||
* i>=0 iff self>0
|
||||
* abs(i) <= abs(self).
|
||||
* i>=0 iff self>0;
|
||||
* abs(i) <= abs(self);
|
||||
* for any Integral j satisfying the first two conditions,
|
||||
abs(i) >= abs(j) [i.e. i has "maximal" abs among those]
|
||||
abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
|
||||
i.e. "truncate towards 0".
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
@ -205,7 +205,7 @@ totally ordered except for NaNs (which this PEP basically ignores). ::
|
|||
def __round__(self, ndigits:Integral=None):
|
||||
"""Rounds self to ndigits decimal places, defaulting to 0.
|
||||
|
||||
If ndigits is omitted, returns an Integral, otherwise
|
||||
If ndigits is omitted or None, returns an Integral, otherwise
|
||||
returns a Real. Rounds half toward even.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
@ -261,14 +261,18 @@ totally ordered except for NaNs (which this PEP basically ignores). ::
|
|||
def __le__(self, other):
|
||||
raise NotImplementedError
|
||||
|
||||
# __gt__ and __ge__ are automatically done by reversing the arguments.
|
||||
# (But __le__ is not computed as the opposite of __gt__!)
|
||||
|
||||
# Concrete implementations of Complex abstract methods.
|
||||
# Subclasses may override these, but don't have to.
|
||||
|
||||
def __complex__(self):
|
||||
return complex(float(self))
|
||||
|
||||
@property
|
||||
def real(self):
|
||||
return self
|
||||
return +self
|
||||
|
||||
@property
|
||||
def imag(self):
|
||||
|
@ -276,10 +280,10 @@ totally ordered except for NaNs (which this PEP basically ignores). ::
|
|||
|
||||
def conjugate(self):
|
||||
"""Conjugate is a no-op for Reals."""
|
||||
return self
|
||||
return +self
|
||||
|
||||
|
||||
We need to clean up Demo/classes/Rat.py and promote it into
|
||||
We should clean up Demo/classes/Rat.py and promote it into
|
||||
rational.py in the standard library. Then it will implement the
|
||||
Rational ABC. ::
|
||||
|
||||
|
@ -295,6 +299,7 @@ Rational ABC. ::
|
|||
raise NotImplementedError
|
||||
|
||||
# Concrete implementation of Real's conversion to float.
|
||||
# (This invokes Integer.__div__().)
|
||||
|
||||
def __float__(self):
|
||||
return self.numerator / self.denominator
|
||||
|
@ -310,21 +315,25 @@ And finally integers::
|
|||
raise NotImplementedError
|
||||
|
||||
def __index__(self):
|
||||
"""__index__() exists because float and Decimal have __int__()."""
|
||||
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.
|
||||
Implement this if you want to support the 3-argument
|
||||
version of pow(). Otherwise, just implement the 2-argument
|
||||
version described in Complex. If modulus is None, this
|
||||
should behave as the 2-argument version; otherwise, raise
|
||||
a TypeError if exponent < 0 or any argument isn't
|
||||
Integral.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def __lshift__(self, other):
|
||||
"""i<<j returns i * 2**j."""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
|
@ -333,6 +342,7 @@ And finally integers::
|
|||
|
||||
@abstractmethod
|
||||
def __rshift__(self, other):
|
||||
"""i>>j returns i // 2**j."""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
|
@ -374,7 +384,7 @@ And finally integers::
|
|||
|
||||
@property
|
||||
def numerator(self):
|
||||
return self
|
||||
return +self
|
||||
|
||||
@property
|
||||
def denominator(self):
|
||||
|
@ -390,7 +400,7 @@ you would expect. For example, it is possible for ``(X + -X) + 3 ==
|
|||
functions deal with this isn't a problem, but it is something to be
|
||||
aware of.
|
||||
|
||||
Therefore, I define ``Exact`` and ``Inexact`` ABCs to mark whether
|
||||
Therefore, we define ``Exact`` and ``Inexact`` ABCs to mark whether
|
||||
types have this problem. Every instance of ``Integral`` and
|
||||
``Rational`` should be Exact, but ``Reals`` and ``Complexes`` may or
|
||||
may not be. (Do we really only need one of these, and the other is
|
||||
|
@ -404,7 +414,7 @@ Changes to operations and __magic__ methods
|
|||
-------------------------------------------
|
||||
|
||||
To support more precise narrowing from float to int (and more
|
||||
generally, from Real to Integral), I'm proposing the following new
|
||||
generally, from Real to Integral), we propose the following new
|
||||
__magic__ methods, to be called from the corresponding library
|
||||
functions. All of these return Integrals rather than Reals.
|
||||
|
||||
|
@ -418,12 +428,14 @@ functions. All of these return Integrals rather than Reals.
|
|||
least Integral ``>= x``.
|
||||
|
||||
4. ``__round__(self)``, called from ``round(x)``, which returns the
|
||||
Integral closest to ``x``, rounding half toward even. The
|
||||
2-argument version should return a Real.
|
||||
Integral closest to ``x``, rounding half toward even. There is also
|
||||
a 2-argument version, ``__round__(self, other)``, called from
|
||||
``round(x, y)``, which should return a Real.
|
||||
|
||||
Because the ``int()`` conversion from ``float`` is equivalent to but
|
||||
less explicit than ``trunc()``, let's remove it. (Or, if that breaks
|
||||
too much, just add a deprecation warning.)
|
||||
Because the ``int()`` conversion implemented by ``float`` (and by
|
||||
``decimal.Decimal``) is equivalent to but less explicit than
|
||||
``trunc()``, let's remove it. (Or, if that breaks too much, just add a
|
||||
deprecation warning.)
|
||||
|
||||
``complex.__{divmod,mod,floordiv,int,float}__`` also go away. It would
|
||||
be nice to provide a nice error message to help confused porters, but
|
||||
|
@ -519,14 +531,14 @@ Rejected Alternatives
|
|||
The initial version of this PEP defined an algebraic hierarchy
|
||||
inspired by a Haskell Numeric Prelude [#numericprelude]_ including
|
||||
MonoidUnderPlus, AdditiveGroup, Ring, and Field, and mentioned several
|
||||
other possible algebraic types before getting to the numbers. I had
|
||||
other possible algebraic types before getting to the numbers. We had
|
||||
expected this to be useful to people using vectors and matrices, but
|
||||
the NumPy community really wasn't interested, and we ran into the
|
||||
issue that even if ``x`` is an instance of ``X <: MonoidUnderPlus``
|
||||
and ``y`` is an instance of ``Y <: MonoidUnderPlus``, ``x + y`` may
|
||||
still not make sense.
|
||||
|
||||
Then I gave the numbers a much more branching structure to include
|
||||
Then we gave the numbers a much more branching structure to include
|
||||
things like the Gaussian Integers and Z/nZ, which could be Complex but
|
||||
wouldn't necessarily support things like division. The community
|
||||
decided that this was too much complication for Python, so I've now
|
||||
|
@ -540,10 +552,11 @@ References
|
|||
.. [#pep3119] Introducing Abstract Base Classes
|
||||
(http://www.python.org/dev/peps/pep-3119/)
|
||||
|
||||
.. [#classtree] Possible Python 3K Class Tree?, wiki page created by Bill Janssen
|
||||
.. [#classtree] Possible Python 3K Class Tree?, wiki page by Bill Janssen
|
||||
(http://wiki.python.org/moin/AbstractBaseClasses)
|
||||
|
||||
.. [#numericprelude] NumericPrelude: An experimental alternative hierarchy of numeric type classes
|
||||
.. [#numericprelude] NumericPrelude: An experimental alternative hierarchy
|
||||
of numeric type classes
|
||||
(http://darcs.haskell.org/numericprelude/docs/html/index.html)
|
||||
|
||||
.. [#schemetower] The Scheme numerical tower
|
||||
|
|
Loading…
Reference in New Issue