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 from lib2to3.fixer_base import BaseFix
import lib2to3.pgen2 import lib2to3.pgen2
from lib2to3.pygram import python_symbols as syms from lib2to3.pygram import python_symbols as syms
from lib2to3.pytree import Leaf, Node from lib2to3.pytree import Leaf, Node
import os 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 analyze_types(types):
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):
"""Indicates whether the division described by `data` should be modified into """Indicates whether the division described by `data` should be modified into
`//`, or should remain as `/` `//`, or should remain as `/`
""" """
data = list(data) # data was a set if len(types) == 1:
if len(data) == 1: dividend, divisor = types[0]
dividend, divisor = data[0]
if dividend is divisor is int: if dividend is divisor is int:
return True return True
return False return False
...@@ -49,32 +21,21 @@ def analyze_data(data): ...@@ -49,32 +21,21 @@ def analyze_data(data):
class FixDivisionSupport(BaseFix): class FixDivisionSupport(BaseFix):
"""Rewrites division_traced(n, a, b) into Py2/Py3-compatible division """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 # Inspired by https://github.com/python/cpython/blob/e42b705188271da108de42b55d9344642170aa2b/Lib/lib2to3/fixes/fix_xrange.py#L14
PATTERN = """ PATTERN = """
power<'division_traced' trailer< '(' args=any ')' > power<'division_traced' trailer< '(' args=any ')' >
rest=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): def transform(self, node, results):
lineno = node.get_lineno() filename, lineno, id_ = [l.value for l in node.children[1].children[1].children[:-4:2]]
id_ = int(node.children[1].children[1].children[0].value) data = get_data("division", ["dividend_type", "divisor_type"], dict(filename=filename, lineno=lineno, id=id_))
data = self.traces[self.absolute_filename][lineno][id_]
if not data: if not data:
return return
if analyze_data(data): if analyze_types(data2types(data)):
add_future(node, 'division') add_future(node, 'division')
operator = Leaf(lib2to3.pgen2.token.DOUBLESLASH, "//") operator = Leaf(lib2to3.pgen2.token.DOUBLESLASH, "//")
else: else:
......
...@@ -43,6 +43,24 @@ def get_fixers(): ...@@ -43,6 +43,24 @@ def get_fixers():
f for f in get_fixers_from_package("my2to3.fixes") if f.endswith("_trace") 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): def apply_fixers(string, name):
# This function is inspired by refactoring_tool.refactor_file # This function is inspired by refactoring_tool.refactor_file
......
import __builtin__
from lib2to3 import fixer_util from lib2to3 import fixer_util
from lib2to3.pytree import Leaf, Node from lib2to3.pytree import Leaf, Node
from lib2to3.pgen2 import token from lib2to3.pgen2 import token
...@@ -10,6 +11,13 @@ def parse_type(type_): ...@@ -10,6 +11,13 @@ def parse_type(type_):
return type_match(str(type_)).group(1) 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 # https://github.com/python-modernize/python-modernize/blob/84d973cb7b8153f9f7f22c3574a59312b2372ccb/libmodernize/__init__.py#L10-49
def check_future_import(node): def check_future_import(node):
"""If this is a future import, return set of symbols that are imported, """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