def test_snippets(self):
for input, output, kind in ((exec_tests, exec_results, "exec"),
(single_tests, single_results, "single"),
(eval_tests, eval_results, "eval")):
for i, o in itertools.izip(input, output):
ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
self.assertEqual(to_tuple(ast_tree), o)
self._assertTrueorder(ast_tree, (0, 0))
python类PyCF_ONLY_AST()的实例源码
def test_parse(self):
a = ast.parse('foo(1 + 1)')
b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
self.assertEqual(ast.dump(a), ast.dump(b))
def _find_decorators(cls):
result = dict()
def visit_FunctionDef(node):
result[node.name] = [ast.dump(e) for e in node.decorator_list]
v = ast.NodeVisitor()
v.visit_FunctionDef = visit_FunctionDef
v.visit(compile(inspect.getsource(cls), '?', 'exec', ast.PyCF_ONLY_AST))
return result
def get_ast(expr):
return convert_ast(compile(expr, '<string>', 'eval',ast.PyCF_ONLY_AST).body)
# Precedence table for figuring out whether we need to parenthesize an expression
# when printing it out
def main(argv=None):
if argv is None:
argv = sys.argv[1:]
opar = optparse.OptionParser()
opar.add_option("-d", "--dot", dest="dot",
help="output a graphviz dot file", action="store_true")
opar.add_option("-m", "--min", dest="threshold",
help="minimum complexity for output", type="int",
default=1)
options, args = opar.parse_args(argv)
code = _read(args[0])
tree = compile(code, args[0], "exec", ast.PyCF_ONLY_AST)
visitor = PathGraphingAstVisitor()
visitor.preorder(tree, visitor)
if options.dot:
print('graph {')
for graph in visitor.graphs.values():
if (not options.threshold or
graph.complexity() >= options.threshold):
graph.to_dot()
print('}')
else:
for graph in visitor.graphs.values():
if graph.complexity() >= options.threshold:
print(graph.name, graph.complexity())
def test_snippets(self):
for input, output, kind in ((exec_tests, exec_results, "exec"),
(single_tests, single_results, "single"),
(eval_tests, eval_results, "eval")):
for i, o in zip(input, output):
ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
self.assertEqual(to_tuple(ast_tree), o)
self._assertTrueorder(ast_tree, (0, 0))
def test_parse(self):
a = ast.parse('foo(1 + 1)')
b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
self.assertEqual(ast.dump(a), ast.dump(b))
def check_roundtrip(self, code1, filename="internal"):
ast1 = compile(code1, filename, "exec", ast.PyCF_ONLY_AST)
unparse_buffer = io.StringIO()
unparse.Unparser(ast1, unparse_buffer)
code2 = unparse_buffer.getvalue()
ast2 = compile(code2, filename, "exec", ast.PyCF_ONLY_AST)
self.assertASTEqual(ast1, ast2)
def test_compile_to_ast(self):
import ast
source = Source("x = 4")
mod = source.compile(flag=ast.PyCF_ONLY_AST)
assert isinstance(mod, ast.Module)
compile(mod, "<filename>", "exec")
def test_compile_to_ast(self):
import ast
source = Source("x = 4")
mod = source.compile(flag=ast.PyCF_ONLY_AST)
assert isinstance(mod, ast.Module)
compile(mod, "<filename>", "exec")
def __scan_code(code, use_ast, monkeypatch):
mg = modulegraph.ModuleGraph()
# _process_imports would set _deferred_imports to None
monkeypatch.setattr(mg, '_process_imports', lambda m: None)
module = mg.createNode(modulegraph.Script, 'dummy.py')
code = textwrap.dedent(code)
if use_ast:
co_ast = compile(code, 'dummy', 'exec', ast.PyCF_ONLY_AST)
co = compile(co_ast, 'dummy', 'exec')
else:
co_ast = None
co = compile(code, 'dummy', 'exec')
mg._scan_code(module, co)
return module
def run_script(self, pathname, caller=None):
"""
Create a node by path (not module name). It is expected to be a Python
source file, and will be scanned for dependencies.
"""
self.msg(2, "run_script", pathname)
pathname = os.path.realpath(pathname)
m = self.findNode(pathname)
if m is not None:
return m
if sys.version_info[0] != 2:
with open(pathname, 'rb') as fp:
encoding = util.guess_encoding(fp)
with open(pathname, _READ_MODE, encoding=encoding) as fp:
contents = fp.read() + '\n'
if contents.startswith(BOM):
# Ignore BOM at start of input
contents = contents[1:]
else:
with open(pathname, _READ_MODE) as fp:
contents = fp.read() + '\n'
co_ast = compile(contents, pathname, 'exec', ast.PyCF_ONLY_AST, True)
co = compile(co_ast, pathname, 'exec', 0, True)
m = self.createNode(Script, pathname)
self._updateReference(caller, m, None)
self._scan_code(m, co, co_ast)
m.code = co
if self.replace_paths:
m.code = self._replace_paths_in_code(m.code)
return m
#FIXME: For safety, the "source_module" parameter should default to the
#root node of the current graph if unpassed. This parameter currently
#defaults to None, thus disconnected modules imported in this manner (e.g.,
#hidden imports imported by depend.analysis.initialize_modgraph()).
def ast_parse(self, source, filename='<unknown>', symbol='exec'):
"""Parse code to an AST with the current compiler flags active.
Arguments are exactly the same as ast.parse (in the standard library),
and are passed to the built-in compile function."""
return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)
def handleDoctests(self, node):
try:
(docstring, node_lineno) = self.getDocstring(node.body[0])
examples = docstring and self._getDoctestExamples(docstring)
except (ValueError, IndexError):
# e.g. line 6 of the docstring for <string> has inconsistent
# leading whitespace: ...
return
if not examples:
return
node_offset = self.offset or (0, 0)
self.pushScope()
underscore_in_builtins = '_' in self.builtIns
if not underscore_in_builtins:
self.builtIns.add('_')
for example in examples:
try:
tree = compile(example.source, "<doctest>", "exec", ast.PyCF_ONLY_AST)
except SyntaxError:
e = sys.exc_info()[1]
position = (node_lineno + example.lineno + e.lineno,
example.indent + 4 + (e.offset or 0))
self.report(messages.DoctestSyntaxError, node, position)
else:
self.offset = (node_offset[0] + node_lineno + example.lineno,
node_offset[1] + example.indent + 4)
self.handleChildren(tree)
self.offset = node_offset
if not underscore_in_builtins:
self.builtIns.remove('_')
self.popScope()
def main(argv=None):
if argv is None:
argv = sys.argv[1:]
opar = optparse.OptionParser()
opar.add_option("-d", "--dot", dest="dot",
help="output a graphviz dot file", action="store_true")
opar.add_option("-m", "--min", dest="threshold",
help="minimum complexity for output", type="int",
default=1)
options, args = opar.parse_args(argv)
with open(args[0], "rU") as mod:
code = mod.read()
tree = compile(code, args[0], "exec", ast.PyCF_ONLY_AST)
visitor = PathGraphingAstVisitor()
visitor.preorder(tree, visitor)
if options.dot:
print('graph {')
for graph in visitor.graphs.values():
if (not options.threshold or
graph.complexity() >= options.threshold):
graph.to_dot()
print('}')
else:
for graph in visitor.graphs.values():
if graph.complexity() >= options.threshold:
print(graph.name, graph.complexity())
def ast_parse(self, source, filename='<unknown>', symbol='exec'):
"""Parse code to an AST with the current compiler flags active.
Arguments are exactly the same as ast.parse (in the standard library),
and are passed to the built-in compile function."""
return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)
def process(py_source, max_complexity):
code = py_source.text()
tree = compile(code, py_source, "exec", ast.PyCF_ONLY_AST)
visitor = mccabe.PathGraphingAstVisitor()
visitor.preorder(tree, visitor)
for graph in visitor.graphs.values():
if graph.complexity() > max_complexity:
text = "{}:{}:{} {} {}"
return text.format(py_source, graph.lineno, graph.column, graph.entity,
graph.complexity())
def register(name, handler, mask=None, filename=None, lineno=None):
"""Register an Event handler"""
# already registered
if name in _handlers:
return AlreadyRegistered
if handler is not None:
# handle string containing python code
if isinstance(handler, str):
tmp = "def %s(e):\n%s" % (name, handler)
try:
code = bb.methodpool.compile_cache(tmp)
if not code:
if filename is None:
filename = "%s(e)" % name
code = compile(tmp, filename, "exec", ast.PyCF_ONLY_AST)
if lineno is not None:
ast.increment_lineno(code, lineno-1)
code = compile(code, filename, "exec")
bb.methodpool.compile_cache_add(tmp, code)
except SyntaxError:
logger.error("Unable to register event handler '%s':\n%s", name,
''.join(traceback.format_exc(limit=0)))
_handlers[name] = noop
return
env = {}
bb.utils.better_exec(code, env)
func = bb.utils.better_eval(name, env)
_handlers[name] = func
else:
_handlers[name] = handler
if not mask or '*' in mask:
_catchall_handlers[name] = True
else:
for m in mask:
if _event_handler_map.get(m, None) is None:
_event_handler_map[m] = {}
_event_handler_map[m][name] = True
return Registered
def handleDoctests(self, node):
try:
if hasattr(node, 'docstring'):
docstring = node.docstring
# This is just a reasonable guess. In Python 3.7, docstrings no
# longer have line numbers associated with them. This will be
# incorrect if there are empty lines between the beginning
# of the function and the docstring.
node_lineno = node.lineno
if hasattr(node, 'args'):
node_lineno = max([node_lineno] +
[arg.lineno for arg in node.args.args])
else:
(docstring, node_lineno) = self.getDocstring(node.body[0])
examples = docstring and self._getDoctestExamples(docstring)
except (ValueError, IndexError):
# e.g. line 6 of the docstring for <string> has inconsistent
# leading whitespace: ...
return
if not examples:
return
# Place doctest in module scope
saved_stack = self.scopeStack
self.scopeStack = [self.scopeStack[0]]
node_offset = self.offset or (0, 0)
self.pushScope(DoctestScope)
underscore_in_builtins = '_' in self.builtIns
if not underscore_in_builtins:
self.builtIns.add('_')
for example in examples:
try:
tree = compile(example.source, "<doctest>", "exec", ast.PyCF_ONLY_AST)
except SyntaxError:
e = sys.exc_info()[1]
if PYPY:
e.offset += 1
position = (node_lineno + example.lineno + e.lineno,
example.indent + 4 + (e.offset or 0))
self.report(messages.DoctestSyntaxError, node, position)
else:
self.offset = (node_offset[0] + node_lineno + example.lineno,
node_offset[1] + example.indent + 4)
self.handleChildren(tree)
self.offset = node_offset
if not underscore_in_builtins:
self.builtIns.remove('_')
self.popScope()
self.scopeStack = saved_stack