Skip to content

Commit d94fb35

Browse files
authored
Merge pull request #441 from fbessho/old_div_bug
Fixed bug in fix_division_safe fixture
2 parents 2d0d253 + 49495ee commit d94fb35

File tree

2 files changed

+34
-31
lines changed

2 files changed

+34
-31
lines changed

src/libfuturize/fixes/fix_division_safe.py

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414
"""
1515

1616
import re
17-
import lib2to3.pytree as pytree
1817
from lib2to3.fixer_util import Leaf, Node, Comma
1918
from lib2to3 import fixer_base
20-
from lib2to3.fixer_util import syms, does_tree_import
2119
from libfuturize.fixer_util import (token, future_import, touch_import_top,
2220
wrap_in_fn_call)
2321

@@ -33,8 +31,8 @@ def match_division(node):
3331

3432
const_re = re.compile('^[0-9]*[.][0-9]*$')
3533

36-
def is_floaty(node, div_idx):
37-
return _is_floaty(node.children[0:div_idx]) or _is_floaty(node.children[div_idx+1:])
34+
def is_floaty(node):
35+
return _is_floaty(node.prev_sibling) or _is_floaty(node.next_sibling)
3836

3937

4038
def _is_floaty(expr):
@@ -50,24 +48,6 @@ def _is_floaty(expr):
5048
return expr.children[0].value == u'float'
5149
return False
5250

53-
def find_division(node):
54-
for i, child in enumerate(node.children):
55-
if match_division(child):
56-
return i
57-
return False
58-
59-
def clone_div_operands(node, div_idx):
60-
children = []
61-
for i, child in enumerate(node.children):
62-
if i == div_idx:
63-
children.append(Comma())
64-
else:
65-
children.append(child.clone())
66-
67-
# Strip any leading space for the first number:
68-
children[0].prefix = u''
69-
70-
return children
7151

7252
class FixDivisionSafe(fixer_base.BaseFix):
7353
# BM_compatible = True
@@ -92,18 +72,33 @@ def match(self, node):
9272
matches, we can start discarding matches after the first.
9373
"""
9474
if node.type == self.syms.term:
95-
div_idx = find_division(node)
96-
if div_idx is not False:
97-
# if expr1 or expr2 are obviously floats, we don't need to wrap in
98-
# old_div, as the behavior of division between any number and a float
99-
# should be the same in 2 or 3
100-
if not is_floaty(node, div_idx):
101-
return clone_div_operands(node, div_idx)
75+
matched = False
76+
skip = False
77+
children = []
78+
for child in node.children:
79+
if skip:
80+
skip = False
81+
continue
82+
if match_division(child) and not is_floaty(child):
83+
matched = True
84+
85+
# Strip any leading space for the first number:
86+
children[0].prefix = u''
87+
88+
children = [wrap_in_fn_call("old_div",
89+
children + [Comma(), child.next_sibling.clone()],
90+
prefix=node.prefix)]
91+
skip = True
92+
else:
93+
children.append(child.clone())
94+
if matched:
95+
return Node(node.type, children, fixers_applied=node.fixers_applied)
96+
10297
return False
10398

10499
def transform(self, node, results):
105100
if self.skip:
106101
return
107102
future_import(u"division", node)
108103
touch_import_top(u'past.utils', u'old_div', node)
109-
return wrap_in_fn_call("old_div", results, prefix=node.prefix)
104+
return results

tests/test_future/test_futurize.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,10 @@ def total_count(self):
12081208
val = float(obj.numer) / obj.denom * 1e-9
12091209
obj.numer * obj.denom / val
12101210
obj.total_count() * val / 100
1211+
obj.numer / obj.denom * 1e-9
1212+
obj.numer / (obj.denom * 1e-9)
1213+
obj.numer / obj.denom / 1e-9
1214+
obj.numer / (obj.denom / 1e-9)
12111215
original_numer = 1
12121216
original_denom = 50
12131217
100 * abs(obj.numer - original_numer) / float(max(obj.denom, original_denom))
@@ -1237,13 +1241,17 @@ def total_count(self):
12371241
b = 1 + foo[old_div(len(foo) * 3, 4)]
12381242
assert a == 51
12391243
assert b == 76
1240-
r = old_div(random.randint(0, 1000) * 1.0, 1000)
1244+
r = random.randint(0, 1000) * 1.0 / 1000
12411245
output = { "SUCCESS": 5, "TOTAL": 10 }
12421246
old_div(output["SUCCESS"] * 100, output["TOTAL"])
12431247
obj = fraction(1, 50)
12441248
val = float(obj.numer) / obj.denom * 1e-9
12451249
old_div(obj.numer * obj.denom, val)
12461250
old_div(obj.total_count() * val, 100)
1251+
old_div(obj.numer, obj.denom) * 1e-9
1252+
old_div(obj.numer, (obj.denom * 1e-9))
1253+
old_div(old_div(obj.numer, obj.denom), 1e-9)
1254+
old_div(obj.numer, (old_div(obj.denom, 1e-9)))
12471255
original_numer = 1
12481256
original_denom = 50
12491257
100 * abs(obj.numer - original_numer) / float(max(obj.denom, original_denom))

0 commit comments

Comments
 (0)