Commit b07744cc authored by Bryton Lacquement's avatar Bryton Lacquement 🚪

division_support: use the database data

parent f7b06530
import __builtin__
from collections import defaultdict
from lib2to3.fixer_base import BaseFix
import lib2to3.pgen2
from lib2to3.pygram import python_symbols as syms
from lib2to3.pytree import Leaf, Node
import os
import re
from my2to3.util import add_future
from my2to3.trace import get_data
from my2to3.util import add_future, data2types
trace_file_match = re.compile(r"^(.*)\|(.*)\|(.*) <type '(.*)'> / <type '(.*)'>$").match
def parse_trace_data(filepath):
def tree():
return defaultdict(tree)
traces = tree()
with open(filepath) as f:
for line in f:
file, lineno, id_, dividend_type, divisor_type = trace_file_match(line).groups()
lineno = int(lineno)
id_ = int(id_)
dividend_type = getattr(__builtin__, dividend_type)
divisor_type = getattr(__builtin__, divisor_type)
t = traces[file][lineno]
data = (dividend_type, divisor_type)
if id_ in t:
t[id_].add(data)
else:
t[id_] = {data}
return traces
def analyze_data(data):
def analyze_types(types):
"""Indicates whether the division described by `data` should be modified into
`//`, or should remain as `/`
"""
data = list(data) # data was a set
if len(data) == 1:
dividend, divisor = data[0]
if len(types) == 1:
dividend, divisor = types[0]
if dividend is divisor is int:
return True
return False
......@@ -49,32 +21,21 @@ def analyze_data(data):
class FixDivisionSupport(BaseFix):
"""Rewrites division_traced(n, a, b) into Py2/Py3-compatible division
The `TRACE_FILE` environment variable must point to the trace data file. See
`fix_trace_division.py` for more details.
"""
traces = parse_trace_data(os.environ["TRACE_FILE"])
# Inspired by https://github.com/python/cpython/blob/e42b705188271da108de42b55d9344642170aa2b/Lib/lib2to3/fixes/fix_xrange.py#L14
PATTERN = """
power<'division_traced' trailer< '(' args=any ')' >
rest=any* >
"""
def start_tree(self, tree, filename):
super(FixDivisionSupport, self).start_tree(tree, filename)
self.absolute_filename = os.path.abspath(filename)
def transform(self, node, results):
lineno = node.get_lineno()
id_ = int(node.children[1].children[1].children[0].value)
data = self.traces[self.absolute_filename][lineno][id_]
filename, lineno, id_ = [l.value for l in node.children[1].children[1].children[:-4:2]]
data = get_data("division", ["dividend_type", "divisor_type"], dict(filename=filename, lineno=lineno, id=id_))
if not data:
return
if analyze_data(data):
if analyze_types(data2types(data)):
add_future(node, 'division')
operator = Leaf(lib2to3.pgen2.token.DOUBLESLASH, "//")
else:
......
......@@ -43,6 +43,24 @@ def get_fixers():
f for f in get_fixers_from_package("my2to3.fixes") if f.endswith("_trace")
]
def get_data(table, columns_to_select, conditions):
# TODO:
# - refactor
# - optimize
conn = sqlite3.connect(database)
c = conn.cursor()
data = c.execute("SELECT %s FROM %s WHERE %s" % (
', '.join(columns_to_select),
table,
' AND '.join(k + " = " + v for k, v in conditions.items()))
)
try:
return data.fetchall()
finally:
conn.close()
def apply_fixers(string, name):
# This function is inspired by refactoring_tool.refactor_file
......
import __builtin__
from lib2to3 import fixer_util
from lib2to3.pytree import Leaf, Node
from lib2to3.pgen2 import token
......@@ -10,6 +11,13 @@ def parse_type(type_):
return type_match(str(type_)).group(1)
def data2types(data):
types = []
for tuple_ in data:
types.append([getattr(__builtin__, type_) for type_ in tuple_])
return types
# https://github.com/python-modernize/python-modernize/blob/84d973cb7b8153f9f7f22c3574a59312b2372ccb/libmodernize/__init__.py#L10-49
def check_future_import(node):
"""If this is a future import, return set of symbols that are imported,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment