Commit 11323cc4 authored by Emmeline Vouriot's avatar Emmeline Vouriot

add internship2to3 code

parent bf38f2b2
logging... C:\Users\emmy\Documents\BOSSAGE\BAC+5\stage\2\my2to3\tests\sample\sample.py div 8 (6, 4, 'BinOp') {'a': 2, 'b': 3}
logging... C:\Users\emmy\Documents\BOSSAGE\BAC+5\stage\2\my2to3\tests\sample\sample2.py div 6 (5, 4, 'BinOp') {'a': 4, 'b': 5}
import my2to3.trace
from . import sample2
def f(): pass def f(): pass
......
def f(): pass
b = 4 / 5
from __future__ import print_function
import ast
import inspect
import os
import unittest
import sys
import context
from my2to3.hook import Finder
from my2to3.visit import DepthVisitor
from my2to3.visit import InstrumentVisitor
import my2to3.runtime
class BinOpVisitor(InstrumentVisitor):
def visit_BinOp(self, node):
self.visit_children(node)
if isinstance(node.op, ast.Div):
node.left = self.make_trace(node.left)
node.right = self.make_trace(node.right)
return node
def log(data, _id, node, output_log, extradata=None):
res = "logging... %(file)s %(extra)s %(id)s %(node)s %(data)s\n" % {
"file": output_log[1],
"extra": extradata or "",
"id": _id,
"node": node,
"data": data
}
print(res)
__mybuiltins__.__logs__.append((output_log[0], _id, node, res))
def savelog():
for output_log, _id, node, res in sorted(__mybuiltins__.__logs__, key=lambda x: (x[2], x[1])):
with open(output_log, "a") as f:
f.write(res)
def add(a, b, node, _id, output_log):
__mybuiltins__.__log__({"a": a, "b": b}, _id, node, output_log, "add")
return a + b
def mult(a, b, node, _id, output_log):
__mybuiltins__.__log__({"a": a, "b": b}, _id, node, output_log, "mult")
return a * b
def div(a, b, node, _id, output_log):
__mybuiltins__.__log__({"a": a, "b": b}, _id, node, output_log, "div")
return a / b
def floordiv(a, b, node, _id, output_log):
__mybuiltins__.__log__({"a": a, "b": b}, _id, node, output_log, "floordiv")
return a // b
def string(string_, node, _id, output_log):
__mybuiltins__.__log__({"string": string_}, _id, node, output_log, "string")
return string_
__mybuiltins__ = type('', (), {})()
__mybuiltins__.__log__ = log
__mybuiltins__.__savelog__ = savelog
__mybuiltins__.__nodes__ = {}
__mybuiltins__.__add__ = add
__mybuiltins__.__mult__ = mult
__mybuiltins__.__div__ = div
__mybuiltins__.__string__ = string
__mybuiltins__.__floordiv__ = floordiv
__mybuiltins__.__logs__ = []
import atexit
atexit.register(__mybuiltins__.__savelog__)
# Check python 2
assert sys.version_info[0] == 2
# add log function to builtins
__builtins__["__mybuiltins__"] = __mybuiltins__
def first_injectable_parent_node(node):
"""get the first parent node where another line can be inserted"""
parentnode = node
while not hasattr(parentnode, "body"):
parentnode = parentnode.parent
return parentnode
def get_id(node):
"""get unique id of node"""
return ast.parse(repr((node.lineno, node.col_offset, type(node).__name__)), mode="exec").body[0].value
def add_log_string_node(node, output_log):
f = "__mybuiltins__.__string__(None, None, %(id)s, %(output_log)r)" % {
"id": node._id,
"output_log": output_log
}
p = ast.parse(f, mode="exec").body[0].value
p.args[:2] = [node, get_id(node)]
return p
def add_log_binop_node(node, kind, output_log):
f = "__mybuiltins__.__%(kind)s__(None, None, None, %(id)s, %(output_log)r)" % {
"kind": kind,
"id": node._id,
"output_log": output_log
}
p = ast.parse(f, mode="exec").body[0].value
p.args[:3] = [node.left, node.right, get_id(node)]
return p
def add_id_to_function_node(node, id_):
"""adds __id__ variable to store data of node, so it is known by the code"""
f = "__id__ = %(id)r" % {"id": id_}
node.body.insert(0, ast.parse(f, mode="exec").body[0])
return node
class AddLogFunc(ast.NodeTransformer):
def __init__(self, code, output_log):
self._code = code
self._output_log = output_log
#def visit_FunctionDef(self, node):
# id_ = tuple([node.lineno, node.col_offset, type(node).__name__])
# __mybuiltins__.__nodes__[id_] = []
# # add id to function node
# node = add_id_to_function_node(node, id_)
# # add log function call
# node = add_log_function_node(node, id_, self._output_log)
# self.generic_visit(node)
# return node
def visit_BinOp(self, node):
node.left = self.visit(node.left)
node.right = self.visit(node.right)
id_ = tuple([node.lineno, node.col_offset, type(node).__name__])
print(id_)
print("node: " + str(node._id))
print("parent: " + str(node.parent))
oldnode = node
__mybuiltins__.__nodes__[id_] = []
lookup = {
ast.Add: "add",
ast.Mult: "mult",
ast.Div: "div",
ast.FloorDiv: "floordiv"
}
f_name = lookup.get(type(node.op), None)
if f_name is not None:
node = add_log_binop_node(node, f_name, self._output_log)
return node
def visit_Str(self, node):
self.generic_visit(node)
node = add_log_string_node(node, self._output_log)
return node
class TestVisitBinOp(unittest.TestCase):
def setUp(self):
self._calls = []
self._finder = None
if not os.path.exists("../logs/logs_dyn_injection"):
os.makedirs("../logs/logs_dyn_injection")
else:
for test in os.listdir("../logs/logs_dyn_injection"):
if test.endswith(".txt"):
os.remove("../logs/logs_dyn_injection/" + test)
def transform(self, source, name, filename):
tree = ast.parse(source, filename)
i = 0
for node in ast.walk(tree): # todo find a function with a specified order
node._id = i
for child in ast.iter_child_nodes(node):
child.parent = (i, node)
i += 1
ast.fix_missing_locations(AddLogFunc(source, ("../logs/logs_dyn_injection/" + name + ".txt", filename)).visit(tree))
return tree
def info(self, data):
self._calls.append(data)
def test_visit_sample(self):
self._finder = Finder('sample', self.transform)
sys.meta_path.append(self._finder)
my2to3.runtime.logger = self
import sample.sample
self.assertEqual(len(self._calls), 2)
self.assertEqual(
self._calls,
[
'{"loc": {"depth": 3, "col": 4, "line": 5, "name": "sample.sample"}, "type": "<type \'int\'>", "value": "2", "desc": null}',
'{"loc": {"depth": 3, "col": 8, "line": 5, "name": "sample.sample"}, "type": "<type \'int\'>", "value": "3", "desc": null}'
]
)
def tearDown(self):
del my2to3.runtime.logger
sys.meta_path.remove(self._finder)
del sys.modules['sample']
del sys.modules['sample.sample']
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