def barron_mwe_error_unicode_literal(): import textwrap import redbaron # This works properly text = textwrap.dedent(''' p1, p2 = (1, 2) ''').strip('\n') red = redbaron.RedBaron(text) # But this fails when we use unicode symbols for identifiers text = textwrap.dedent(''' ρ1, ρ2 = (1, 2) ''').strip('\n') red = redbaron.RedBaron(text) # Still fails with a single unicdoe element text = textwrap.dedent(''' ρ2 = 2 ''').strip('\n') red = redbaron.RedBaron(text) # Still fails with different unicode identifiers even with explicit # unicode literal futures text = textwrap.dedent(''' from __future__ import unicode_literals θ = 2 ''').strip('\n') red = redbaron.RedBaron(text) # System information import sys print('sys.version_info = {!r}'.format(sys.version_info)) import ubelt as ub _ = ub.cmd('pip list | grep redbaron', shell=True, verbose=1)
def autogen_mkint_utils(): import ubelt as ub # Uses netharn closer until it is ported to a standalone module from liberator import closer closer = closer.Closer() from ubelt import util_import closer.add_dynamic(util_import.split_modpath) closer.add_dynamic(util_import.modpath_to_modname) closer.add_dynamic(util_import.modname_to_modpath) closer.expand(["ubelt"]) text = closer.current_sourcecode() print(text) import redbaron new_baron = redbaron.RedBaron(text) new_names = [n.name for n in new_baron.node_list if n.type in ["class", "def"]] import mkinit from mkinit import util from mkinit.util import util_import # NOQA old_baron = redbaron.RedBaron(open(mkinit.util.util_import.__file__, "r").read()) old_names = [n.name for n in old_baron.node_list if n.type in ["class", "def"]] set(old_names) - set(new_names) set(new_names) - set(old_names) prefix = ub.codeblock( ''' # -*- coding: utf-8 -*- """ This file was autogenerated based on code in ubelt """ from __future__ import print_function, division, absolute_import, unicode_literals ''' ) code = prefix + "\n" + text + "\n" print(code) fpath = ub.expandpath("~/code/mkinit/mkinit/util/util_import.py") open(fpath, "w").write(code)
def process_code(py_code): # create the ast ast = redbaron.RedBaron(py_code) global simple_calls, chained_calls, print_calls # replaces all traditional function calls for node in ast.find_all("atomtrailers"): # every CallNode is preceded by a NameNode that contains the name of # the function for i in range(len(node.value)): if isinstance(node.value[i], redbaron.nodes.CallNode): # we replace the NameNode value node.value[i - 1].replace("foo") # i < 3 means there is no trainwreck of object accesses and # func calls, like z.y().x() if i < 3: simple_calls += 1 else: chained_calls += 1 # replaces (almost) all print function calls for node in ast.find_all("print"): parent = node.parent # reassigning top-level nodes doesn't work at the moment # todo: replace top-level prints as well if (isinstance(parent, redbaron.redbaron.RedBaron)): break # looks for the node in the parent's children, such that it can get # reassigned to a foo function call node, while keeping the same # parameters for i in range(len(parent.value)): if (parent.value[i] == node): if isinstance(node.value[0], \ redbaron.nodes.AssociativeParenthesisNode): # handle new python print("abcd") syntax parent.value[i] = redbaron.RedBaron("foo" + \ str(node.value[0])) else: # handle old python print "abcd" syntax parent.value[i] = redbaron.RedBaron("foo(" + \ str(node.value[0]) + ")") print_calls += 1 # unparses the AST and returns the code and simple_calls chained_calls and # print_calls for unit testing the stats part # todo: refactor simple_calls, chained_calls, etc. return ast.dumps(), simple_calls, chained_calls, print_calls
def test_get_node_of_region_simple(): """Test get_node_of_region for when start and end are part of a simple expression""" testsrc = redbaron.RedBaron("1+1") start = reddel_server.Position(1, 1) end = reddel_server.Position(1, 3) expected = testsrc[0] assert expected == reddel_server.get_node_of_region(testsrc, start, end)
def _update_init_all(module_path, r): """Add or update __all__ in __init__.py file.""" module_dir_path = os.path.split(module_path)[0] module_list = [] for item_name in os.listdir(module_dir_path): item_path = os.path.join(module_dir_path, item_name) if os.path.isfile(item_path) and item_name in ("__init__.py", "setup.py"): continue if os.path.isfile(item_path) and not item_name.endswith(".py"): continue # if os.path.isdir(item_path) and not os.path.isfile( # os.path.join(item_path, '__init__.py') # ): # continue if os.path.isdir(item_path): continue module_list.append(re.sub(r".py$", "", item_name).encode("utf-8")) module_literal_str = str(sorted(module_list)) assignment_node_list = r("AssignmentNode", recursive=False) for n in assignment_node_list: if n.type == "assignment" and n.target.value == "__all__": n.value = module_literal_str break else: r.node_list.append( redbaron.RedBaron("__all__ = {}\n".format(module_literal_str))) return r
def test_OptionalRegionValidator_transform_no_region(): """Test that there is no tranformation without any region""" testsrc = redbaron.RedBaron("a=1+1\nb=5") validator = reddel_server.OptionalRegionValidator() result = validator.transform(testsrc) expected = (testsrc, None, None) assert expected == result
def test_get_node_of_region_same(): """Test get_node_of_region for when start and end are the same nodes""" testsrc = redbaron.RedBaron("lambda: 1+1") start = reddel_server.Position(1, 1) end = reddel_server.Position(1, 2) expected = testsrc[0] assert expected == reddel_server.get_node_of_region(testsrc, start, end)
def test_SingleNodeValidator_transform_region_no_list(): """Test that there is no transformation if there is a region""" testsrc = redbaron.RedBaron("1+1") validator = reddel_server.SingleNodeValidator() expected = (testsrc, (1, 1), (1, 3)) assert expected == validator.transform(testsrc, start=reddel_server.Position(1, 1), end=reddel_server.Position(1, 3))
def program_as_ast(path): ''' returns program (specified by path) as Python abstract syntax tree (Redbaron)''' try: str_repr = open(path, 'r').read() except: print("specified file doesn't exist") #TODO replace with proper error return rb.RedBaron(str_repr)
def _update_init_all(module_path, r): """Add or update __all__ in __init__.py file""" module_dir_path = os.path.split(module_path)[0] module_list = [] for item_name in os.listdir(module_dir_path): item_path = os.path.join(module_dir_path, item_name) if os.path.isfile(item_path) and item_name in ('__init__.py', 'setup.py'): continue if os.path.isfile(item_path) and not item_name.endswith('.py'): continue # if os.path.isdir(item_path) and not os.path.isfile( # os.path.join(item_path, '__init__.py') # ): # continue if os.path.isdir(item_path): continue module_list.append(re.sub(r'.py$', '', item_name).encode('utf-8')) module_literal_str = str(sorted(module_list)) assignment_node_list = r('AssignmentNode', recursive=False) for n in assignment_node_list: if n.type == 'assignment' and n.target.value == '__all__': n.value = module_literal_str break else: r.node_list.append( redbaron.RedBaron('__all__ = {}\n'.format(module_literal_str))) return r
def parse_version_from_module() -> Tuple[ version.Version, redbaron.RedBaron, redbaron.Node ]: # Parse the AST and load the `__version__` node so that we can edit it # later. with open("synapse/__init__.py") as f: red = redbaron.RedBaron(f.read()) version_node = None for node in red: if node.type != "assignment": continue if node.target.type != "name": continue if node.target.value != "__version__": continue version_node = node break if not version_node: print("Failed to find '__version__' definition in synapse/__init__.py") sys.exit(1) # Parse the current version. current_version = version.parse(version_node.value.value.strip('"')) assert isinstance(current_version, version.Version) return current_version, red, version_node
def evaluate(self, filename): ''' Calcola la Complessità Cognitiva per tutte le funzioni ed i metodi definiri nel file. - filename: file python da parsare -> torna un dizionario { 'nomeFunzione': cc, 'nomeClasse.nomeMetodo': cc } ''' fns = dict() with open(filename) as file: red = redbaron.RedBaron(file.read()) # trova tutte le funzioni e ne costruisce il nome puntato (Class.method...) for fn in red.find_all("def"): names = [] p = fn while p: names = [p.name] + names p = p.parent_find([ 'def', 'class' ]) # trova funzioni o classi che contengono la funzione name = '.'.join(names) #if not fn.parent_find("DefNode"): # FIXME: necessario? cc = self.__sequences(fn) + self.__conditions( fn) + self.__structures(fn) fns[name] = cc return fns
def test_get_node_of_region_slice_list_declaration(): """Test get_node_of_region for when the nodes slice a list declaration""" testsrc = redbaron.RedBaron("[1, 2, 3, 4, 5, 6]") start = reddel_server.Position(1, 8) end = reddel_server.Position(1, 14) expected = "3, 4, 5" assert expected == reddel_server.get_node_of_region(testsrc, start, end).dumps()
def test_get_parents(): """Test retrieving all parents from a node""" testsrc = redbaron.RedBaron("def foo(): a = 1+1") testnode = testsrc.find_by_position((1, 18)) parents = reddel_server.get_parents(testnode) expected = [testnode.parent, testnode.parent.parent, testnode.parent.parent.parent, testnode.parent.parent.parent.parent] assert expected == list(parents)
def read_module_txt_n_fst(path): """Parse module source code in form of Full Syntax Tree.""" mod_src_text = read_text_from_file(path) try: return mod_src_text, redbaron.RedBaron(mod_src_text) except ParsingError: logger.exception('failed parsing on %s', mod_src_text) raise
def split_by_last_import(r): import_node_list = r("ImportNode", recursive=False) if not import_node_list: return redbaron.RedBaron("").node_list, r.node_list last_import_n = import_node_list[-1] import_r = r.node_list[:last_import_n.index_on_parent_raw + 1] remaining_r = r.node_list[last_import_n.index_on_parent_raw + 1:] return import_r, remaining_r
def test_collect_f_names(): PATH = "./data/example.py" str_repr = open(PATH, 'r').read() ast = rb.RedBaron(str_repr) result = m.collect_f_names(ast) EXPECTED_NO_FUNCTIONS = 3 contents_as_expected = ("foo" in result and "bar" in result and "baz" in result) assert (len(result) == EXPECTED_NO_FUNCTIONS and contents_as_expected)
def test_OptionalRegionValidator_transform_region(): """Test that the region is extracted when specified""" testsrc = redbaron.RedBaron("a=1+1\nb=5") start = reddel_server.Position(1, 1) end = reddel_server.Position(1, 4) validator = reddel_server.OptionalRegionValidator() result = validator.transform(testsrc, start, end) expected = (testsrc[0], reddel_server.Position(1, 1), reddel_server.Position(1, 5)) assert expected == result, "Expected that the region was extracted and the bounding box was updated."
def insert_import_node(r, dotted_name): new_r = redbaron.NodeList() first = True for v in r.node_list: if v.type == "import" and first: first = False new_r.append(redbaron.RedBaron("import {}\n".format(dotted_name))) new_r.append(v) return new_r
def _autogen_xdoctest_utils(): import ubelt as ub # Uses netharn closer until it is ported to a standalone module import netharn as nh closer = nh.export.closer.Closer() from ubelt import util_import closer.add_dynamic(util_import.split_modpath) closer.add_dynamic(util_import.modpath_to_modname) closer.add_dynamic(util_import.modname_to_modpath) closer.add_dynamic(util_import.import_module_from_name) closer.add_dynamic(util_import.import_module_from_path) closer.add_dynamic(util_import._pkgutil_modname_to_modpath) closer.add_dynamic(util_import._importlib_import_modpath) closer.add_dynamic(util_import.is_modname_importable) closer.expand(['ubelt']) text = closer.current_sourcecode() print(text) import redbaron new_baron = redbaron.RedBaron(text) new_names = [n.name for n in new_baron.node_list if n.type in ['class', 'def']] import xdoctest old_baron = redbaron.RedBaron(open(xdoctest.utils.util_import.__file__, 'r').read()) old_names = [n.name for n in old_baron.node_list if n.type in ['class', 'def']] set(old_names) - set(new_names) set(new_names) - set(old_names) prefix = ub.codeblock( ''' # -*- coding: utf-8 -*- """ This file was autogenerated based on code in ubelt """ from __future__ import print_function, division, absolute_import, unicode_literals ''') fpath = ub.expandpath('~/code/xdoctest/xdoctest/utils/util_import.py') open(fpath, 'w').write(prefix + '\n' + text + '\n')
def load_style(filepath): file = open(filepath, 'r').read() ast = redbaron.RedBaron(file) gdict = ast.find('assign', lambda x: x.find('name', 'pnlv_graphics_spec')) namespace = {} if gdict: exec(gdict.dumps(), namespace) pnl_container.graphics_spec = namespace['pnlv_graphics_spec'] else: pnl_container.graphics_spec = {}
def test_get_node_of_region_slice_list(): """Test get_node_of_region for when the nodes are only a slice in a node list""" testsrc = redbaron.RedBaron("1+1\n" "a=1\n" "for i in range(10):\n" " b=i\n" "c=3") start = reddel_server.Position(2, 3) # a="1" end = reddel_server.Position(4, 6) # b"="1 expected = redbaron.NodeList(testsrc.node_list[2:5]) assert expected.dumps() == reddel_server.get_node_of_region(testsrc, start, end).dumps()
def test_get_node_of_region_slice_for_loop(): """Test get_node_of_region for when the nodes slice a for loop body""" testsrc = redbaron.RedBaron("for i in range(10):\n" " a = 1 + 2\n" " b = 4\n" " c = 5\n" " d = 7\n") start = reddel_server.Position(3, 7) end = reddel_server.Position(5, 8) expected = "b = 4\n c = 5\n d = 7" assert expected == reddel_server.get_node_of_region(testsrc, start, end).dumps()
def render_func(module, func): def_node = redbaron.RedBaron(getsource(func))[0] hints = typing.get_type_hints(func) args = {} for arg in def_node.arguments: name = arg.target.value args[name] = make_instance(hints.get(name)) Context(module, args).eval(def_node)
def update_graphics_dict(styleSheet): ast = redbaron.RedBaron(pnl_container.AST) gdict = ast.find('assign', lambda x: x.find('name', 'pnlv_graphics_spec')) stylesheet_str = json.dumps(styleSheet, indent=4) if gdict: gdict.value = stylesheet_str ast = ast.dumps() else: ast = ast.dumps( ) + f'\n# PsyNeuLinkView Graphics Info \npnlv_graphics_spec = {stylesheet_str}\n' pnl_container.AST = ast with open(pnl_container.filepath, 'w') as script: script.write(ast)
def get_new_source(target, kind, filepath=None): """Get the new source code of the target if given kind ('class' or 'def'). This works by using RedBaron to fetch the source code of the first object that shares its name and kind with the target, inside the Python file from which the target has been loaded. """ assert kind in ('class', 'def') filepath = filepath or inspect.getsourcefile(target) red = redbaron.RedBaron(open(filepath).read()) # dumps() returns Python code as a string return red.find(kind, target.__name__).dumps()
def _add_absolute_import(r): if has_future_absolute_import(r): return r new_r = redbaron.NodeList() first = True for v in r.node_list: if v.type == "import" and first: first = False new_r.append( redbaron.RedBaron("from __future__ import absolute_import\n")) new_r.append(v) return new_r
def barron_mwe_error_dict_unpack(): import textwrap import redbaron text = textwrap.dedent(''' d1 = {1: 2} d2 = {3: 4} d_combo = {**d1, **d2} ''').strip('\n') # This code should work exec(text) # But it does not red = redbaron.RedBaron(text)
def _insert_copyright_header(r): for i, n in enumerate(r.node_list): if n.type == 'comment' and re.search(r'Copyright.*DataONE', n.value): return r logging.info('Adding copyright header') i = 0 for n in r('CommentNode', recursive=False)[:3]: if n.value.startswith('#!') or 'coding' in n.value: # Skip endl node. i = n.index_on_parent_raw + 2 r.node_list.insert( i, redbaron.RedBaron(COPYRIGHT_NOTICE.format(datetime.datetime.now().year)) ) return r
def msplit(self, line): print line args = parse_argstring(self.msplit, line) print args if not args.target: raise ValueError('FF') if args.delimiter: delim = args.delimiter[0] else: delim = '#%#' filename = args.target[0] shell = self.shell with open(filename, "r") as source_code: red = redbaron.RedBaron(source_code.read()) # r = open('test.py','r') # t = ast.parse(r.read()) if not args.function: outlist = group_extraction(red, delim) for stringlist in outlist[::-1]: string = "\n".join(stringlist) make_cell(string) else: func_name = args.function[0] func = find_func(red, func_name) # get everything BUT that function first_outlist = [] for item in red: if item != func: first_outlist.append(item.dumps()) firstoutstr = "\n".join(first_outlist) # lets modify a copy of the function func = func.copy() # parse arguments argstr = parse_func_args(func) func.value.decrease_indentation(4) secondoutlist = group_extraction(func.value, delim) tocelllist = [firstoutstr, argstr] for stringlist in secondoutlist: string = "\n".join(stringlist) if string.strip('\n').strip(' ') != '': tocelllist.append(string) for item in tocelllist[::-1]: make_cell(item)