Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_token():
# Test token formatting of: LOAD_CONST None
t = Token('LOAD_CONST', offset=0, attr=None, pattr=None, has_arg=True)
expect = ' 0 LOAD_CONST None'
# print(t.format())
assert t
assert t.format() == expect
# Make sure equality testing of tokens ignores offset
t2 = Token('LOAD_CONST', offset=2, attr=None, pattr=None, has_arg=True)
assert t2 == t
# Make sure formatting of: LOAD_CONST False. We assume False is the 0th index
# of co_consts.
t = Token('LOAD_CONST', offset=1, attr=False, pattr=False, has_arg=True)
expect = ' 1 LOAD_CONST 0 False'
assert t.format() == expect
def __hash__(self):
return hash(self.kind)
def __getitem__(self, i):
raise IndexError
def off2int(self):
if isinstance(self.offset, int):
return self.offset
else:
assert isinstance(self.offset, str)
return(int(self.offset.split("_")[0]))
NoneToken = Token("LOAD_CONST", offset=-1, attr=None, pattr=None)
try:
if first_stmt == NAME_MODULE:
if self.hide_internal:
del ast[0]
first_stmt = ast[0][0]
pass
except:
pass
have_qualname = False
if self.version < 3.0:
# Should we ditch this in favor of the "else" case?
qualname = '.'.join(self.classes)
QUAL_NAME = AST('stmt',
[ AST('assign',
[ AST('expr', [Token('LOAD_CONST', pattr=qualname)]),
AST('store', [ Token('STORE_NAME', pattr='__qualname__')])
])])
have_qualname = (ast[0][0] == QUAL_NAME)
else:
# Python 3.4+ has constants like 'cmp_to_key..K'
# which are not simple classes like the < 3 case.
try:
if (first_stmt[0] == 'assign' and
first_stmt[0][0][0] == 'LOAD_CONST' and
first_stmt[0][1] == 'store' and
first_stmt[0][1][0] == Token('STORE_NAME', pattr='__qualname__')):
have_qualname = True
except:
pass
if have_qualname:
def transform(self, ast):
self.maybe_show_tree(ast)
self.ast = copy(ast)
self.ast = self.traverse(self.ast, is_lambda=False)
try:
for i in range(len(self.ast)):
if is_docstring(self.ast[i]):
docstring_ast = SyntaxTree(
"docstring",
[
Token(
"LOAD_STR",
has_arg=True,
offset=0,
pattr=self.ast[i][0][0][0][0].attr,
)
],
transformed_by="transform",
)
del self.ast[i]
self.ast.insert(0, docstring_ast)
break
if self.ast[-1] == RETURN_NONE:
self.ast.pop() # remove last node
# todo: if empty, add 'pass'
except:
if version <= 2.4:
TABLE_DIRECT.update({
'importmultiple': ( '%|import %c%c\n', 2, 3),
'import_cont' : ( ', %c', 2),
})
if version == 2.3:
TABLE_DIRECT.update({
'if1_stmt': ( '%|if 1\n%+%c%-', 5 )
})
global NAME_MODULE
NAME_MODULE = AST('stmt',
[ AST('assign',
[ AST('expr',
[Token('LOAD_GLOBAL', pattr='__name__',
offset=0, has_arg=True)]),
AST('store',
[ Token('STORE_NAME', pattr='__module__',
offset=3, has_arg=True)])
])])
pass
if version <= 2.3:
TABLE_DIRECT.update({
'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', 1, 4 )
})
if version <= 2.1:
TABLE_DIRECT.update({
'importmultiple': ( '%c', 2 ),
'imports_cont': ( '%c', 2 ),
# FIXME: not quite right. We have indiividual imports
# when there is in fact one: "import a, b, ..."
'importmultiple': ( '%|import %c%c\n', 2, 3),
'import_cont' : ( ', %c', 2),
})
if version == 2.3:
TABLE_DIRECT.update({
'if1_stmt': ( '%|if 1\n%+%c%-', 5 )
})
global NAME_MODULE
NAME_MODULE = AST('stmt',
[ AST('assign',
[ AST('expr',
[Token('LOAD_GLOBAL', pattr='__name__',
offset=0, has_arg=True)]),
AST('store',
[ Token('STORE_NAME', pattr='__module__',
offset=3, has_arg=True)])
])])
pass
if version <= 2.3:
TABLE_DIRECT.update({
'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', 1, 4 )
})
if version <= 2.1:
TABLE_DIRECT.update({
'importmultiple': ( '%c', 2 ),
'imports_cont': ( '%c', 2 ),
# FIXME: not quite right. We have indiividual imports
# when there is in fact one: "import a, b, ..."
'imports_cont': ( '%C%,', (1, 100, '\n') ),
})
pass
'dict_comp': 0,
'generator_exp': 0, # (expressions...)
'list': 0, # [expressions...]
'list_comp': 0,
'set_comp': 0,
'set_comp_expr': 0,
'unary_convert': 0,
}
LINE_LENGTH = 80
# Some parse trees created below are used for comparing code
# fragments (like 'return None' at the end of functions).
RETURN_LOCALS = SyntaxTree('return',
[ SyntaxTree('ret_expr', [SyntaxTree('expr', [ Token('LOAD_LOCALS') ])]),
Token('RETURN_VALUE')])
NONE = SyntaxTree('expr', [ NoneToken ] )
RETURN_NONE = SyntaxTree('stmt',
[ SyntaxTree('return',
[ NONE, Token('RETURN_VALUE')]) ])
PASS = SyntaxTree('stmts',
[ SyntaxTree('sstmt',
[ SyntaxTree('stmt',
[ SyntaxTree('pass', [])])])])
ASSIGN_DOC_STRING = lambda doc_string, doc_load: \
SyntaxTree('stmt',
[ SyntaxTree('assign',
# The bytecode for the end of the main routine has a
# "return None". However you can't issue a "return" statement in
# main. So as the old cigarette slogan goes: I'd rather switch (the token stream)
# than fight (with the grammar to not emit "return None").
if self.hide_internal:
if len(tokens) >= 2 and not noneInNames:
if tokens[-1].kind in ('RETURN_VALUE', 'RETURN_VALUE_LAMBDA'):
# Python 3.4's classes can add a "return None" which is
# invalid syntax.
if tokens[-2].kind == 'LOAD_CONST':
if isTopLevel or tokens[-2].pattr is None:
del tokens[-2:]
else:
tokens.append(Token('RETURN_LAST'))
else:
tokens.append(Token('RETURN_LAST'))
if len(tokens) == 0:
return PASS
# Build AST from disassembly.
try:
ast = python_parser.parse(self.p, tokens, customize)
except (python_parser.ParserError, AssertionError) as e:
raise ParserError(e, tokens)
maybe_show_ast(self.showast, ast)
checker(ast, False, self.ast_errors)
return ast
"else_suite",
"opt_come_from_except",
),
),
):
return False
# Make sure all of the "come froms" offset at the
# end of the "if" come from somewhere inside the "if".
# Since the come_froms are ordered so that lowest
# offset COME_FROM is last, it is sufficient to test
# just the last one.
come_froms = ast[-1]
if come_froms == "opt_come_from_except" and len(come_froms) > 0:
come_froms = come_froms[0]
if not isinstance(come_froms, Token):
return tokens[first].offset > come_froms[-1].attr
elif tokens[first].offset > come_froms.attr:
return True
# For mysterious reasons a COME_FROM in tokens[last+1] might be part of the grammar rule
# even though it is not found in come_froms.
# Work around this.
if (
last < n
and tokens[last] == "COME_FROM"
and tokens[first].offset > tokens[last].attr
):
return True
testexpr = ast[0]
def is_return_none(self, node):
# Is there a better way?
ret = (node[0] == 'ret_expr'
and node[0][0] == 'expr'
and node[0][0][0] == 'LOAD_CONST'
and node[0][0][0].pattr is None)
if self.version <= 2.6:
return ret
else:
# FIXME: should the AST expression be folded into
# the global RETURN_NONE constant?
return (ret or
node == AST('return_stmt',
[AST('ret_expr', [NONE]), Token('RETURN_VALUE')]))