Skip to content

Skip float divisions in fix_division_safe #345

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/libfuturize/fixes/fix_division_safe.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
nothing.
"""

import re
import lib2to3.pytree as pytree
from lib2to3.fixer_util import Leaf, Node
from lib2to3 import fixer_base
from lib2to3.fixer_util import syms, does_tree_import
from libfuturize.fixer_util import (token, future_import, touch_import_top,
Expand All @@ -28,6 +31,19 @@ def match_division(node):
return node.type == slash and not node.next_sibling.type == slash and \
not node.prev_sibling.type == slash

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


def _is_floaty(expr):
if isinstance(expr, Leaf):
# If it's a leaf, let's see if it's a numeric constant containing a '.'
return const_re.match(expr.value)
elif isinstance(expr, Node):
# If the expression is a node, let's see if it's a direct cast to float
if isinstance(expr.children[0], Leaf):
return expr.children[0].value == u'float'
return False


class FixDivisionSafe(fixer_base.BaseFix):
# BM_compatible = True
Expand Down Expand Up @@ -64,9 +80,14 @@ def transform(self, node, results):
return
future_import(u"division", node)

touch_import_top(u'past.utils', u'old_div', node)
expr1, expr2 = results[0].clone(), results[1].clone()
# Strip any leading space for the first number:
expr1.prefix = u''
# if expr1 or expr2 are obviously floats, we don't need to wrap in
# old_div, as the behavior of division between any number and a float
# should be the same in 2 or 3
if _is_floaty(expr1) or _is_floaty(expr2):
return
touch_import_top(u'past.utils', u'old_div', node)
return wrap_in_fn_call("old_div", (expr1, expr2), prefix=node.prefix)

2 changes: 1 addition & 1 deletion tests/test_future/test_futurize.py
Original file line number Diff line number Diff line change
Expand Up @@ -1179,7 +1179,7 @@ def test_safe_division(self):
from __future__ import division
from past.utils import old_div
x = old_div(3, 2)
y = old_div(3., 2)
y = 3. / 2
assert x == 1 and isinstance(x, int)
assert y == 1.5 and isinstance(y, float)
"""
Expand Down