Skip to content

Commit

Permalink
Remove unnecessary print and add inspect locals example
Browse files Browse the repository at this point in the history
  • Loading branch information
dhzdhd committed Jun 19, 2024
1 parent 08b78e7 commit 2b2875d
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 49 deletions.
52 changes: 6 additions & 46 deletions examples/inspect_locals.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,12 @@
# This has not been implemented in the library yet, for testing purposes only
#
# It will either be implemented as a decorator composable with @test
# For example -
# @test(...)
# @inspect_locals
# def foo(...):
# ...
#
# or as a part of @test
# For example -
# @test(..., inspect_locals=True)
# def foo(...):
# ...
from pysvt import test

d = {
"i": [[]],
"o": [5],
}

import sys
import types


# https://stackoverflow.com/a/52358426
def call_function_get_frame(func, *args, **kwargs):
frame: types.FrameType | None = None
trace = sys.gettrace()

def snatch_locals(_frame, name, arg):
nonlocal frame
if frame is None and name == "call":
frame = _frame
sys.settrace(trace)
return trace

sys.settrace(snatch_locals)
try:
result = func(*args, **kwargs)
finally:
sys.settrace(trace)
return frame, result


def inspect_locals(func):
frame, result = call_function_get_frame(func)
print(f"Local variables: {frame.f_locals}")
print(f"Result: {result}")

return func


@inspect_locals
@test(data=d, show_locals=True)
def hello():
a = 5

Expand Down
57 changes: 57 additions & 0 deletions examples/inspect_locals_deco.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# This has not been implemented in the library yet, for testing purposes only
#
# It will either be implemented as a decorator composable with @test
# For example -
# @test(...)
# @inspect_locals
# def foo(...):
# ...
#
# or as a part of @test
# For example -
# @test(..., inspect_locals=True)
# def foo(...):
# ...


import sys
import types


# https://stackoverflow.com/a/52358426
def call_function_get_frame(func, *args, **kwargs):
frame: types.FrameType | None = None
trace = sys.gettrace()

def snatch_locals(_frame, name, arg):
nonlocal frame
if frame is None and name == "call":
frame = _frame
sys.settrace(trace)
return trace

sys.settrace(snatch_locals)
try:
result = func(*args, **kwargs)
finally:
sys.settrace(trace)
return frame, result


def inspect_locals(func):
frame, result = call_function_get_frame(func)
print(f"Local variables: {frame.f_locals}")
print(f"Result: {result}")

return func


@inspect_locals
def hello():
a = 5

for _ in range(5):
a += 1
print("Hello, World!")

return 5
16 changes: 13 additions & 3 deletions pysvt/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class test:
- `is_live` (bool): Flag indicating whether to run the tests in live mode. Default is False.
- `pretty_print_errors` (bool): Flag indicating whether to pretty print errors with colors and more information. Default is True.
- `redirect_stdout` (bool): Flag indicating whether to redirect all stdout (print statements, etc) to the pretty printed panels. Default is True.
- `show_locals` (bool): Flag indicating whether to show local variable values after execution of the function. Default is False.
Raises:
- `ValueError`: If the `file` argument is not of type str or Path or `method` argument is not provided for instance methods.
Expand Down Expand Up @@ -64,16 +65,20 @@ def function(arg1, arg2):

def __init__(
self,
file: str | Path | None = None,
data: dict[str, Any] | None = None,
file: str | Path | None = None,
method: str | None = None,
preprocess: Callable[..., Any] | None = None,
postprocess: Callable[..., Any] | None = None,
error_only: bool = False,
is_live: bool = False,
pretty_print_errors: bool = True,
redirect_stdout: bool = True,
show_locals: bool = False,
) -> None:
if show_locals:
raise NotImplementedError("show_locals has not been implemented yet")

if (file is None and data is None) or (file is not None and data is not None):
raise ValueError("Either of file or data argument should be filled")

Expand All @@ -93,6 +98,7 @@ def __init__(
self._is_live = is_live
self._pretty_print_errors = pretty_print_errors
self._redirect_stdout = redirect_stdout
self._show_locals = show_locals

self._printer = Printer(console, self._is_live)

Expand Down Expand Up @@ -137,8 +143,6 @@ def __call__(self, obj: object) -> Any:
# with self._printer.init_normal() as _:
failures = 0

print(self._data.data)

for index, data in enumerate(self._data.data):
partial_method = partial(method, obj(*self._data.init[index]))
with Timer() as timer:
Expand Down Expand Up @@ -379,3 +383,9 @@ def _validate(self, data: _FuncModel, func: Callable[..., Any]) -> Result:
result = self._postprocess(result)

return Result(result, stdout, result == data.output)


class inspect_locals:
def __init__(self) -> None: ...

def __call__(self, obj: object) -> Any: ...

0 comments on commit 2b2875d

Please sign in to comment.