def test_oauth_auth_example():
import ast
import _ast
import codegen
client_id = "n4mnzQGfDEfOhFixwBvLV2mZJJLvf86pzfMMiPF5"
client_secret = "40ON9IPJRDAngUkVbGBTEjCBAwc2wB7lV8e71jJUPKabdKq6KBTUBKb1xGkh82KtAI1AqISrL3Zi4sTfhCBVh27YvlV6Y5klpXXV5loUWvuhMSRiN3HRZzVDO0fLBibv"
with open("examples/oauth_auth_example.py", "r") as f:
data = f.read()
p = ast.parse(data)
for node in p.body:
if type(node) == _ast.Assign:
if node.targets[0].id == 'client_id':
node.value.s = client_id
if node.targets[0].id == 'client_secret':
node.value.s = client_secret
ls = {}
exec(codegen.to_source(p), ls)
assert ls['course']['courses'][0]['id'] == 67
python类Assign()的实例源码
def UNPACK_SEQUENCE(self, instr):
nargs = instr.oparg
nodes = []
ast_tuple = _ast.Tuple(elts=nodes, ctx=_ast.Store(), lineno=instr.lineno, col_offset=0)
for i in range(nargs):
nex_instr = self.ilst.pop(0)
self.ast_stack.append(None)
self.visit(nex_instr)
node = self.ast_stack.pop()
nodes.append(node.targets[0])
expr = self.ast_stack.pop()
if isinstance(expr, _ast.Assign):
assgn = expr
assgn.targets.append(ast_tuple)
value_dup = self.ast_stack.pop()
assert cmp_ast(assgn.value, value_dup)
else:
assgn = _ast.Assign(targets=[ast_tuple], value=expr, lineno=instr.lineno, col_offset=0)
self.ast_stack.append(assgn)
def STORE_SUBSCR(self, instr):
index = self.ast_stack.pop()
value = self.ast_stack.pop()
expr = self.ast_stack.pop()
expr = self.process_ifexpr(expr)
if isinstance(expr, _ast.AugAssign):
self.ast_stack.append(expr)
else:
kw = dict(lineno=instr.lineno, col_offset=0)
index = self.format_slice(index, kw)
subscr = _ast.Subscript(value=value, slice=index, ctx=_ast.Store(), **kw)
assign = _ast.Assign(targets=[subscr], value=expr, **kw)
self.ast_stack.append(assign)
def __new__(cls, name, bases, dct):
slots = dct.get('__slots__', [])
orig_slots = []
for base in bases:
if hasattr(base, "__slots__"):
orig_slots += base.__slots__
if '__init__' in dct:
init = dct['__init__']
initproc = type.__new__(cls, name, bases, dct)
initproc_source = inspect.getsource(initproc)
ast = compile(initproc_source, "dont_care", 'exec', _ast.PyCF_ONLY_AST)
classdef = ast.body[0]
stmts = classdef.body
for declaration in stmts:
if isinstance(declaration, _ast.FunctionDef):
name1 = declaration.name
if name1 == '__init__': # delete this line if you do not initialize all instance variables in __init__
initbody = declaration.body
for statement in initbody:
if isinstance(statement, _ast.Assign):
for target in statement.targets:
name1 = target.attr
if name1 not in orig_slots:
slots.append(name1)
if slots:
dct['__slots__'] = slots
return type.__new__(cls, name, bases, dct)
def _transform_multiline_assignment_statements(statements):
assignment_statements = [statement for statement in statements
if type(statement) is _ast.BinOp
and type(statement.op) is _ast.LShift
and type(statement.left) is _ast.Name]
other_statements = [statement for statement in statements if statement not in assignment_statements]
assignments = [ast.Assign(targets=[statement.left], value=statement.right, lineno=statement.lineno, col_offset=statement.col_offset)
for statement in assignment_statements]
for assignment in assignments:
assignment.targets[0].ctx = ast.Store()
return other_statements + assignments
def parse_assign_expr(ctx, tree, subparser):
if isinstance(tree, _ast.Assign):
assert len(tree.targets) == 1 and isinstance(tree.targets[0], _ast.Name)
return RowExprAssign(tree.targets[0].id, subparser(ctx, tree.value))
elif isinstance(tree, _ast.Expr):
if isinstance(tree.value, _ast.Name):
return RowExprAssign(tree.value.id, subparser(ctx, tree))
else:
raise Exception("Please assign expression to a variable")
else:
raise Exception("Please assign expression to a variable")
def isLiteralTupleUnpacking(self, node):
if isinstance(node, ast.Assign):
for child in node.targets + [node.value]:
if not hasattr(child, 'elts'):
return False
return True
def isLiteralTupleUnpacking(self, node):
if isinstance(node, ast.Assign):
for child in node.targets + [node.value]:
if not hasattr(child, 'elts'):
return False
return True
def SETUP_WITH(self, instr):
with_block = self.make_block(to=instr.to, inclusive=False)
assert with_block.pop().opname == 'LOAD_CONST'
assert with_block.pop().opname == 'POP_BLOCK'
with_cleanup = self.ilst.pop(0)
assert with_cleanup.opname == 'WITH_CLEANUP'
end_finally = self.ilst.pop(0)
assert end_finally.opname == 'END_FINALLY'
with_ = self.decompile_block(with_block, stack_items=['WITH_BLOCK']).stmnt()
if isinstance(with_[0], _ast.Assign) and with_[0].value == 'WITH_BLOCK':
assign = with_.pop(0)
as_ = assign.targets[0]
else:
as_ = None
body = with_
expr = self.ast_stack.pop()
with_ = _ast.With(context_expr=expr, optional_vars=as_, body=body,
lineno=instr.lineno, col_offset=0)
self.ast_stack.append(with_)
def pop_assignment(stmnts, name):
for i in range(len(stmnts)):
stmnt = stmnts[i]
if isinstance(stmnt, _ast.Assign) and len(stmnt.targets) == 1 \
and isinstance(stmnt.targets[0], _ast.Name) \
and isinstance(stmnt.targets[0].ctx, _ast.Store):
if stmnt.targets[0].id == name:
stmnts.pop(i)
return stmnt.value
return None
def ROT_TWO(self, instr):
one = self.ast_stack.pop()
two = self.ast_stack.pop()
if self.ilst[0].opname == 'STORE_NAME':
kw = dict(lineno=instr.lineno, col_offset=0)
stores = []
while self.ilst[0].opname == 'STORE_NAME':
stores.append(self.ilst.pop(0))
assert len(stores) <= 3, stores
elts_load = [one, two]
if len(stores) == 3:
elts_load.insert(0, self.ast_stack.pop())
tup_load = _ast.Tuple(elts=elts_load[::-1], ctx=_ast.Load(), **kw)
elts_store = [_ast.Name(id=store.arg, ctx=_ast.Store(), **kw) for store in stores]
tup_store = _ast.Tuple(elts=elts_store, ctx=_ast.Store(), **kw)
assgn = _ast.Assign(value=tup_load, targets=[tup_store], **kw)
self.ast_stack.append(assgn)
# self.ast_stack.append(tup_store)
else:
self.ast_stack.append(one)
self.ast_stack.append(two)
def STORE_SLICE_0(self, instr):
'obj[:] = expr'
value = self.ast_stack.pop()
expr = self.ast_stack.pop()
kw = dict(lineno=instr.lineno, col_offset=0)
slice = _ast.Slice(lower=None, step=None, upper=None, **kw)
subscr = _ast.Subscript(value=value, slice=slice, ctx=_ast.Store(), **kw)
assign = _ast.Assign(targets=[subscr], value=expr, **kw)
self.ast_stack.append(assign)
def STORE_SLICE_1(self, instr):
'obj[lower:] = expr'
lower = self.ast_stack.pop()
value = self.ast_stack.pop()
expr = self.ast_stack.pop()
kw = dict(lineno=instr.lineno, col_offset=0)
slice = _ast.Slice(lower=lower, step=None, upper=None, **kw)
subscr = _ast.Subscript(value=value, slice=slice, ctx=_ast.Store(), **kw)
assign = _ast.Assign(targets=[subscr], value=expr, **kw)
self.ast_stack.append(assign)
def STORE_SLICE_2(self, instr):
'obj[:upper] = expr'
upper = self.ast_stack.pop()
value = self.ast_stack.pop()
expr = self.ast_stack.pop()
kw = dict(lineno=instr.lineno, col_offset=0)
slice = _ast.Slice(lower=None, step=None, upper=upper, **kw)
subscr = _ast.Subscript(value=value, slice=slice, ctx=_ast.Store(), **kw)
assign = _ast.Assign(targets=[subscr], value=expr, **kw)
self.ast_stack.append(assign)
def isLiteralTupleUnpacking(self, node):
if isinstance(node, ast.Assign):
for child in node.targets + [node.value]:
if not hasattr(child, 'elts'):
return False
return True
def __new__(cls, name: str, bases: list, dictionary: dict) -> object:
slots, original_slots = dictionary.get('__slots__', []), []
for base in bases:
if hasattr(base, "__slots__"):
original_slots += base.__slots__
if '__init__' in dictionary:
init_src = getsource(type.__new__(cls, name, bases, dictionary))
ast = compile(init_src, "", 'exec', _ast.PyCF_ONLY_AST, optimize=2)
for declaration in tuple(ast.body[0].body):
if isinstance(declaration, _ast.FunctionDef):
nombre = declaration.name
if nombre == '__init__':
initbody = declaration.body
for statement in initbody:
if isinstance(statement, _ast.Assign):
for target in statement.targets:
nombrecito = target.attr
if nombrecito not in original_slots:
slots.append(nombrecito)
dictionary['__slots__'] = namedtuple("AutoSlots", slots)(*slots)
dictionary['__doc__'] = dictionary.get(
'__doc__', f"""{name} class from '{dictionary['__module__']}'.
\nInstantiated using Angler AutoSlots MetaClass.
Mutable/writable/readable attributes: {dictionary['__slots__']}
\nThis does not make the {name} class Inmmutable.
\nAdding new attributes via assignments/setattr/etc is Blocked.
\nUses less memory, speeds up attribute accesses and avoid bugs
\nTry to add new attributes to this {name} class will raise:
AttributeError: {name} object has no attribute\n\n""" + __doc__
)
return type.__new__(cls, name, bases, dictionary)
def visit_FunctionDef(self, node):
"""
:type node: _ast.FunctionDef
"""
children = node.body
lambda_assign_children = [child for child in children
if type(child) == _ast.Assign
and len(child.targets) == 1
and type(child.value) == _ast.Compare
and (type(child.value.left) == _ast.Tuple or type(child.value.left) == _ast.Name)
and all(map(lambda t: type(t) == _ast.Name, getattr(child.value.left, 'elts', [])))]
# Support single line lambdas outside of assigns
other_children = [child for child in children if child not in lambda_assign_children]
for child in other_children:
CompareNodeVisitor().visit(child)
for assign_type_child in lambda_assign_children:
arguments = _transform_function_arguments(assign_type_child.value.left)
function_body = assign_type_child.value.comparators[0]
if _is_multiline_lambda(function_body):
all_statements = function_body.elts
return_statement = all_statements[-1]
statements = all_statements[0:len(all_statements) - 1]
statements = _transform_multiline_assignment_statements(statements)
return_statement = _transform_multiline_return_statement(return_statement)
assign_target = assign_type_child.targets[0]
if type(assign_target) is _ast.Attribute:
function_name = assign_target.attr
else:
function_name = assign_target.id
all_transformed_statements = statements + [return_statement]
functiondef_object = ast.FunctionDef(args = arguments,
body=all_transformed_statements,
lineno=assign_type_child.lineno,
name=function_name,
col_offset=assign_type_child.col_offset,
decorator_list=[])
children.insert(0, functiondef_object)
assign_type_child.value = ast.Name(id=functiondef_object.name,
col_offset=functiondef_object.col_offset,
lineno=functiondef_object.lineno,
ctx=ast.Load())
else:
lambda_ast_transform = ast.Lambda(args=arguments,
body=function_body,
lineno=assign_type_child.lineno,
col_offset = assign_type_child.col_offset)
assign_type_child.value = lambda_ast_transform
return node
def make_list_comp(self, get_iter, for_iter):
block = self.make_block(for_iter.to, inclusive=False, raise_=False)
jump_abs = block.pop()
assert jump_abs.opname == 'JUMP_ABSOLUTE', jump_abs.opname
jump_map = {for_iter.i:for_iter.to}
stmnts = self.decompile_block(block, stack_items=[None], jump_map=jump_map).stmnt()
if len(stmnts) > 1:
assign = stmnts.pop(0)
assert len(stmnts) == 1
assert isinstance(assign, _ast.Assign)
list_expr = self.ast_stack.pop()
# empty ast.List object
list_ = self.ast_stack.pop()
ifs = []
elt = refactor_ifs(stmnts[0], ifs)
assert len(assign.targets) == 1
generators = [_ast.comprehension(target=assign.targets[0], iter=list_expr, ifs=ifs, lineno=get_iter.lineno, col_offset=0)]
if isinstance(list_, _ast.Assign):
comp = _ast.comprehension(target=list_.targets[0], iter=None, ifs=ifs, lineno=get_iter.lineno, col_offset=0)
generators.insert(0, comp)
list_comp = _ast.ListComp(elt=elt, generators=generators, lineno=get_iter.lineno, col_offset=0)
else:
list_expr = self.ast_stack.pop()
list_comp = stmnts[0]
generators = list_comp.generators
# empty ast.List object
list_ = self.ast_stack.pop()
if not isinstance(list_, _ast.Assign):
comp = _ast.comprehension(target=list_.targets[0], iter=None, ifs=[], lineno=get_iter.lineno, col_offset=0)
generators.insert(0, comp)
generators[0].iter = list_expr
self.ast_stack.append(list_comp)
def LOAD_BUILD_CLASS(self, instr):
class_body = []
body_instr = instr
while body_instr.opname not in function_ops:
body_instr = self.ilst.pop(0)
class_body.append(body_instr)
call_func = self.decompile_block(class_body, stack_items=[None]).stmnt()
assert len(call_func) == 1
call_func = call_func[0]
func_def = call_func.args[0]
code = func_def.body
name = call_func.args[1].s
bases = call_func.args[2:]
keywords = call_func.keywords
kwargs = call_func.kwargs
starargs = call_func.starargs
if isinstance(code[0], _ast.Expr):
_name = code.pop(1)
_doc = code.pop(1)
elif isinstance(code[0], _ast.Assign):
_name = code.pop(0)
else:
assert False
ret = code.pop(-1)
assert isinstance(ret, _ast.Return)
class_ = _ast.ClassDef(name=name, bases=bases, body=code, decorator_list=[],
kwargs=kwargs, keywords=keywords, starargs=starargs,
lineno=instr.lineno, col_offset=0,
)
self.ast_stack.append(class_)
def STORE_NAME(self, instr):
value = self.ast_stack.pop()
value = self.process_ifexpr(value)
if isinstance(value, _ast.Import):
if value.from_:
assert isinstance(self.ast_stack[-1], _ast.ImportFrom)
from_ = self.ast_stack.pop()
as_name = instr.arg
name = from_.names[0].name
if as_name != name:
from_.names[0].asname = as_name
self.ast_stack.append(from_)
else:
as_name = instr.arg
if value.names[0].asname is None:
base_name = value.names[0].name.split('.')[0]
if base_name != as_name:
value.names[0].asname = as_name
self.ast_stack.append(value)
elif isinstance(value, (_ast.Attribute)) and isinstance(value.value, (_ast.Import)):
asname = instr.arg
value = value.value
value.names[0].asname = asname
self.ast_stack.append(value)
elif isinstance(value, (_ast.ClassDef, _ast.FunctionDef)):
as_name = instr.arg
value.name = as_name
self.ast_stack.append(value)
elif isinstance(value, _ast.AugAssign):
self.ast_stack.append(value)
elif isinstance(value, _ast.Assign):
_ = self.ast_stack.pop()
assname = _ast.Name(instr.arg, _ast.Store(), lineno=instr.lineno, col_offset=0)
value.targets.append(assname)
self.ast_stack.append(value)
else:
assname = _ast.Name(instr.arg, _ast.Store(), lineno=instr.lineno, col_offset=0)
assign = _ast.Assign(targets=[assname], value=value, lineno=instr.lineno, col_offset=0)
self.ast_stack.append(assign)