fix in-place division in Py3
authorStefan Behnel <scoder@users.berlios.de>
Thu, 22 Oct 2009 20:34:15 +0000 (22:34 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Thu, 22 Oct 2009 20:34:15 +0000 (22:34 +0200)
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
tests/run/future_division.pyx
tests/run/non_future_division.pyx

index 68dd56f59719b75970acd1c597d3dca7aef6bc4c..1db9b6fc0df79b53bb1677b707455b1d8ea0f974 100644 (file)
@@ -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")
 
index 29eb0b15f42ac52d9b28c65240ddc2eb89fb04c1..7d22f885b577ba1c596df55a75d5a4c172397614 100644 (file)
@@ -3199,7 +3199,7 @@ class InPlaceAssignmentNode(AssignmentNode):
         "+":        "PyNumber_InPlaceAdd",
         "-":        "PyNumber_InPlaceSubtract",
         "*":        "PyNumber_InPlaceMultiply",
-        "/":        "PyNumber_InPlaceDivide",
+        "/":        "__Pyx_PyNumber_InPlaceDivide",
         "%":        "PyNumber_InPlaceRemainder",
         "<<":        "PyNumber_InPlaceLshift",
         ">>":        "PyNumber_InPlaceRshift",
index f87b83a84c8382e6218e4c27cc65719b98642f52..e67bc091167643aa51e9a9215d7b18d170edcc84 100644 (file)
@@ -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
index 61acb1bc653320e64151ea20f4ef27615ee46053..2d93551b247b14335657965d6143f301289d165d 100644 (file)
@@ -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