Skip to content

Commit

Permalink
incorporated len event
Browse files Browse the repository at this point in the history
  • Loading branch information
smythi93 committed Oct 24, 2023
1 parent 41b60dc commit 43398f4
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 44 deletions.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "sflkit"
version = "0.2.12"
version = "0.2.13"
authors = [
{ name = "Marius Smytzek", email = "marius.smytzek@cispa.de" },
]
Expand All @@ -23,7 +23,7 @@ classifiers = [
"Topic :: Software Development :: Testing"
]
dependencies = [
"sflkitlib>=0.0.1",
"sflkitlib>=0.0.2",
"numpy>=1.23.5",
"matplotlib>=3.7.2",
"sortedcollections>=2.1.0"
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
sflkitlib>=0.0.1
sflkitlib>=0.0.2
numpy>=1.23.5
matplotlib>=3.7.2
sortedcollections>=2.1.0
11 changes: 11 additions & 0 deletions resources/subjects/tests/test_len/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import sys


def evaluate(args):
for a in args:
print(a)
break


if __name__ == "__main__":
evaluate(sys.argv[1:])
43 changes: 17 additions & 26 deletions src/sflkit/language/language.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@
from sflkit.language.python.visitor import PythonInstrumentation
from sflkit.language.visitor import ASTVisitor

_PYTHON_FACTORIES = {
EventType.LINE: python_factory.LineEventFactory,
EventType.BRANCH: python_factory.BranchEventFactory,
EventType.DEF: python_factory.DefEventFactory,
EventType.USE: python_factory.UseEventFactory,
EventType.LOOP_BEGIN: python_factory.LoopBeginEventFactory,
EventType.LOOP_HIT: python_factory.LoopHitEventFactory,
EventType.LOOP_END: python_factory.LoopEndEventFactory,
EventType.FUNCTION_ENTER: python_factory.FunctionEnterEventFactory,
EventType.FUNCTION_EXIT: python_factory.FunctionExitEventFactor,
EventType.FUNCTION_ERROR: python_factory.FunctionErrorEventFactory,
EventType.CONDITION: python_factory.ConditionEventFactory,
EventType.LEN: python_factory.LenEventFactory,
}


class Language(enum.Enum):
def __init__(
Expand Down Expand Up @@ -48,19 +63,7 @@ def setup(self):

PYTHON = (
PythonInstrumentation,
{
EventType.LINE: python_factory.LineEventFactory,
EventType.BRANCH: python_factory.BranchEventFactory,
EventType.DEF: python_factory.DefEventFactory,
EventType.USE: python_factory.UseEventFactory,
EventType.LOOP_BEGIN: python_factory.LoopBeginEventFactory,
EventType.LOOP_HIT: python_factory.LoopHitEventFactory,
EventType.LOOP_END: python_factory.LoopEndEventFactory,
EventType.FUNCTION_ENTER: python_factory.FunctionEnterEventFactory,
EventType.FUNCTION_EXIT: python_factory.FunctionExitEventFactor,
EventType.FUNCTION_ERROR: python_factory.FunctionErrorEventFactory,
EventType.CONDITION: python_factory.ConditionEventFactory,
},
_PYTHON_FACTORIES,
PythonVarExtract(),
PythonVarExtract(use=True),
PythonConditionExtract(),
Expand All @@ -72,19 +75,7 @@ def setup(self):
PYTHON3 = PYTHON
PYTHON2 = (
None,
{
EventType.LINE: python_factory.LineEventFactory,
EventType.BRANCH: python_factory.BranchEventFactory,
EventType.DEF: python_factory.DefEventFactory,
EventType.USE: python_factory.UseEventFactory,
EventType.LOOP_BEGIN: python_factory.LoopBeginEventFactory,
EventType.LOOP_HIT: python_factory.LoopHitEventFactory,
EventType.LOOP_END: python_factory.LoopEndEventFactory,
EventType.FUNCTION_ENTER: python_factory.FunctionEnterEventFactory,
EventType.FUNCTION_EXIT: python_factory.FunctionExitEventFactor,
EventType.FUNCTION_ERROR: python_factory.FunctionEnterEventFactory,
EventType.CONDITION: python_factory.ConditionEventFactory,
},
_PYTHON_FACTORIES,
PythonVarExtract(),
PythonVarExtract(use=True),
PythonConditionExtract(),
Expand Down
62 changes: 53 additions & 9 deletions src/sflkit/language/python/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
LoopEndEvent,
UseEvent,
ConditionEvent,
LenEvent,
)

from sflkit.language.meta import MetaVisitor, Injection, IDGenerator, TmpGenerator
Expand Down Expand Up @@ -58,7 +59,7 @@ def get_function(self):
pass

def get_event_call(self, event: Event):
return get_call(self.get_function(), event.file, event.line, event.id_)
return get_call(self.get_function(), event.file, event.line, event.event_id)


class LineEventFactory(PythonEventFactory):
Expand Down Expand Up @@ -148,7 +149,7 @@ def get_event_call(self, event: BranchEvent):
self.get_function(),
event.file,
event.line,
event.id_,
event.event_id,
event.then_id,
event.else_id,
)
Expand Down Expand Up @@ -225,7 +226,7 @@ def get_function(self):

def get_event_call(self, event: DefEvent):
call = get_call(
self.get_function(), event.file, event.line, event.id_, event.var
self.get_function(), event.file, event.line, event.event_id, event.var
)
assert isinstance(call.value, Call)
call.value.args.append(
Expand Down Expand Up @@ -400,7 +401,7 @@ def get_event_call(self, event: FunctionEnterEvent):
self.get_function(),
event.file,
event.line,
event.id_,
event.event_id,
event.function_id,
event.function,
)
Expand Down Expand Up @@ -448,7 +449,7 @@ def get_event_call(self, event: FunctionExitEvent):
self.get_function(),
event.file,
event.line,
event.id_,
event.event_id,
event.function_id,
event.function,
)
Expand Down Expand Up @@ -532,7 +533,7 @@ def get_event_call(self, event: FunctionEnterEvent | FunctionErrorEvent):
self.get_function(),
event.file,
event.line,
event.id_,
event.event_id,
event.function_id,
event.function,
)
Expand Down Expand Up @@ -567,7 +568,7 @@ def get_event_call(
self, event: typing.Union[LoopBeginEvent, LoopHitEvent, LoopEndEvent]
):
return get_call(
self.get_function(), event.file, event.line, event.id_, event.loop_id
self.get_function(), event.file, event.line, event.event_id, event.loop_id
)

