def test_dump(self):
node = ast.parse('spam(eggs, "and cheese")')
self.assertEqual(ast.dump(node),
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
"args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], "
"keywords=[], starargs=None, kwargs=None))])"
)
self.assertEqual(ast.dump(node, annotate_fields=False),
"Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
"Str('and cheese')], [], None, None))])"
)
self.assertEqual(ast.dump(node, include_attributes=True),
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
"lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), "
"lineno=1, col_offset=5), Str(s='and cheese', lineno=1, "
"col_offset=11)], keywords=[], starargs=None, kwargs=None, "
"lineno=1, col_offset=4), lineno=1, col_offset=0)])"
)
python类Module()的实例源码
def generic_visit(self, node):
# Fallback when we don't have a special implementation.
if _is_ast_expr(node):
mod = ast.Expression(node)
co = self._compile(mod)
try:
result = self.frame.eval(co)
except Exception:
raise Failure()
explanation = self.frame.repr(result)
return explanation, result
elif _is_ast_stmt(node):
mod = ast.Module([node])
co = self._compile(mod, "exec")
try:
self.frame.exec_(co)
except Exception:
raise Failure()
return None, None
else:
raise AssertionError("can't handle %s" %(node,))
def generic_visit(self, node):
# Fallback when we don't have a special implementation.
if _is_ast_expr(node):
mod = ast.Expression(node)
co = self._compile(mod)
try:
result = self.frame.eval(co)
except Exception:
raise Failure()
explanation = self.frame.repr(result)
return explanation, result
elif _is_ast_stmt(node):
mod = ast.Module([node])
co = self._compile(mod, "exec")
try:
self.frame.exec_(co)
except Exception:
raise Failure()
return None, None
else:
raise AssertionError("can't handle %s" %(node,))
def generic_visit(self, node):
# Fallback when we don't have a special implementation.
if _is_ast_expr(node):
mod = ast.Expression(node)
co = self._compile(mod)
try:
result = self.frame.eval(co)
except Exception:
raise Failure()
explanation = self.frame.repr(result)
return explanation, result
elif _is_ast_stmt(node):
mod = ast.Module([node])
co = self._compile(mod, "exec")
try:
self.frame.exec_(co)
except Exception:
raise Failure()
return None, None
else:
raise AssertionError("can't handle %s" %(node,))
def pythoneval(self, args, debug=False):
refs = [ast.Name("x{0}".format(i), ast.Load()) for i in xrange(len(args))]
if sys.version_info[0] <= 2:
params = ast.arguments([ast.Name("x{0}".format(i), ast.Param()) for i in xrange(len(args))], None, None, [])
fcn = ast.FunctionDef("tmp", params, [ast.Return(self.pythonast(refs))], [])
else:
params = ast.arguments([ast.arg("x{0}".format(i), None) for i in xrange(len(args))], None, [], [], None, [])
fcn = ast.FunctionDef("tmp", params, [ast.Return(self.pythonast(refs))], [], None)
moduleast = ast.Module([fcn])
fakeLineNumbers(moduleast)
if debug:
print(astToSource(fcn))
modulecomp = compile(moduleast, "Femtocode", "exec")
out = {"$importlib": importlib, "$math": math}
exec(modulecomp, out)
return out["tmp"](*args)
def eval_function_def(function_def, globals_=None, flags=None):
"""
Evaluates an AST of a function definition with an optional dictionary of globals.
Returns a callable function (a ``types.FunctionType`` object).
"""
assert type(function_def) == ast.FunctionDef
# Making a copy before mutating
module = ast.Module(body=[copy.deepcopy(function_def)])
ast.fix_missing_locations(module)
if flags is not None:
kwds = dict(dont_inherit=True, flags=flags)
else:
kwds = {}
code_object = compile(module, '<nofile>', 'exec', **kwds)
locals_ = {}
eval(code_object, globals_, locals_)
return locals_[function_def.name]
def make_module(*stmts):
m = ast.Module(list(stmts))
return ast.copy_location(m, stmts[0]) if stmts else m
def build_cfg(module_node, project_modules, local_modules, filename):
"""Create a Control Flow Graph.
Args:
module_node(ast.Module) is the first node (Module) of an Abstract Syntax Tree generated with the module_node module.
"""
visitor = Visitor(module_node, project_modules, local_modules, filename)
return CFG(visitor.nodes)
def visit_Assign(self, assign):
value_explanation, value_result = self.visit(assign.value)
explanation = "... = %s" % (value_explanation,)
name = ast.Name("__exprinfo_expr", ast.Load(),
lineno=assign.value.lineno,
col_offset=assign.value.col_offset)
new_assign = ast.Assign(assign.targets, name, lineno=assign.lineno,
col_offset=assign.col_offset)
mod = ast.Module([new_assign])
co = self._compile(mod, "exec")
try:
self.frame.exec_(co, __exprinfo_expr=value_result)
except Exception:
raise Failure(explanation)
return explanation, value_result
def func_to_ast(func: types.FunctionType, file: str = None) -> ast.Module:
"""
Return node object for function.
"""
if func and not isinstance(func, types.FunctionType):
raise TypeError('Unexpected type: {}'.format(str(type(func))))
result = None
if func and hasattr(func, '__code__'):
result = code_to_ast(func.__code__, file)
return result
def source_to_ast(source: str, file: str = None) -> ast.Module:
"""
Return node object for python source.
"""
if source and not isinstance(source, str):
raise TypeError('Unexpected type: {}'.format(str(type(source))))
return _call_with_frames_removed\
( ast.parse
, source = source
, filename = file or '<file>'
, mode = 'exec'
)
def ast_to_module(node: ast.AST, old_module: types.ModuleType = None, file: str = None) -> types.ModuleType:
"""
Compile node object to module.
"""
if node and not isinstance(node, ast.AST):
raise TypeError('Unexpected type for node: {}'.format(str(type(node))))
if old_module and not isinstance(old_module, types.ModuleType):
raise TypeError('Unexpected type for old_module: {}'.format(str(type(old_module))))
if not isinstance(node, ast.Module):
node = ast.copy_location(ast.Module(body = [node]), node)
file = file or (inspect.getfile(old_module) if old_module else None)
code = _call_with_frames_removed\
( compile
, source = node
, filename = file or '<file>'
, mode = 'exec'
, dont_inherit = True
)
module = old_module or types.ModuleType()
exec(code, module.__dict__)
return module
def visit_Module(self, node: ast.Module):
self._values = {}
return self.generic_visit(node)
def anonymizeNames(a, namesToKeep, imports):
"""Anonymize all of variables/names that occur in the given AST"""
"""If we run this on an anonymized AST, it will fix the names again to get rid of any gaps!"""
if type(a) != ast.Module:
return a
globalMap = { }
for var in namesToKeep:
globalMap[var] = var
anonymizeStatementNames(a, globalMap, "", imports, goBackwards=True)
return a
def isStatement(a):
"""Determine whether the given node is a statement (vs an expression)"""
return type(a) in [ ast.Module, ast.Interactive, ast.Expression, ast.Suite,
ast.FunctionDef, ast.ClassDef, ast.Return, ast.Delete,
ast.Assign, ast.AugAssign, ast.For, ast.While,
ast.If, ast.With, ast.Raise, ast.Try,
ast.Assert, ast.Import, ast.ImportFrom, ast.Global,
ast.Expr, ast.Pass, ast.Break, ast.Continue ]
def gatherAllHelpers(a, restricted_names):
"""Gather all helper function names in the tree that have been anonymized"""
if type(a) != ast.Module:
return set()
helpers = set()
for item in a.body:
if type(item) == ast.FunctionDef:
if not hasattr(item, "dontChangeName") and item.name not in restricted_names: # this got anonymized
origName = item.originalId if hasattr(item, "originalId") else None
helpers |= set([(item.name, origName)])
return helpers
def get_docstring_and_rest(filename):
"""Separate `filename` content between docstring and the rest
Strongly inspired from ast.get_docstring.
Returns
-------
docstring: str
docstring of `filename`
rest: str
`filename` content without the docstring
"""
with open(filename) as f:
content = f.read()
node = ast.parse(content)
if not isinstance(node, ast.Module):
raise TypeError("This function only supports modules. "
"You provided {0}".format(node.__class__.__name__))
if node.body and isinstance(node.body[0], ast.Expr) and \
isinstance(node.body[0].value, ast.Str):
docstring_node = node.body[0]
docstring = docstring_node.value.s
# This get the content of the file after the docstring last line
# Note: 'maxsplit' argument is not a keyword argument in python2
rest = content.split('\n', docstring_node.lineno)[-1]
return docstring, rest
else:
raise ValueError(('Could not find docstring in file "{0}". '
'A docstring is required by sphinx-gallery')
.format(filename))
def _validate_identifier(name):
try:
mod = ast.parse('%s = 1' % name)
except SyntaxError:
return False
else:
if (isinstance(mod, ast.Module) and len(mod.body) == 1 and
isinstance(mod.body[0], ast.Assign) and
len(mod.body[0].targets) == 1 and
isinstance(mod.body[0].targets[0], ast.Name)):
return True
return False
def make_module(function_asts, main_ast):
module_body = function_asts
module_body.append(ast.Expr(value=main_ast))
module_ast = ast.Module(body=module_body)
ast.fix_missing_locations(module_ast)
return module_ast
def isidentifier(ident):
"""
Determines, if string is valid Python identifier using the ast module.
Orignally posted at: http://stackoverflow.com/a/29586366
"""
if not isinstance(ident, string_types):
return False
try:
root = ast.parse(ident)
except SyntaxError:
return False
if not isinstance(root, ast.Module):
return False
if len(root.body) != 1:
return False
if not isinstance(root.body[0], ast.Expr):
return False
if not isinstance(root.body[0].value, ast.Name):
return False
if root.body[0].value.id != ident:
return False
return True