From d2c94b6e588a810cde23a46fb17245804662cd3e Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Thu, 22 Oct 2009 22:34:15 +0200 Subject: [PATCH] fix in-place division in Py3 --- Cython/Compiler/ModuleNode.py | 3 + Cython/Compiler/Nodes.py | 2 +- tests/run/future_division.pyx | 96 +++++++++++++++++++------------ tests/run/non_future_division.pyx | 96 +++++++++++++++++++------------ 4 files changed, 120 insertions(+), 77 deletions(-) diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 68dd56f5..1db9b6fc 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -511,11 +511,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln(" #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask") code.putln(" #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask") code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)") + code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)") code.putln("#else") if Future.division in env.context.future_directives: code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)") + code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)") else: code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)") + code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)") code.putln(" #define PyBytes_Type PyString_Type") code.putln("#endif") diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 29eb0b15..7d22f885 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -3199,7 +3199,7 @@ class InPlaceAssignmentNode(AssignmentNode): "+": "PyNumber_InPlaceAdd", "-": "PyNumber_InPlaceSubtract", "*": "PyNumber_InPlaceMultiply", - "/": "PyNumber_InPlaceDivide", + "/": "__Pyx_PyNumber_InPlaceDivide", "%": "PyNumber_InPlaceRemainder", "<<": "PyNumber_InPlaceLshift", ">>": "PyNumber_InPlaceRshift", diff --git a/tests/run/future_division.pyx b/tests/run/future_division.pyx index f87b83a8..e67bc091 100644 --- a/tests/run/future_division.pyx +++ b/tests/run/future_division.pyx @@ -1,63 +1,83 @@ from __future__ import division -__doc__ = u""" ->>> doit(1,2) -(0.5, 0) ->>> doit(4,3) -(1.3333333333333333, 1) ->>> doit(4,3.0) -(1.3333333333333333, 1.0) ->>> doit(4,2) -(2.0, 2) - ->>> constants() -(0.5, 0, 2.5, 2.0, 2.5, 2) - ->>> py_mix(1) -(0.5, 0, 0.5, 0.0, 0.5, 0) - ->>> py_mix_rev(4) -(0.25, 0, 1.25, 1.0, 1.25, 1) - ->>> py_mix(1.0) -(0.5, 0.0, 0.5, 0.0, 0.5, 0.0) - ->>> py_mix_rev(4.0) -(0.25, 0.0, 1.25, 1.0, 1.25, 1.0) - ->>> int_mix(1) -(0.5, 0, 0.5, 0.0, 0.5, 0) - ->>> int_mix_rev(4) -(0.25, 0, 1.25, 1.0, 1.25, 1) - ->>> float_mix(1.0) -(0.5, 0.0, 0.5, 0.0, 0.5, 0.0) - ->>> float_mix_rev(4.0) -(0.25, 0.0, 1.25, 1.0, 1.25, 1.0) -""" - def doit(x,y): + """ + >>> doit(1,2) + (0.5, 0) + >>> doit(4,3) + (1.3333333333333333, 1) + >>> doit(4,3.0) + (1.3333333333333333, 1.0) + >>> doit(4,2) + (2.0, 2) + """ return x/y, x//y +def doit_inplace(x,y): + """ + >>> doit_inplace(1,2) + 0.5 + """ + x /= y + return x + +def doit_inplace_floor(x,y): + """ + >>> doit_inplace_floor(1,2) + 0 + """ + x //= y + return x + def constants(): + """ + >>> constants() + (0.5, 0, 2.5, 2.0, 2.5, 2) + """ return 1/2, 1//2, 5/2.0, 5//2.0, 5/2, 5//2 def py_mix(a): + """ + >>> py_mix(1) + (0.5, 0, 0.5, 0.0, 0.5, 0) + >>> py_mix(1.0) + (0.5, 0.0, 0.5, 0.0, 0.5, 0.0) + """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def py_mix_rev(a): + """ + >>> py_mix_rev(4) + (0.25, 0, 1.25, 1.0, 1.25, 1) + >>> py_mix_rev(4.0) + (0.25, 0.0, 1.25, 1.0, 1.25, 1.0) + """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a def int_mix(int a): + """ + >>> int_mix(1) + (0.5, 0, 0.5, 0.0, 0.5, 0) + """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def int_mix_rev(int a): + """ + >>> int_mix_rev(4) + (0.25, 0, 1.25, 1.0, 1.25, 1) + """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a def float_mix(float a): + """ + >>> float_mix(1.0) + (0.5, 0.0, 0.5, 0.0, 0.5, 0.0) + """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def float_mix_rev(float a): + """ + >>> float_mix_rev(4.0) + (0.25, 0.0, 1.25, 1.0, 1.25, 1.0) + """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a diff --git a/tests/run/non_future_division.pyx b/tests/run/non_future_division.pyx index 61acb1bc..2d93551b 100644 --- a/tests/run/non_future_division.pyx +++ b/tests/run/non_future_division.pyx @@ -1,63 +1,83 @@ # Py2.x mixed true-div/floor-div behaviour of '/' operator -__doc__ = u""" ->>> doit(1,2) -(0, 0) ->>> doit(4,3) -(1, 1) ->>> doit(4,3.0) -(1.3333333333333333, 1.0) ->>> doit(4,2) -(2, 2) - ->>> constants() -(0, 0, 2.5, 2.0, 2, 2) - ->>> py_mix(1) -(0, 0, 0.5, 0.0, 0, 0) - ->>> py_mix_rev(4) -(0, 0, 1.25, 1.0, 1, 1) - ->>> py_mix(1.0) -(0.5, 0.0, 0.5, 0.0, 0.5, 0.0) - ->>> py_mix_rev(4.0) -(0.25, 0.0, 1.25, 1.0, 1.25, 1.0) - ->>> int_mix(1) -(0, 0, 0.5, 0.0, 0, 0) - ->>> int_mix_rev(4) -(0, 0, 1.25, 1.0, 1, 1) - ->>> float_mix(1.0) -(0.5, 0.0, 0.5, 0.0, 0.5, 0.0) - ->>> float_mix_rev(4.0) -(0.25, 0.0, 1.25, 1.0, 1.25, 1.0) -""" - def doit(x,y): + """ + >>> doit(1,2) + (0, 0) + >>> doit(4,3) + (1, 1) + >>> doit(4,3.0) + (1.3333333333333333, 1.0) + >>> doit(4,2) + (2, 2) + """ return x/y, x//y +def doit_inplace(x,y): + """ + >>> doit_inplace(1,2) + 0 + """ + x /= y + return x + +def doit_inplace_floor(x,y): + """ + >>> doit_inplace_floor(1,2) + 0 + """ + x //= y + return x + def constants(): + """ + >>> constants() + (0, 0, 2.5, 2.0, 2, 2) + """ return 1/2, 1//2, 5/2.0, 5//2.0, 5/2, 5//2 def py_mix(a): + """ + >>> py_mix(1) + (0, 0, 0.5, 0.0, 0, 0) + >>> py_mix(1.0) + (0.5, 0.0, 0.5, 0.0, 0.5, 0.0) + """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def py_mix_rev(a): + """ + >>> py_mix_rev(4) + (0, 0, 1.25, 1.0, 1, 1) + >>> py_mix_rev(4.0) + (0.25, 0.0, 1.25, 1.0, 1.25, 1.0) + """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a def int_mix(int a): + """ + >>> int_mix(1) + (0, 0, 0.5, 0.0, 0, 0) + """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def int_mix_rev(int a): + """ + >>> int_mix_rev(4) + (0, 0, 1.25, 1.0, 1, 1) + """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a def float_mix(float a): + """ + >>> float_mix(1.0) + (0.5, 0.0, 0.5, 0.0, 0.5, 0.0) + """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def float_mix_rev(float a): + """ + >>> float_mix_rev(4.0) + (0.25, 0.0, 1.25, 1.0, 1.25, 1.0) + """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a -- 2.26.2