Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/libfuturize/fixes/fix_division_safe.py @ 1:56ad4e20f292 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
| author | guerler | 
|---|---|
| date | Fri, 31 Jul 2020 00:32:28 -0400 | 
| parents | |
| children | 
   comparison
  equal
  deleted
  inserted
  replaced
| 0:d30785e31577 | 1:56ad4e20f292 | 
|---|---|
| 1 """ | |
| 2 For the ``future`` package. | |
| 3 | |
| 4 Adds this import line: | |
| 5 | |
| 6 from __future__ import division | |
| 7 | |
| 8 at the top and changes any old-style divisions to be calls to | |
| 9 past.utils.old_div so the code runs as before on Py2.6/2.7 and has the same | |
| 10 behaviour on Py3. | |
| 11 | |
| 12 If "from __future__ import division" is already in effect, this fixer does | |
| 13 nothing. | |
| 14 """ | |
| 15 | |
| 16 import re | |
| 17 from lib2to3.fixer_util import Leaf, Node, Comma | |
| 18 from lib2to3 import fixer_base | |
| 19 from libfuturize.fixer_util import (token, future_import, touch_import_top, | |
| 20 wrap_in_fn_call) | |
| 21 | |
| 22 | |
| 23 def match_division(node): | |
| 24 u""" | |
| 25 __future__.division redefines the meaning of a single slash for division, | |
| 26 so we match that and only that. | |
| 27 """ | |
| 28 slash = token.SLASH | |
| 29 return node.type == slash and not node.next_sibling.type == slash and \ | |
| 30 not node.prev_sibling.type == slash | |
| 31 | |
| 32 const_re = re.compile('^[0-9]*[.][0-9]*$') | |
| 33 | |
| 34 def is_floaty(node): | |
| 35 return _is_floaty(node.prev_sibling) or _is_floaty(node.next_sibling) | |
| 36 | |
| 37 | |
| 38 def _is_floaty(expr): | |
| 39 if isinstance(expr, list): | |
| 40 expr = expr[0] | |
| 41 | |
| 42 if isinstance(expr, Leaf): | |
| 43 # If it's a leaf, let's see if it's a numeric constant containing a '.' | |
| 44 return const_re.match(expr.value) | |
| 45 elif isinstance(expr, Node): | |
| 46 # If the expression is a node, let's see if it's a direct cast to float | |
| 47 if isinstance(expr.children[0], Leaf): | |
| 48 return expr.children[0].value == u'float' | |
| 49 return False | |
| 50 | |
| 51 | |
| 52 class FixDivisionSafe(fixer_base.BaseFix): | |
| 53 # BM_compatible = True | |
| 54 run_order = 4 # this seems to be ignored? | |
| 55 | |
| 56 _accept_type = token.SLASH | |
| 57 | |
| 58 PATTERN = """ | |
| 59 term<(not('/') any)+ '/' ((not('/') any))> | |
| 60 """ | |
| 61 | |
| 62 def start_tree(self, tree, name): | |
| 63 """ | |
| 64 Skip this fixer if "__future__.division" is already imported. | |
| 65 """ | |
| 66 super(FixDivisionSafe, self).start_tree(tree, name) | |
| 67 self.skip = "division" in tree.future_features | |
| 68 | |
| 69 def match(self, node): | |
| 70 u""" | |
| 71 Since the tree needs to be fixed once and only once if and only if it | |
| 72 matches, we can start discarding matches after the first. | |
| 73 """ | |
| 74 if node.type == self.syms.term: | |
| 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 | |
| 97 return False | |
| 98 | |
| 99 def transform(self, node, results): | |
| 100 if self.skip: | |
| 101 return | |
| 102 future_import(u"division", node) | |
| 103 touch_import_top(u'past.utils', u'old_div', node) | |
| 104 return results | 
