diff options
author | Guido van Rossum <guido@python.org> | 2001-08-08 05:00:18 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-08-08 05:00:18 (GMT) |
commit | 4668b000a1d9113394941ad39875c827634feb49 (patch) | |
tree | 734560442fef1ce34912ceb772099b9a006e010a /Objects | |
parent | 074c9d2b2081237c1071a3775f6e36252cf16ad7 (diff) | |
download | cpython-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.c | 30 | ||||
-rw-r--r-- | Objects/classobject.c | 8 | ||||
-rw-r--r-- | Objects/complexobject.c | 30 | ||||
-rw-r--r-- | Objects/floatobject.c | 45 | ||||
-rw-r--r-- | Objects/intobject.c | 10 | ||||
-rw-r--r-- | Objects/longobject.c | 32 |
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 = { |