@staticmethod
Expand Down Expand Up @@ -670,7 +671,7 @@ def _get_try_wrapper(self, event: UseEvent):

def _get_std_call(self, event: UseEvent):
call = get_call(
self.get_function(), event.file, event.line, event.id_, event.var
self.get_function(), event.file, event.line, event.event_id, event.var
)
assert isinstance(call.value, Call)
call.value.args.append(
Expand Down Expand Up @@ -830,7 +831,8 @@ def get_event_call(self, event: ConditionEvent):
self.get_function(),
event.file,
event.line,
event.id_,
event.event_id,
event.event_id,
event.condition,
)
assert isinstance(call.value, Call)
Expand All @@ -853,3 +855,45 @@ def visit_While(self, node: While) -> Injection:

def visit_If(self, node: If) -> Injection:
return self.visit_condition(node)


class LenEventFactory(DefEventFactory):
def get_function(self):
return "add_len_event"

def get_check_for_len(self, event: LenEvent):
call = get_call(
self.get_function(), event.file, event.line, event.event_id, event.var
)
assert isinstance(call.value, Call)
call.value.args.append(
Call(
func=Attribute(
value=Name(
id=python_lib, # enter lib
),
attr="get_id", # enter lib function
),
args=[Name(id=event.var)],
keywords=[],
)
)
call.value.args.append(
Call(
func=Name(id="len"),
args=[Name(id=event.var)],
keywords=[],
)
)
return If(
test=Call(
func=Name(id="hasattr"),
args=[Name(id=event.var), Constant(value="__len__")],
keywords=[],
),
body=[call],
orelse=[],
)

def get_event_call(self, event: LenEvent):
return self.get_check_for_len(event)
10 changes: 4 additions & 6 deletions src/sflkit/model/event_file.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import csv
from pickle import PickleError

from sflkitlib.events import event
Expand All @@ -13,8 +12,7 @@ def __init__(self, path: str, run_id: int, failing: bool = False):
self._file_pointer = None

def __enter__(self):
self._file_pointer = open(self.path, "r")
self._csv_reader = csv.reader(self._file_pointer)
self._file_pointer = open(self.path, "rb")

def __exit__(self, exc_type, exc_val, exc_tb):
self._file_pointer.close()
Expand All @@ -26,8 +24,8 @@ def __str__(self):
return repr(self)

def load(self):
for row in self._csv_reader:
while self._file_pointer.peek(1):
try:
yield event.load_event(event.EventType(int(row[0])), *row[1:])
yield event.load_next_event(self._file_pointer)
except (IndexError, ValueError, PickleError):
pass
break
3 changes: 3 additions & 0 deletions src/sflkit/model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def handle_loop_hit_event(self, event):
def handle_loop_end_event(self, event):
self.handle_event(event)

def handle_len_event(self, event):
self.handle_event(event)

def enter_scope(self):
self.variables = self.variables.enter()

Expand Down
23 changes: 23 additions & 0 deletions tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,29 @@ def test_condition(self):
self.assertEqual(ev, e.value, f"{e} has not correct value")
self.assertEqual(exp, e.condition, f"{e} has not correct condition")

def test_len(self):
config = Config.create(
path=os.path.join(self.TEST_RESOURCES, self.TEST_LEN),
language="python",
events="len",
working=self.TEST_DIR,
)
instrument_config(config)

subprocess.run(
[self.PYTHON, self.ACCESS, "a", "b", "c"],
cwd=self.TEST_DIR,
)

events = event.load(os.path.join(self.TEST_DIR, self.TEST_PATH))
self.assertEqual(2, len(events))
for i, a, l, e in zip([4, 5], ["args", "a"], [3, 1], events):
self.assertIsInstance(e, event.LenEvent, f"{e} is not a line event")
self.assertEqual(self.ACCESS, e.file, f"{e} has not correct file")
self.assertEqual(i, e.line, f"{e} has not correct line")
self.assertEqual(a, e.var, f"{e} has not correct var")
self.assertEqual(l, e.length, f"{e} has not correct length")


class SerializeEventsTest(BaseTest):
@parameterized.expand(map(lambda x: (str(x), x), BaseTest.EVENTS))
Expand Down
1 change: 1 addition & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class BaseTest(unittest.TestCase):
PYTHON = "python3.10"
ACCESS = "main.py"
TEST_LINES = "test_lines"
TEST_LEN = "test_len"
TEST_BRANCHES = "test_branches"
TEST_SUGGESTIONS = "test_suggestions"
TEST_TYPES = "test_types"
Expand Down

0 comments on commit 43398f4

Please sign in to comment.