summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-08-08 05:00:18 (GMT)
committerGuido van Rossum <guido@python.org>2001-08-08 05:00:18 (GMT)
commit4668b000a1d9113394941ad39875c827634feb49 (patch)
tree734560442fef1ce34912ceb772099b9a006e010a /Objects
parent074c9d2b2081237c1071a3775f6e36252cf16ad7 (diff)
downloadcpython-4668b000a1d9113394941ad39875c827634feb49.zip
cpython-4668b000a1d9113394941ad39875c827634feb49.tar.gz
cpython-4668b000a1d9113394941ad39875c827634feb49.tar.bz2
Implement PEP 238 in its (almost) full glory.
This introduces: - A new operator // that means floor division (the kind of division where 1/2 is 0). - The "future division" statement ("from __future__ import division) which changes the meaning of the / operator to implement "true division" (where 1/2 is 0.5). - New overloadable operators __truediv__ and __floordiv__. - New slots in the PyNumberMethods struct for true and floor division, new abstract APIs for them, new opcodes, and so on. I emphasize that without the future division statement, the semantics of / will remain unchanged until Python 3.0. Not yet implemented are warnings (default off) when / is used with int or long arguments. This has been on display since 7/31 as SF patch #443474. Flames to /dev/null.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c30
-rw-r--r--Objects/classobject.c8
-rw-r--r--Objects/complexobject.c30
-rw-r--r--Objects/floatobject.c45
-rw-r--r--Objects/intobject.c10
-rw-r--r--Objects/longobject.c32
6 files changed, 131 insertions, 24 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index a0f075f..b646c36 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -565,6 +565,20 @@ PyNumber_Add(PyObject *v, PyObject *w)
}
PyObject *
+PyNumber_FloorDivide(PyObject *v, PyObject *w)
+{
+ /* XXX tp_flags test */
+ return binary_op(v, w, NB_SLOT(nb_floor_divide), "//");
+}
+
+PyObject *
+PyNumber_TrueDivide(PyObject *v, PyObject *w)
+{
+ /* XXX tp_flags test */
+ return binary_op(v, w, NB_SLOT(nb_true_divide), "/");
+}
+
+PyObject *
PyNumber_Remainder(PyObject *v, PyObject *w)
{
if (PyString_Check(v))
@@ -631,6 +645,22 @@ INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=")
INPLACE_BINOP(PyNumber_InPlaceDivide, nb_inplace_divide, nb_divide, "/=")
PyObject *
+PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w)
+{
+ /* XXX tp_flags test */
+ return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide),
+ NB_SLOT(nb_floor_divide), "//=");
+}
+
+PyObject *
+PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w)
+{
+ /* XXX tp_flags test */
+ return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide),
+ NB_SLOT(nb_true_divide), "/=");
+}
+
+PyObject *
PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
{
binaryfunc f = NULL;
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 4bad2fd..9c01538 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -1435,6 +1435,8 @@ BINARY(instance_mul, "mul", PyNumber_Multiply)
BINARY(instance_div, "div", PyNumber_Divide)
BINARY(instance_mod, "mod", PyNumber_Remainder)
BINARY(instance_divmod, "divmod", PyNumber_Divmod)
+BINARY(instance_floordiv, "floordiv", PyNumber_FloorDivide)
+BINARY(instance_truediv, "truediv", PyNumber_TrueDivide)
BINARY_INPLACE(instance_ior, "or", PyNumber_InPlaceOr)
BINARY_INPLACE(instance_ixor, "xor", PyNumber_InPlaceXor)
@@ -1446,6 +1448,8 @@ BINARY_INPLACE(instance_isub, "sub", PyNumber_InPlaceSubtract)
BINARY_INPLACE(instance_imul, "mul", PyNumber_InPlaceMultiply)
BINARY_INPLACE(instance_idiv, "div", PyNumber_InPlaceDivide)
BINARY_INPLACE(instance_imod, "mod", PyNumber_InPlaceRemainder)
+BINARY_INPLACE(instance_ifloordiv, "floordiv", PyNumber_InPlaceFloorDivide)
+BINARY_INPLACE(instance_itruediv, "truediv", PyNumber_InPlaceTrueDivide)
/* Try a 3-way comparison, returning an int; v is an instance. Return:
-2 for an exception;
@@ -1900,6 +1904,10 @@ static PyNumberMethods instance_as_number = {
(binaryfunc)instance_iand, /* nb_inplace_and */
(binaryfunc)instance_ixor, /* nb_inplace_xor */
(binaryfunc)instance_ior, /* nb_inplace_or */
+ (binaryfunc)instance_floordiv, /* nb_floor_divide */
+ (binaryfunc)instance_truediv, /* nb_true_divide */
+ (binaryfunc)instance_ifloordiv, /* nb_inplace_floor_divide */
+ (binaryfunc)instance_itruediv, /* nb_inplace_true_divide */
};
PyTypeObject PyInstance_Type = {
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index 9a66c0c..5cfb3ca 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -442,6 +442,21 @@ complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
}
static PyObject *
+complex_int_div(PyComplexObject *v, PyComplexObject *w)
+{
+ PyObject *t, *r;
+
+ t = complex_divmod(v, w);
+ if (t != NULL) {
+ r = PyTuple_GET_ITEM(t, 0);
+ Py_INCREF(r);
+ Py_DECREF(t);
+ return r;
+ }
+ return NULL;
+}
+
+static PyObject *
complex_neg(PyComplexObject *v)
{
Py_complex neg;
@@ -859,6 +874,21 @@ static PyNumberMethods complex_as_number = {
(unaryfunc)complex_float, /* nb_float */
0, /* nb_oct */
0, /* nb_hex */
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply*/
+ 0, /* nb_inplace_divide */
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ (binaryfunc)complex_int_div, /* nb_floor_divide */
+ (binaryfunc)complex_div, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
};
PyTypeObject PyComplex_Type = {
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index df88736..34b252b 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -558,6 +558,21 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
}
static PyObject *
+float_int_div(PyObject *v, PyObject *w)
+{
+ PyObject *t, *r;
+
+ t = float_divmod(v, w);
+ if (t != NULL) {
+ r = PyTuple_GET_ITEM(t, 0);
+ Py_INCREF(r);
+ Py_DECREF(t);
+ return r;
+ }
+ return NULL;
+}
+
+static PyObject *
float_neg(PyFloatObject *v)
{
return PyFloat_FromDouble(-v->ob_fval);
@@ -678,19 +693,23 @@ static PyNumberMethods float_as_number = {
(unaryfunc)float_int, /*nb_int*/
(unaryfunc)float_long, /*nb_long*/
(unaryfunc)float_float, /*nb_float*/
- 0, /*nb_oct*/
- 0, /*nb_hex*/
- 0, /*nb_inplace_add*/
- 0, /*nb_inplace_subtract*/
- 0, /*nb_inplace_multiply*/
- 0, /*nb_inplace_divide*/
- 0, /*nb_inplace_remainder*/
- 0, /*nb_inplace_power*/
- 0, /*nb_inplace_lshift*/
- 0, /*nb_inplace_rshift*/
- 0, /*nb_inplace_and*/
- 0, /*nb_inplace_xor*/
- 0, /*nb_inplace_or*/
+ 0, /* nb_oct */
+ 0, /* nb_hex */
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply */
+ 0, /* nb_inplace_divide */
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ float_int_div, /* nb_floor_divide */
+ float_div, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
};
PyTypeObject PyFloat_Type = {
diff --git a/Objects/intobject.c b/Objects/intobject.c
index e5106c5..f69f81a 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -703,6 +703,12 @@ int_or(PyIntObject *v, PyIntObject *w)
}
static PyObject *
+int_true_divide(PyObject *v, PyObject *w)
+{
+ return PyFloat_Type.tp_as_number->nb_divide(v, w);
+}
+
+static PyObject *
int_int(PyIntObject *v)
{
Py_INCREF(v);
@@ -812,6 +818,10 @@ static PyNumberMethods int_as_number = {
0, /*nb_inplace_and*/
0, /*nb_inplace_xor*/
0, /*nb_inplace_or*/
+ (binaryfunc)int_div, /* nb_floor_divide */
+ int_true_divide, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
};
PyTypeObject PyInt_Type = {
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 28c3e57..9f7272c 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -1981,6 +1981,12 @@ long_or(PyObject *v, PyObject *w)
return c;
}
+static PyObject *
+long_true_divide(PyObject *v, PyObject *w)
+{
+ return PyFloat_Type.tp_as_number->nb_divide(v, w);
+}
+
static int
long_coerce(PyObject **pv, PyObject **pw)
{
@@ -2092,17 +2098,21 @@ static PyNumberMethods long_as_number = {
(unaryfunc) long_float, /*nb_float*/
(unaryfunc) long_oct, /*nb_oct*/
(unaryfunc) long_hex, /*nb_hex*/
- 0, /*nb_inplace_add*/
- 0, /*nb_inplace_subtract*/
- 0, /*nb_inplace_multiply*/
- 0, /*nb_inplace_divide*/
- 0, /*nb_inplace_remainder*/
- 0, /*nb_inplace_power*/
- 0, /*nb_inplace_lshift*/
- 0, /*nb_inplace_rshift*/
- 0, /*nb_inplace_and*/
- 0, /*nb_inplace_xor*/
- 0, /*nb_inplace_or*/
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply */
+ 0, /* nb_inplace_divide */
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ (binaryfunc)long_div, /* nb_floor_divide */
+ long_true_divide, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
};
PyTypeObject PyLong_Type = {