First implementation of Debugger for SyaNodeParser
This commit is contained in:
+88
-49
@@ -1,16 +1,15 @@
|
||||
import ast
|
||||
import importlib
|
||||
import inspect
|
||||
import os
|
||||
import pkgutil
|
||||
from copy import deepcopy
|
||||
|
||||
from cache.Cache import Cache
|
||||
from core.ast_helpers import ast_to_props
|
||||
from core.tokenizer import TokenKind, Tokenizer
|
||||
from pyparsing import *
|
||||
|
||||
default_debug_name = "*default*"
|
||||
debug_activated = set()
|
||||
|
||||
COLORS = {
|
||||
"black",
|
||||
"red",
|
||||
@@ -43,55 +42,17 @@ integer = Word(nums)
|
||||
escapeSeq = Combine(ESC + '[' + Optional(delimitedList(integer, ';')) +
|
||||
oneOf(list(alphas)))
|
||||
|
||||
try:
|
||||
CONSOLE_ROWS, CONSOLE_COLUMNS = os.popen('stty size', 'r').read().split()
|
||||
CONSOLE_ROWS, CONSOLE_COLUMNS = int(CONSOLE_ROWS), int(CONSOLE_COLUMNS)
|
||||
except ValueError:
|
||||
CONSOLE_ROWS, CONSOLE_COLUMNS = 50, 80
|
||||
|
||||
|
||||
def no_color_str(text):
|
||||
return Suppress(escapeSeq).transformString(str(text))
|
||||
|
||||
|
||||
def my_debug(*args, check_started=None):
|
||||
"""
|
||||
Write one line per arg in 'debug.txt'
|
||||
:param args:
|
||||
:param check_started:
|
||||
True : first check if start_debug() was called
|
||||
<name> : first check if start_debug(name) was called
|
||||
list of <names> : first check if start_debug() is called for all names
|
||||
:return:
|
||||
"""
|
||||
if check_started and default_debug_name not in debug_activated:
|
||||
return
|
||||
|
||||
if isinstance(check_started, str) and check_started not in debug_activated:
|
||||
return
|
||||
|
||||
if isinstance(check_started, list):
|
||||
for debug_name in check_started:
|
||||
if debug_name not in debug_activated:
|
||||
return
|
||||
|
||||
with open("debug.txt", "a") as f:
|
||||
for arg in args:
|
||||
if isinstance(arg, list):
|
||||
for item in arg:
|
||||
f.write(f"{item}\n")
|
||||
else:
|
||||
f.write(f"{arg}\n")
|
||||
|
||||
|
||||
def start_debug(debug_name=default_debug_name, msg=None):
|
||||
debug_activated.add(debug_name)
|
||||
if msg:
|
||||
with open("debug.txt", "a") as f:
|
||||
f.write(f"{msg}\n")
|
||||
|
||||
|
||||
def stop_debug(debug_name=default_debug_name, msg=None):
|
||||
if msg:
|
||||
with open("debug.txt", "a") as f:
|
||||
f.write(f"{msg}\n")
|
||||
debug_activated.remove(debug_name)
|
||||
|
||||
|
||||
def sysarg_to_string(argv):
|
||||
"""
|
||||
Transform a list of strings into a single string
|
||||
@@ -606,13 +567,17 @@ def tokens_index(tokens, sub_tokens, skip=0):
|
||||
raise ValueError(f"sub tokens '{sub_tokens}' not found")
|
||||
|
||||
|
||||
def as_bag(obj):
|
||||
def as_bag(obj, forced_properties=None):
|
||||
"""
|
||||
Get the properties of an object (static and dynamic)
|
||||
:param obj:
|
||||
:param forced_properties:
|
||||
:return:
|
||||
"""
|
||||
if hasattr(obj, "as_bag"):
|
||||
|
||||
if forced_properties:
|
||||
bag = {p: getattr(obj, p) for p in forced_properties}
|
||||
elif hasattr(obj, "as_bag"):
|
||||
bag = obj.as_bag()
|
||||
else:
|
||||
bag = {} if type(obj) in PRIMITIVES_TYPES else {prop: getattr(obj, prop)
|
||||
@@ -726,3 +691,77 @@ def dump_ast(node):
|
||||
for to_remove in [", ctx=Load()", ", kind=None", ", type_ignores=[]"]:
|
||||
dump = dump.replace(to_remove, "")
|
||||
return dump
|
||||
|
||||
|
||||
def sheerka_deepcopy(obj):
|
||||
"""
|
||||
Internal implementation of deepcopy that can handle Concept circular references
|
||||
:param obj:
|
||||
:return:
|
||||
"""
|
||||
already_seen = {}
|
||||
|
||||
def copy_concept(c):
|
||||
id_c = id(c)
|
||||
if id_c in already_seen:
|
||||
ref = already_seen[id_c]
|
||||
if ref == '_##_REF_##_':
|
||||
raise Exception("Circular Ref not managed yet!")
|
||||
else:
|
||||
return ref
|
||||
|
||||
already_seen[id_c] = '_##_REF_##_'
|
||||
|
||||
cls = type(c)
|
||||
instance = cls()
|
||||
# update the metadata
|
||||
for prop_name, prop_value in vars(c.get_metadata()).items():
|
||||
if prop_name != "props":
|
||||
setattr(instance.get_metadata(), prop_name, prop_value)
|
||||
else:
|
||||
setattr(instance.get_metadata(), prop_name, sheerka_deepcopy(prop_value))
|
||||
|
||||
# update the values
|
||||
for prop_name, prop_value in c.values().items():
|
||||
setattr(instance, prop_name, prop_value)
|
||||
|
||||
already_seen[id_c] = instance
|
||||
return instance
|
||||
|
||||
from core.concept import Concept
|
||||
if isinstance(obj, dict):
|
||||
res = {sheerka_deepcopy(k): sheerka_deepcopy(v) for k, v in obj.items()}
|
||||
return res
|
||||
elif isinstance(obj, list):
|
||||
return [sheerka_deepcopy(item) for item in obj]
|
||||
elif isinstance(obj, set):
|
||||
return {sheerka_deepcopy(item) for item in obj}
|
||||
elif isinstance(obj, tuple):
|
||||
return tuple((sheerka_deepcopy(item) for item in obj))
|
||||
elif isinstance(obj, Concept):
|
||||
return copy_concept(obj)
|
||||
else:
|
||||
return deepcopy(obj)
|
||||
|
||||
|
||||
def escape_str(x):
|
||||
"""
|
||||
Returns a string representation that look like what would produce a debugger
|
||||
:param x:
|
||||
:return:
|
||||
"""
|
||||
if isinstance(x, str):
|
||||
return f"'{x}'"
|
||||
return x
|
||||
|
||||
|
||||
class NextIdManager:
|
||||
"""
|
||||
solely return the next integer
|
||||
"""
|
||||
def __init__(self):
|
||||
self.id = -1
|
||||
|
||||
def get_next_id(self):
|
||||
self.id += 1
|
||||
return self.id
|
||||
|
||||
Reference in New Issue
Block a user