Module osbot_utils.helpers.ast.Ast_Base
Expand source code
import ast
import inspect
from osbot_utils.utils.Dev import pprint, jprint
from osbot_utils.utils.Exceptions import syntax_error
from osbot_utils.utils.Files import is_file, file_contents
from osbot_utils.utils.Objects import obj_data, obj_info
from osbot_utils.utils.Str import str_dedent
class Ast_Base:
def __init__(self, node):
if node.__module__ != 'ast':
raise Exception(f'Expected node.__module__ to be ast, got: {node.__module__}')
self.node = node
def __repr__(self):
return self.__class__.__name__
def is_ast(self, target):
if hasattr(target, "__module__"):
if target.__module__ == 'ast':
return True
return False
def is_not_ast(self, target):
return self.is_ast(target) is False
def dump(self):
return ast.dump(self.node, indent=4)
def execute_code(self, exec_locals=None, exec_namespace=None):
exec_locals = exec_locals or {}
#exec_namespace = exec_namespace or {'__builtins__': {}} # this has quite a lot of side effects
exec_namespace = exec_namespace or {}
exec_error = None
try:
exec(self.source_code(), exec_namespace, exec_locals)
status = 'ok'
except Exception as error:
status = 'error'
exec_error = str(error)
return { 'status' : status ,
'error' : exec_error ,
'locals' : exec_locals ,
'namespace' : exec_namespace }
def info(self):
return {} # to be overwritten by calles that uses this base class
def json_data(self, target):
if type(target) is dict:
data = {}
for key, value in target.items():
data[key] = self.json_data(value)
return data
if type(target) is list:
data = []
for item in target:
data.append(self.json_data(item))
return data
if isinstance(target, Ast_Base):
return self.json_data(target.info())
return target
def jprint(self):
return self.jprint_json()
def jprint_json(self):
jprint(self.json())
def json(self):
return self.json_data(self.info())
def key(self):
return str(self)
def obj_data(self, remove_source_info=True):
data = obj_data(self.node)
if remove_source_info:
vars_to_del = ['col_offset', 'end_col_offset', 'lineno', 'end_lineno', 'type_comment']
for var_to_del in vars_to_del:
if data.get(var_to_del):
del data[var_to_del]
return data
def parse(self, target):
try:
if type(target) is str:
if is_file(target):
source = file_contents(target)
else:
source = target
else:
source = inspect.getsource(target)
code = str_dedent(source) # remove any training spaces or it won't compile
return ast.parse(code)
except SyntaxError as error:
raise syntax_error(error) from None
def print(self):
return self.print_dump()
def print_dump(self):
print(self.dump())
return self
def print_json(self):
pprint(self.json())
return self
def print_obj_info(self):
obj_info(self.node)
return self
def print_source_code(self):
print(self.source_code())
return self
def source_code(self):
return ast.unparse(self.node)
Classes
class Ast_Base (node)
-
Expand source code
class Ast_Base: def __init__(self, node): if node.__module__ != 'ast': raise Exception(f'Expected node.__module__ to be ast, got: {node.__module__}') self.node = node def __repr__(self): return self.__class__.__name__ def is_ast(self, target): if hasattr(target, "__module__"): if target.__module__ == 'ast': return True return False def is_not_ast(self, target): return self.is_ast(target) is False def dump(self): return ast.dump(self.node, indent=4) def execute_code(self, exec_locals=None, exec_namespace=None): exec_locals = exec_locals or {} #exec_namespace = exec_namespace or {'__builtins__': {}} # this has quite a lot of side effects exec_namespace = exec_namespace or {} exec_error = None try: exec(self.source_code(), exec_namespace, exec_locals) status = 'ok' except Exception as error: status = 'error' exec_error = str(error) return { 'status' : status , 'error' : exec_error , 'locals' : exec_locals , 'namespace' : exec_namespace } def info(self): return {} # to be overwritten by calles that uses this base class def json_data(self, target): if type(target) is dict: data = {} for key, value in target.items(): data[key] = self.json_data(value) return data if type(target) is list: data = [] for item in target: data.append(self.json_data(item)) return data if isinstance(target, Ast_Base): return self.json_data(target.info()) return target def jprint(self): return self.jprint_json() def jprint_json(self): jprint(self.json()) def json(self): return self.json_data(self.info()) def key(self): return str(self) def obj_data(self, remove_source_info=True): data = obj_data(self.node) if remove_source_info: vars_to_del = ['col_offset', 'end_col_offset', 'lineno', 'end_lineno', 'type_comment'] for var_to_del in vars_to_del: if data.get(var_to_del): del data[var_to_del] return data def parse(self, target): try: if type(target) is str: if is_file(target): source = file_contents(target) else: source = target else: source = inspect.getsource(target) code = str_dedent(source) # remove any training spaces or it won't compile return ast.parse(code) except SyntaxError as error: raise syntax_error(error) from None def print(self): return self.print_dump() def print_dump(self): print(self.dump()) return self def print_json(self): pprint(self.json()) return self def print_obj_info(self): obj_info(self.node) return self def print_source_code(self): print(self.source_code()) return self def source_code(self): return ast.unparse(self.node)
Subclasses
Methods
def dump(self)
-
Expand source code
def dump(self): return ast.dump(self.node, indent=4)
def execute_code(self, exec_locals=None, exec_namespace=None)
-
Expand source code
def execute_code(self, exec_locals=None, exec_namespace=None): exec_locals = exec_locals or {} #exec_namespace = exec_namespace or {'__builtins__': {}} # this has quite a lot of side effects exec_namespace = exec_namespace or {} exec_error = None try: exec(self.source_code(), exec_namespace, exec_locals) status = 'ok' except Exception as error: status = 'error' exec_error = str(error) return { 'status' : status , 'error' : exec_error , 'locals' : exec_locals , 'namespace' : exec_namespace }
def info(self)
-
Expand source code
def info(self): return {} # to be overwritten by calles that uses this base class
def is_ast(self, target)
-
Expand source code
def is_ast(self, target): if hasattr(target, "__module__"): if target.__module__ == 'ast': return True return False
def is_not_ast(self, target)
-
Expand source code
def is_not_ast(self, target): return self.is_ast(target) is False
def jprint(self)
-
Expand source code
def jprint(self): return self.jprint_json()
def jprint_json(self)
-
Expand source code
def jprint_json(self): jprint(self.json())
def json(self)
-
Expand source code
def json(self): return self.json_data(self.info())
def json_data(self, target)
-
Expand source code
def json_data(self, target): if type(target) is dict: data = {} for key, value in target.items(): data[key] = self.json_data(value) return data if type(target) is list: data = [] for item in target: data.append(self.json_data(item)) return data if isinstance(target, Ast_Base): return self.json_data(target.info()) return target
def key(self)
-
Expand source code
def key(self): return str(self)
def obj_data(self, remove_source_info=True)
-
Expand source code
def obj_data(self, remove_source_info=True): data = obj_data(self.node) if remove_source_info: vars_to_del = ['col_offset', 'end_col_offset', 'lineno', 'end_lineno', 'type_comment'] for var_to_del in vars_to_del: if data.get(var_to_del): del data[var_to_del] return data
def parse(self, target)
-
Expand source code
def parse(self, target): try: if type(target) is str: if is_file(target): source = file_contents(target) else: source = target else: source = inspect.getsource(target) code = str_dedent(source) # remove any training spaces or it won't compile return ast.parse(code) except SyntaxError as error: raise syntax_error(error) from None
def print(self)
-
Expand source code
def print(self): return self.print_dump()
def print_dump(self)
-
Expand source code
def print_dump(self): print(self.dump()) return self
def print_json(self)
-
Expand source code
def print_json(self): pprint(self.json()) return self
def print_obj_info(self)
-
Expand source code
def print_obj_info(self): obj_info(self.node) return self
def print_source_code(self)
-
Expand source code
def print_source_code(self): print(self.source_code()) return self
def source_code(self)
-
Expand source code
def source_code(self): return ast.unparse(self.node)