From 4886cc331ff158f8ede74878a436adfad205bd2d Mon Sep 17 00:00:00 2001 From: Neal Norwitz Date: Mon, 21 Aug 2006 17:06:07 +0000 Subject: Get rid of most of the rest of coerce (slot is still there for now). --- BROKEN | 28 +++++++++++ Doc/api/abstract.tex | 14 ------ Doc/ref/ref3.tex | 127 +---------------------------------------------- Doc/tut/glossary.tex | 41 +++------------ Include/abstract.h | 18 ------- Include/object.h | 1 - Lib/test/test_builtin.py | 11 ---- Lib/test/test_complex.py | 3 -- Lib/test/test_descr.py | 35 +------------ Misc/NEWS | 81 ++++++++++++++++++++++++++++++ Misc/cheatsheet | 1 - Objects/abstract.c | 43 ++-------------- Objects/complexobject.c | 47 +----------------- Objects/floatobject.c | 27 +--------- Objects/intobject.c | 17 ++----- Objects/object.c | 20 +------- Objects/typeobject.c | 88 -------------------------------- PC/_winreg.c | 1 - Python/bltinmodule.c | 25 ---------- 19 files changed, 131 insertions(+), 497 deletions(-) diff --git a/BROKEN b/BROKEN index 6d1b4fe..3468e43 100644 --- a/BROKEN +++ b/BROKEN @@ -110,3 +110,31 @@ Traceback (most recent call last): File "../Lib/test/test_set.py", line 291, in test_remove self.assert_(self.thetype(self.word) in s) AssertionError + +//////////////////////////////////////////////////////////////////////// +test_compare +//////////////////////////////////////////////////////////////////////// +test test_compare failed -- Traceback (most recent call last): + File "/Users/nnorwitz/build/python/py3k.2/Lib/test/test_compare.py", line 28, in test_comparisons + self.assertEqual(a, b) +AssertionError: 2 != (2+0j) + +//////////////////////////////////////////////////////////////////////// +test_complex +//////////////////////////////////////////////////////////////////////// +====================================================================== +FAIL: test_pow (test.test_complex.ComplexTest) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/Users/nnorwitz/build/python/py3k.2/Lib/test/test_complex.py", line 130, in test_pow + self.assertEqual(a ** 0j, 1) +AssertionError: (1+0j) != 1 + +====================================================================== +FAIL: test_richcompare (test.test_complex.ComplexTest) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/Users/nnorwitz/build/python/py3k.2/Lib/test/test_complex.py", line 96, in test_richcompare + self.assertRaises(OverflowError, complex.__eq__, 1+1j, 1L<<10000) +AssertionError: OverflowError not raised + diff --git a/Doc/api/abstract.tex b/Doc/api/abstract.tex index 7c742a0..f35fb63 100644 --- a/Doc/api/abstract.tex +++ b/Doc/api/abstract.tex @@ -654,20 +654,6 @@ determination. statement \samp{\var{o1} |= \var{o2}}. \end{cfuncdesc} -\begin{cfuncdesc}{int}{PyNumber_Coerce}{PyObject **p1, PyObject **p2} - This function takes the addresses of two variables of type - \ctype{PyObject*}. If the objects pointed to by \code{*\var{p1}} - and \code{*\var{p2}} have the same type, increment their reference - count and return \code{0} (success). If the objects can be converted - to a common numeric type, replace \code{*p1} and \code{*p2} by their - converted value (with 'new' reference counts), and return \code{0}. - If no conversion is possible, or if some other error occurs, return - \code{-1} (failure) and don't increment the reference counts. The - call \code{PyNumber_Coerce(\&o1, \&o2)} is equivalent to the Python - statement \samp{\var{o1}, \var{o2} = coerce(\var{o1}, \var{o2})}. - \bifuncindex{coerce} -\end{cfuncdesc} - \begin{cfuncdesc}{PyObject*}{PyNumber_Int}{PyObject *o} Returns the \var{o} converted to an integer object on success, or \NULL{} on failure. If the argument is outside the integer range diff --git a/Doc/ref/ref3.tex b/Doc/ref/ref3.tex index 15fc188..f53dbe3 100644 --- a/Doc/ref/ref3.tex +++ b/Doc/ref/ref3.tex @@ -1645,7 +1645,7 @@ sequence types should implement addition (meaning concatenation) and multiplication (meaning repetition) by defining the methods \method{__add__()}, \method{__radd__()}, \method{__iadd__()}, \method{__mul__()}, \method{__rmul__()} and \method{__imul__()} described -below; they should not define \method{__coerce__()} or other numerical +below; they should not define other numerical operators. It is recommended that both mappings and sequences implement the \method{__contains__()} method to allow efficient use of the \code{in} operator; for mappings, \code{in} should be equivalent @@ -1689,7 +1689,7 @@ through the values. \ttindex{__imul__()} \ttindex{__contains__()} \ttindex{__iter__()}} -\withsubitem{(numeric object method)}{\ttindex{__coerce__()}} +\withsubitem{(numeric object method)} \begin{methoddesc}[container object]{__len__}{self} Called to implement the built-in function @@ -2012,129 +2012,6 @@ integer (int or long). \versionadded{2.5} \end{methoddesc} -\begin{methoddesc}[numeric object]{__coerce__}{self, other} -Called to implement ``mixed-mode'' numeric arithmetic. Should either -return a 2-tuple containing \var{self} and \var{other} converted to -a common numeric type, or \code{None} if conversion is impossible. When -the common type would be the type of \code{other}, it is sufficient to -return \code{None}, since the interpreter will also ask the other -object to attempt a coercion (but sometimes, if the implementation of -the other type cannot be changed, it is useful to do the conversion to -the other type here). A return value of \code{NotImplemented} is -equivalent to returning \code{None}. -\end{methoddesc} - -\subsection{Coercion rules\label{coercion-rules}} - -This section used to document the rules for coercion. As the language -has evolved, the coercion rules have become hard to document -precisely; documenting what one version of one particular -implementation does is undesirable. Instead, here are some informal -guidelines regarding coercion. In Python 3.0, coercion will not be -supported. - -\begin{itemize} - -\item - -If the left operand of a \% operator is a string or Unicode object, no -coercion takes place and the string formatting operation is invoked -instead. - -\item - -It is no longer recommended to define a coercion operation. -Mixed-mode operations on types that don't define coercion pass the -original arguments to the operation. - -\item - -New-style classes (those derived from \class{object}) never invoke the -\method{__coerce__()} method in response to a binary operator; the only -time \method{__coerce__()} is invoked is when the built-in function -\function{coerce()} is called. - -\item - -For most intents and purposes, an operator that returns -\code{NotImplemented} is treated the same as one that is not -implemented at all. - -\item - -Below, \method{__op__()} and \method{__rop__()} are used to signify -the generic method names corresponding to an operator; -\method{__iop__()} is used for the corresponding in-place operator. For -example, for the operator `\code{+}', \method{__add__()} and -\method{__radd__()} are used for the left and right variant of the -binary operator, and \method{__iadd__()} for the in-place variant. - -\item - -For objects \var{x} and \var{y}, first \code{\var{x}.__op__(\var{y})} -is tried. If this is not implemented or returns \code{NotImplemented}, -\code{\var{y}.__rop__(\var{x})} is tried. If this is also not -implemented or returns \code{NotImplemented}, a \exception{TypeError} -exception is raised. But see the following exception: - -\item - -Exception to the previous item: if the left operand is an instance of -a built-in type or a new-style class, and the right operand is an instance -of a proper subclass of that type or class and overrides the base's -\method{__rop__()} method, the right operand's \method{__rop__()} method -is tried \emph{before} the left operand's \method{__op__()} method. - -This is done so that a subclass can completely override binary operators. -Otherwise, the left operand's \method{__op__()} method would always -accept the right operand: when an instance of a given class is expected, -an instance of a subclass of that class is always acceptable. - -\item - -When either operand type defines a coercion, this coercion is called -before that type's \method{__op__()} or \method{__rop__()} method is -called, but no sooner. If the coercion returns an object of a -different type for the operand whose coercion is invoked, part of the -process is redone using the new object. - -\item - -When an in-place operator (like `\code{+=}') is used, if the left -operand implements \method{__iop__()}, it is invoked without any -coercion. When the operation falls back to \method{__op__()} and/or -\method{__rop__()}, the normal coercion rules apply. - -\item - -In \var{x}\code{+}\var{y}, if \var{x} is a sequence that implements -sequence concatenation, sequence concatenation is invoked. - -\item - -In \var{x}\code{*}\var{y}, if one operator is a sequence that -implements sequence repetition, and the other is an integer -(\class{int} or \class{long}), sequence repetition is invoked. - -\item - -Rich comparisons (implemented by methods \method{__eq__()} and so on) -never use coercion. Three-way comparison (implemented by -\method{__cmp__()}) does use coercion under the same conditions as -other binary operations use it. - -\item - -In the current implementation, the built-in numeric types \class{int}, -\class{long} and \class{float} do not use coercion; the type -\class{complex} however does use it. The difference can become -apparent when subclassing these types. Over time, the type -\class{complex} may be fixed to avoid coercion. All these types -implement a \method{__coerce__()} method, for use by the built-in -\function{coerce()} function. - -\end{itemize} - \subsection{With Statement Context Managers\label{context-managers}} \versionadded{2.5} diff --git a/Doc/tut/glossary.tex b/Doc/tut/glossary.tex index 17cc767..738e12d 100644 --- a/Doc/tut/glossary.tex +++ b/Doc/tut/glossary.tex @@ -35,21 +35,6 @@ machine'' that calls the subroutines corresponding to each bytecode. Any class which does not inherit from \class{object}. See \emph{new-style class}. -\index{coercion} -\item[coercion] -The implicit conversion of an instance of one type to another during an -operation which involves two arguments of the same type. For example, -{}\code{int(3.15)} converts the floating point number to the integer -{}\code{3}, but in {}\code{3+4.5}, each argument is of a different type (one -int, one float), and both must be converted to the same type before they can -be added or it will raise a {}\code{TypeError}. Coercion between two -operands can be performed with the {}\code{coerce} builtin function; thus, -{}\code{3+4.5} is equivalent to calling {}\code{operator.add(*coerce(3, -4.5))} and results in {}\code{operator.add(3.0, 4.5)}. Without coercion, -all arguments of even compatible types would have to be normalized to the -same value by the programmer, e.g., {}\code{float(3)+4.5} rather than just -{}\code{3+4.5}. - \index{complex number} \item[complex number] An extension of the familiar real number system in which all numbers are @@ -106,17 +91,14 @@ fast style is characterized by the presence of many \keyword{try} and \index{__future__} \item[__future__] A pseudo module which programmers can use to enable new language -features which are not compatible with the current interpreter. For -example, the expression \code{11/4} currently evaluates to \code{2}. -If the module in which it is executed had enabled \emph{true division} -by executing: +features which are not compatible with the current interpreter. +To enable \code{new_feature} \begin{verbatim} -from __future__ import division +from __future__ import new_feature \end{verbatim} -the expression \code{11/4} would evaluate to \code{2.75}. By -importing the \ulink{\module{__future__}}{../lib/module-future.html} +By importing the \ulink{\module{__future__}}{../lib/module-future.html} module and evaluating its variables, you can see when a new feature was first added to the language and when it will become the default: @@ -183,17 +165,10 @@ example as a key in a dictionary. \index{integer division} \item[integer division] -Mathematical division discarding any remainder. For example, the -expression \code{11/4} currently evaluates to \code{2} in contrast -to the \code{2.75} returned by float division. Also called -{}\emph{floor division}. When dividing two integers the outcome will -always be another integer (having the floor function applied to it). -However, if one of the operands is another numeric type (such as a -{}\class{float}), the result will be coerced (see \emph{coercion}) to -a common type. For example, an integer divided by a float will result -in a float value, possibly with a decimal fraction. Integer division -can be forced by using the \code{//} operator instead of the \code{/} -operator. See also \emph{__future__}. +Mathematical division including any remainder. The result will always +be a float. For example, the expression \code{11/4} evaluates to \code{2.75}. +Integer division can be forced by using the \code{//} operator instead +of the \code{/} operator. \index{interactive} \item[interactive] diff --git a/Include/abstract.h b/Include/abstract.h index eed23c1..eaac278 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -694,24 +694,6 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ expression: o1|o2. */ - /* Implemented elsewhere: - - int PyNumber_Coerce(PyObject **p1, PyObject **p2); - - This function takes the addresses of two variables of type - PyObject*. - - If the objects pointed to by *p1 and *p2 have the same type, - increment their reference count and return 0 (success). - If the objects can be converted to a common numeric type, - replace *p1 and *p2 by their converted value (with 'new' - reference counts), and return 0. - If no conversion is possible, or if some other error occurs, - return -1 (failure) and don't increment the reference counts. - The call PyNumber_Coerce(&o1, &o2) is equivalent to the Python - statement o1, o2 = coerce(o1, o2). - */ - PyAPI_FUNC(Py_ssize_t) PyNumber_Index(PyObject *); /* diff --git a/Include/object.h b/Include/object.h index a9a880a..b69ee31 100644 --- a/Include/object.h +++ b/Include/object.h @@ -393,7 +393,6 @@ PyAPI_FUNC(long) PyObject_Hash(PyObject *); PyAPI_FUNC(int) PyObject_IsTrue(PyObject *); PyAPI_FUNC(int) PyObject_Not(PyObject *); PyAPI_FUNC(int) PyCallable_Check(PyObject *); -PyAPI_FUNC(int) PyNumber_Coerce(PyObject **, PyObject **); PyAPI_FUNC(int) PyNumber_CoerceEx(PyObject **, PyObject **); PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 5797aef..13a5241 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -196,17 +196,6 @@ class BuiltinTest(unittest.TestCase): a.pop(); b.pop(); c.pop() self.assertRaises(TypeError, cmp) - def test_coerce(self): - self.assert_(not fcmp(coerce(1, 1.1), (1.0, 1.1))) - self.assertEqual(coerce(1, 1L), (1L, 1L)) - self.assert_(not fcmp(coerce(1L, 1.1), (1.0, 1.1))) - self.assertRaises(TypeError, coerce) - class BadNumber: - def __coerce__(self, other): - raise ValueError - self.assertRaises(ValueError, coerce, 42, BadNumber()) - self.assertRaises(OverflowError, coerce, 0.5, int("12345" * 1000)) - def test_compile(self): compile('print 1\n', '', 'exec') bom = '\xef\xbb\xbf' diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index 035f524..4aa799d 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -92,9 +92,6 @@ class ComplexTest(unittest.TestCase): self.assertAlmostEqual(complex.__floordiv__(3+0j, 1.5+0j), 2) self.assertRaises(ZeroDivisionError, complex.__floordiv__, 3+0j, 0+0j) - def test_coerce(self): - self.assertRaises(OverflowError, complex.__coerce__, 1+1j, 1L<<10000) - def test_richcompare(self): self.assertRaises(OverflowError, complex.__eq__, 1+1j, 1L<<10000) self.assertEqual(complex.__lt__(1+1j, None), NotImplemented) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 01fd685..00800a7 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -2567,33 +2567,6 @@ def rich_comparisons(): verify(eval("x %s c[y]" % op) == eval("x %s y" % op), "x=%d, y=%d" % (x, y)) -def coercions(): - if verbose: print "Testing coercions..." - class I(int): pass - coerce(I(0), 0) - coerce(0, I(0)) - class L(long): pass - coerce(L(0), 0) - coerce(L(0), 0L) - coerce(0, L(0)) - coerce(0L, L(0)) - class F(float): pass - coerce(F(0), 0) - coerce(F(0), 0L) - coerce(F(0), 0.) - coerce(0, F(0)) - coerce(0L, F(0)) - coerce(0., F(0)) - class C(complex): pass - coerce(C(0), 0) - coerce(C(0), 0L) - coerce(C(0), 0.) - coerce(C(0), 0j) - coerce(0, C(0)) - coerce(0L, C(0)) - coerce(0., C(0)) - coerce(0j, C(0)) - def descrdoc(): if verbose: print "Testing descriptor doc strings..." def check(descr, what): @@ -3961,11 +3934,8 @@ def notimplemented(): ('__and__', 'x & y', 'x &= y'), ('__or__', 'x | y', 'x |= y'), ('__xor__', 'x ^ y', 'x ^= y'), - ('__coerce__', 'coerce(x, y)', None)]: - if name == '__coerce__': - rname = name - else: - rname = '__r' + name[2:] + ]: + rname = '__r' + name[2:] A = metaclass('A', (), {name: specialmethod}) B = metaclass('B', (), {rname: specialmethod}) a = A() @@ -4043,7 +4013,6 @@ def test_main(): str_subclass_as_dict_key() classic_comparisons() rich_comparisons() - coercions() descrdoc() setclass() setdict() diff --git a/Misc/NEWS b/Misc/NEWS index 0c97898..b8314cd 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -7,6 +7,87 @@ Python News What's New in Python 3000? ========================== +*Release date: XX-XXX-200X* + +TO DO +----- + +- See PEP 3000. + +- Test merging certain changes from the 2.5 HEAD code. + +- Weed really old/weird stuff from the library. + +- Unify range() and xrange(). + +- Revamp the dict API: keys(), values(), items() return iterators, etc. + +- Add the bytes type. + +- Rework the standard I/O library to use bytes for binary files. + +- Make strings all Unicode. + +- Get rid of classic class implementation. + +- Get rid of various compatibility-related flags (e.g. division flags). + +Core and Builtins +----------------- + +- __coerce__ has been removed. + +- Classic classes are a thing of the past. All classes are new style. + +- Exceptions *must* derive from BaseException. + +- Integer division always returns a float. The -Q option is no more. + All the following are gone: + * PyNumber_Divide and PyNumber_InPlaceDivide + * __div__, __rdiv__, and __idiv__ + * nb_divide, nb_inplace_divide + * operator.div, operator.idiv, operator.__div__, operator.__idiv__ + (Only __truediv__ and __floordiv__ remain, not sure how to handle them + if we want to re-use __div__ and friends. If we do, it will make + it harder to write code for both 2.x and 3.x.) + +- 'as' and 'with' are keywords. + +- Absolute import is the default behavior for 'import foo' etc. + +- Removed these Python builtins: + apply(), coerce(), input(), raw_input() + +- Removed these Python slots: + __coerce__, __div__, __idiv__, __rdiv__ + +- Removed these attributes from Python modules: + * operator module: div, idiv, __div__, __idiv__ + +*** PyNumber_CoerceEx() and nb_coerce still need to be removed. + +- Removed these C APIs: + PyNumber_Coerce(), + +- Removed these C slots/fields: + nb_divide, nb_inplace_divide + +- Removed these macros: + staticforward, statichere, PyArg_GetInt, PyArg_NoArgs + +- Removed these typedefs: + intargfunc, intintargfunc, intobjargproc, intintobjargproc, + getreadbufferproc, getwritebufferproc, getsegcountproc, getcharbufferproc + +- Removed these opcodes: + BINARY_DIVIDE, INPLACE_DIVIDE + +Extension Modules +----------------- + +Library +------- + Build ----- diff --git a/Misc/cheatsheet b/Misc/cheatsheet index b0e1cce..65b1400 100644 --- a/Misc/cheatsheet +++ b/Misc/cheatsheet @@ -1188,7 +1188,6 @@ Operators int(s) = __int__(s) long(s) = __long__(s) float(s) = __float__(s) complex(s) = __complex__(s) oct(s) = __oct__(s) hex(s) = __hex__(s) - coerce(s,o) = __coerce__(s,o) Right-hand-side equivalents for all binary operators exist; are called when class instance is on r-h-s of operator: a + 3 calls __add__(a, 3) diff --git a/Objects/abstract.c b/Objects/abstract.c index ee137fe..79dfe40 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -339,8 +339,6 @@ PyNumber_Check(PyObject *o) /* Binary operators */ -/* New style number protocol support */ - #define NB_SLOT(x) offsetof(PyNumberMethods, x) #define NB_BINOP(nb_methods, slot) \ (*(binaryfunc*)(& ((char*)nb_methods)[slot])) @@ -350,23 +348,11 @@ PyNumber_Check(PyObject *o) /* Calling scheme used for binary operations: - v w Action - ------------------------------------------------------------------- - new new w.op(v,w)[*], v.op(v,w), w.op(v,w) - new old v.op(v,w), coerce(v,w), v.op(v,w) - old new w.op(v,w), coerce(v,w), v.op(v,w) - old old coerce(v,w), v.op(v,w) + Order operations are tried until either a valid result or error: + w.op(v,w)[*], v.op(v,w), w.op(v,w) [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of v->ob_type - - Legend: - ------- - * new == new style number - * old == old style number - * Action indicates the order in which operations are tried until either - a valid result is produced or an error occurs. - */ static PyObject * @@ -434,29 +420,8 @@ binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name) /* Calling scheme used for ternary operations: - *** In some cases, w.op is called before v.op; see binary_op1. *** - - v w z Action - ------------------------------------------------------------------- - new new new v.op(v,w,z), w.op(v,w,z), z.op(v,w,z) - new old new v.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z) - old new new w.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z) - old old new z.op(v,w,z), coerce(v,w,z), v.op(v,w,z) - new new old v.op(v,w,z), w.op(v,w,z), coerce(v,w,z), v.op(v,w,z) - new old old v.op(v,w,z), coerce(v,w,z), v.op(v,w,z) - old new old w.op(v,w,z), coerce(v,w,z), v.op(v,w,z) - old old old coerce(v,w,z), v.op(v,w,z) - - Legend: - ------- - * new == new style number - * old == old style number - * Action indicates the order in which operations are tried until either - a valid result is produced or an error occurs. - * coerce(v,w,z) actually does: coerce(v,w), coerce(v,z), coerce(w,z) and - only if z != Py_None; if z == Py_None, then it is treated as absent - variable and only coerce(v,w) is tried. - + Order operations are tried until either a valid result or error: + v.op(v,w,z), w.op(v,w,z), z.op(v,w,z) */ static PyObject * diff --git a/Objects/complexobject.c b/Objects/complexobject.c index aa8fc81..e081256 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -573,65 +573,20 @@ complex_nonzero(PyComplexObject *v) return v->cval.real != 0.0 || v->cval.imag != 0.0; } -static int -complex_coerce(PyObject **pv, PyObject **pw) -{ - Py_complex cval; - cval.imag = 0.; - if (PyInt_Check(*pw)) { - cval.real = (double)PyInt_AsLong(*pw); - *pw = PyComplex_FromCComplex(cval); - Py_INCREF(*pv); - return 0; - } - else if (PyLong_Check(*pw)) { - cval.real = PyLong_AsDouble(*pw); - if (cval.real == -1.0 && PyErr_Occurred()) - return -1; - *pw = PyComplex_FromCComplex(cval); - Py_INCREF(*pv); - return 0; - } - else if (PyFloat_Check(*pw)) { - cval.real = PyFloat_AsDouble(*pw); - *pw = PyComplex_FromCComplex(cval); - Py_INCREF(*pv); - return 0; - } - else if (PyComplex_Check(*pw)) { - Py_INCREF(*pv); - Py_INCREF(*pw); - return 0; - } - return 1; /* Can't do it */ -} - static PyObject * complex_richcompare(PyObject *v, PyObject *w, int op) { - int c; Py_complex i, j; PyObject *res; - c = PyNumber_CoerceEx(&v, &w); - if (c < 0) - return NULL; - if (c > 0) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } /* Make sure both arguments are complex. */ if (!(PyComplex_Check(v) && PyComplex_Check(w))) { - Py_DECREF(v); - Py_DECREF(w); Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } i = ((PyComplexObject *)v)->cval; j = ((PyComplexObject *)w)->cval; - Py_DECREF(v); - Py_DECREF(w); if (op != Py_EQ && op != Py_NE) { PyErr_SetString(PyExc_TypeError, @@ -996,7 +951,7 @@ static PyNumberMethods complex_as_number = { 0, /* nb_and */ 0, /* nb_xor */ 0, /* nb_or */ - complex_coerce, /* nb_coerce */ + (coercion)0, /* nb_coerce */ complex_int, /* nb_int */ complex_long, /* nb_long */ complex_float, /* nb_float */ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index cb0d999..40126b2 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -842,31 +842,6 @@ float_nonzero(PyFloatObject *v) return v->ob_fval != 0.0; } -static int -float_coerce(PyObject **pv, PyObject **pw) -{ - if (PyInt_Check(*pw)) { - long x = PyInt_AsLong(*pw); - *pw = PyFloat_FromDouble((double)x); - Py_INCREF(*pv); - return 0; - } - else if (PyLong_Check(*pw)) { - double x = PyLong_AsDouble(*pw); - if (x == -1.0 && PyErr_Occurred()) - return -1; - *pw = PyFloat_FromDouble(x); - Py_INCREF(*pv); - return 0; - } - else if (PyFloat_Check(*pw)) { - Py_INCREF(*pv); - Py_INCREF(*pw); - return 0; - } - return 1; /* Can't do it */ -} - static PyObject * float_long(PyObject *v) { @@ -1119,7 +1094,7 @@ static PyNumberMethods float_as_number = { 0, /*nb_and*/ 0, /*nb_xor*/ 0, /*nb_or*/ - float_coerce, /*nb_coerce*/ + (coercion)0, /*nb_coerce*/ float_int, /*nb_int*/ float_long, /*nb_long*/ float_float, /*nb_float*/ diff --git a/Objects/intobject.c b/Objects/intobject.c index c378b85..f070404 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -580,7 +580,7 @@ i_divmod(register long x, register long y, } static PyObject * -int_div(PyIntObject *x, PyIntObject *y) +int_floor_div(PyIntObject *x, PyIntObject *y) { long xi, yi; long d, m; @@ -872,17 +872,6 @@ int_or(PyIntObject *v, PyIntObject *w) return PyInt_FromLong(a | b); } -static int -int_coerce(PyObject **pv, PyObject **pw) -{ - if (PyInt_Check(*pw)) { - Py_INCREF(*pv); - Py_INCREF(*pw); - return 0; - } - return 1; /* Can't do it */ -} - static PyObject * int_int(PyIntObject *v) { @@ -1036,7 +1025,7 @@ static PyNumberMethods int_as_number = { (binaryfunc)int_and, /*nb_and*/ (binaryfunc)int_xor, /*nb_xor*/ (binaryfunc)int_or, /*nb_or*/ - int_coerce, /*nb_coerce*/ + 0, /*nb_coerce*/ (unaryfunc)int_int, /*nb_int*/ (unaryfunc)int_long, /*nb_long*/ (unaryfunc)int_float, /*nb_float*/ @@ -1052,7 +1041,7 @@ static PyNumberMethods int_as_number = { 0, /*nb_inplace_and*/ 0, /*nb_inplace_xor*/ 0, /*nb_inplace_or*/ - (binaryfunc)int_div, /* nb_floor_divide */ + (binaryfunc)int_floor_div, /* nb_floor_divide */ int_true_divide, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ diff --git a/Objects/object.c b/Objects/object.c index 516098d..44b3f7d 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -681,9 +681,7 @@ try_3way_compare(PyObject *v, PyObject *w) b) have different types or a type without tp_compare; and c) don't have a user-defined tp_compare. tp_compare implementations in C assume that both arguments - have their type, so we give up if the coercion fails or if - it yields types which are still incompatible (which can - happen with a user-defined nb_coerce). + have their type, so we give up if the coercion fails. */ c = PyNumber_CoerceEx(&v, &w); if (c < 0) @@ -1513,22 +1511,6 @@ PyNumber_CoerceEx(PyObject **pv, PyObject **pw) return 1; } -/* Coerce two numeric types to the "larger" one. - Increment the reference count on each argument. - Return -1 and raise an exception if no coercion is possible - (and then no reference count is incremented). -*/ -int -PyNumber_Coerce(PyObject **pv, PyObject **pw) -{ - int err = PyNumber_CoerceEx(pv, pw); - if (err <= 0) - return err; - PyErr_SetString(PyExc_TypeError, "number coercion failed"); - return -1; -} - - /* Test whether an object can be called */ int diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 02d45bd..e9ffa87 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3327,34 +3327,6 @@ wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped) } static PyObject * -wrap_coercefunc(PyObject *self, PyObject *args, void *wrapped) -{ - coercion func = (coercion)wrapped; - PyObject *other, *res; - int ok; - - if (!check_num_args(args, 1)) - return NULL; - other = PyTuple_GET_ITEM(args, 0); - ok = func(&self, &other); - if (ok < 0) - return NULL; - if (ok > 0) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - res = PyTuple_New(2); - if (res == NULL) { - Py_DECREF(self); - Py_DECREF(other); - return NULL; - } - PyTuple_SET_ITEM(res, 0, self); - PyTuple_SET_ITEM(res, 1, other); - return res; -} - -static PyObject * wrap_ternaryfunc(PyObject *self, PyObject *args, void *wrapped) { ternaryfunc func = (ternaryfunc)wrapped; @@ -4247,64 +4219,6 @@ SLOT1BIN(slot_nb_and, nb_and, "__and__", "__rand__") SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__") SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__") -static int -slot_nb_coerce(PyObject **a, PyObject **b) -{ - static PyObject *coerce_str; - PyObject *self = *a, *other = *b; - - if (self->ob_type->tp_as_number != NULL && - self->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) { - PyObject *r; - r = call_maybe( - self, "__coerce__", &coerce_str, "(O)", other); - if (r == NULL) - return -1; - if (r == Py_NotImplemented) { - Py_DECREF(r); - } - else { - if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { - PyErr_SetString(PyExc_TypeError, - "__coerce__ didn't return a 2-tuple"); - Py_DECREF(r); - return -1; - } - *a = PyTuple_GET_ITEM(r, 0); - Py_INCREF(*a); - *b = PyTuple_GET_ITEM(r, 1); - Py_INCREF(*b); - Py_DECREF(r); - return 0; - } - } - if (other->ob_type->tp_as_number != NULL && - other->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) { - PyObject *r; - r = call_maybe( - other, "__coerce__", &coerce_str, "(O)", self); - if (r == NULL) - return -1; - if (r == Py_NotImplemented) { - Py_DECREF(r); - return 1; - } - if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { - PyErr_SetString(PyExc_TypeError, - "__coerce__ didn't return a 2-tuple"); - Py_DECREF(r); - return -1; - } - *a = PyTuple_GET_ITEM(r, 1); - Py_INCREF(*a); - *b = PyTuple_GET_ITEM(r, 0); - Py_INCREF(*b); - Py_DECREF(r); - return 0; - } - return 1; -} - SLOT0(slot_nb_int, "__int__") SLOT0(slot_nb_long, "__long__") SLOT0(slot_nb_float, "__float__") @@ -4958,8 +4872,6 @@ static slotdef slotdefs[] = { RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"), BINSLOT("__or__", nb_or, slot_nb_or, "|"), RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), - NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc, - "x.__coerce__(y) <==> coerce(x, y)"), UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, "int(x)"), UNSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc, diff --git a/PC/_winreg.c b/PC/_winreg.c index 5ed3f6c..c501033 100644 --- a/PC/_winreg.c +++ b/PC/_winreg.c @@ -444,7 +444,6 @@ static PyNumberMethods PyHKEY_NumberMethods = PyHKEY_binaryFailureFunc, /* nb_and */ PyHKEY_binaryFailureFunc, /* nb_xor */ PyHKEY_binaryFailureFunc, /* nb_or */ - 0, /* nb_coerce (allowed to be zero) */ PyHKEY_intFunc, /* nb_int */ PyHKEY_unaryFailureFunc, /* nb_long */ PyHKEY_unaryFailureFunc, /* nb_float */ diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 8f1f464..8b92c87 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -333,30 +333,6 @@ PyDoc_STRVAR(cmp_doc, \n\ Return negative if xy."); - -static PyObject * -builtin_coerce(PyObject *self, PyObject *args) -{ - PyObject *v, *w; - PyObject *res; - - if (!PyArg_UnpackTuple(args, "coerce", 2, 2, &v, &w)) - return NULL; - if (PyNumber_Coerce(&v, &w) < 0) - return NULL; - res = PyTuple_Pack(2, v, w); - Py_DECREF(v); - Py_DECREF(w); - return res; -} - -PyDoc_STRVAR(coerce_doc, -"coerce(x, y) -> (x1, y1)\n\ -\n\ -Return a tuple consisting of the two numeric arguments converted to\n\ -a common type, using the same rules as used by arithmetic operations.\n\ -If coercion is not possible, raise TypeError."); - static PyObject * builtin_compile(PyObject *self, PyObject *args) { @@ -2068,7 +2044,6 @@ static PyMethodDef builtin_methods[] = { {"callable", builtin_callable, METH_O, callable_doc}, {"chr", builtin_chr, METH_VARARGS, chr_doc}, {"cmp", builtin_cmp, METH_VARARGS, cmp_doc}, - {"coerce", builtin_coerce, METH_VARARGS, coerce_doc}, {"compile", builtin_compile, METH_VARARGS, compile_doc}, {"delattr", builtin_delattr, METH_VARARGS, delattr_doc}, {"dir", builtin_dir, METH_VARARGS, dir_doc}, -- cgit v0.12