def test_issue_9011(self): # Issue 9011: compilation of an unary minus expression changed # the meaning of the ST, so that a second compilation produced # incorrect results. st = parser.expr('-3') code1 = parser.compilest(st) self.assertEqual(eval(code1), -3) code2 = parser.compilest(st) self.assertEqual(eval(code2), -3)
def test_compile_filename(self): st = parser.expr('a + 5') code = parser.compilest(st) self.assertEqual(code.co_filename, '<syntax-tree>') code = st.compile() self.assertEqual(code.co_filename, '<syntax-tree>') for filename in ('file.py', b'file.py', bytearray(b'file.py'), memoryview(b'file.py')): code = parser.compilest(st, filename) self.assertEqual(code.co_filename, 'file.py') code = st.compile(filename) self.assertEqual(code.co_filename, 'file.py') self.assertRaises(TypeError, parser.compilest, st, list(b'file.py')) self.assertRaises(TypeError, st.compile, list(b'file.py'))
def get_real_roots(_eq): terms = [token[1] for token in tokenize.generate_tokens(StringIO(_eq).readline) if token[1]] # Better eq.split() try: final_term = int("".join(terms[-2:])) # Constant except ValueError: print("Invalid expression:", _eq, ", final term must be an integer constant") return "Error" _eq = parser.compilest(parser.expr(_eq)) # Parses string expression into executable code possible_roots = get_divisors(final_term) _roots = [x for x in possible_roots if eval(_eq) == 0] return _roots
def find_executable_linenos(filename): """return a dict of the line numbers from executable statements in a file Works by finding all of the code-like objects in the module then searching the byte code for 'SET_LINENO' terms (so this won't work one -O files). """ import parser prog = open(filename).read() ast = parser.suite(prog) code = parser.compilest(ast, filename) # The only way I know to find line numbers is to look for the # SET_LINENO instructions. Isn't there some way to get it from # the AST? return _find_LINENO(code)
def _esoteric_source(src): if str_check(src): return parser.suite(src).compile() if is_ast_node(src): if isinstance(src, ast.ClassDef): node = ast.Module([src]) elif (isinstance(src, ast.Module) and isinstance(src.body[0], ast.ClassDef)): node = src else: raise TypeError(f'build_class() using an ast node as the ' f'class body it must be a ast.Class node ' f'or an ast.Module node whose .body[0] is ' f'a Class') return compile(node, '<ast.Class>', 'exec') if isinstance(src, (tuple, list)): src = parser.sequence2st(src) if isinstance(src, parser.STType): if not parser.issuite(src): raise TypeError(f'build_class() the parser syntax tree objects ' f'must be a "suite"') return parser.compilest(src)
def test_issue_9011(self): st = parser.expr('-3') code1 = parser.compilest(st) self.assertEqual(eval(code1), -3) code2 = parser.compilest(st) self.assertEqual(eval(code2), -3)
def test_compile_suite(self): st = parser.suite('x = 2; y = x + 3') code = parser.compilest(st) globs = {} exec(code, globs) self.assertEqual(globs['y'], 5)
def test_compile_expr(self): st = parser.expr('2 + 3') code = parser.compilest(st) self.assertEqual(eval(code), 5)
def dump_and_modify(node): name = symbol.sym_name.get(node[0]) if name is None: name = token.tok_name.get(node[0]) print(name, '', end='') for i in range(1, len(node)): item = node[i] if type(item) is type([]): dump_and_modify(item) else: print(repr(item)) if name == 'NUMBER': node[i] = repr(int(item) + 1) ast = parser.expr('1 + 3') list = ast.tolist() dump_and_modify(list) ast = parser.sequence2st(list) print(eval(parser.compilest(ast))) ''' eval_input testlist test or_test and_test not_test comparison expr xor_expr and_expr shift_expr arith_expr term factor power atom NUMBER '1' PLUS '+' term factor power atom NUMBER '3' NEWLINE '' ENDMARKER '' 6 [Finished in 0.2s] '''
def ParseAndCompileUserFunctionString(self, inString): # shift user functions into numpy namespace at run time, not import time numpySafeTokenList = [] for key in list(self.functionDictionary.keys()): numpySafeTokenList += self.functionDictionary[key] for key in list(self.constantsDictionary.keys()): numpySafeTokenList += self.constantsDictionary[key] # no blank lines of text, StringIO() allows using file methods on text stringToConvert = '' rawData = io.StringIO(inString).readlines() for line in rawData: stripped = line.strip() if len(stripped) > 0: # no empty strings if stripped[0] != '#': # no comment-only lines stringToConvert += stripped + '\n' # convert brackets to parentheses stringToConvert = stringToConvert.replace('[', '(').replace(']', ')') if stringToConvert == '': raise Exception( 'You must enter some function text for the software to use.') if -1 != stringToConvert.find('='): raise Exception( 'Please do not use an equals sign "=" in your text.') st = parser.expr(stringToConvert) tup = st.totuple() tokens = self.GetTokensFromTupleParsingHelper(tup) if '^' in tokens: raise Exception( 'The caret symbol "^" is not recognized by the parser, please substitute double asterisks "**" for "^".' ) if 'ln' in tokens: raise Exception( "The parser uses log() for the natural log function, not ln(). Please use log() in your text." ) if 'abs' in tokens: raise Exception( "The parser uses fabs() for the absolute value, not abs(). Please use fabs() in your text." ) if 'EXP' in tokens: raise Exception( "The parser uses lower case exp(), not upper case EXP(). Please use lower case exp() in your text." ) if 'LOG' in tokens: raise Exception( "The parser uses lower case log(), not upper case LOG(). Please use lower case log() in your text." ) # test for required reserved tokens tokenNames = list(set(tokens) - set(numpySafeTokenList)) if 'X' not in tokenNames: raise Exception( 'You must use a separate upper case "X" in your function to enter a valid function of X.' ) if 'Y' not in tokenNames: raise Exception( 'You must use a separate upper case "Y" in your function to enter a valid function of Y.' ) self._coefficientDesignators = sorted( list(set(tokenNames) - set(['X', 'Y']))) if len(self._coefficientDesignators) == 0: raise Exception( 'I could not find any equation parameter or coefficient names, please check the function text' ) # now compile code object using safe tokens with integer conversion self.safe_dict = locals() for f in numpySafeTokenList: self.safe_dict[f] = eval('numpy.' + f) # convert integer use such as (3/2) into floats such as (3.0/2.0) st = parser.expr(stringToConvert) stList = parser.st2list(st) stList = self.RecursivelyConvertIntStringsToFloatStrings(stList) st = parser.sequence2st(stList) # later evals re-use this compiled code for improved performance in EvaluateCachedData() methods self.userFunctionCodeObject = parser.compilest(st)
def eval(self, expression): """Evaluate an expression within the namespace of the instance.""" # pylint: disable=eval-used,no-self-use return eval(parser.compilest(parser.expr(expression))) or ""
def test_compile_expr(self): st = parser.expr('2 + 3') code = parser.compilest(st) self.assertEquals(eval(code), 5)
def get_code(source, source_name): translated_source = translate_tokens(source) tree = get_parse_tree(translated_source, source_name) transformed = Transform(tree).get_st() code = compilest(transformed, filename=source_name) return code
def test_compile_suite(self): st = parser.suite("x = 2; y = x + 3") code = parser.compilest(st) globs = {} exec code in globs self.assertEqual(globs["y"], 5)
print(name, '', end = '') for i in range(1, len(node)): item = node[i] if type(item) is type([]): dump_and_modify(item) else: print(repr(item)) if name == 'NUMBER': node[i] = repr(int(item) + 1) ast = parser.expr('1 + 3') list = ast.tolist() dump_and_modify(list) ast = parser.sequence2st(list) print(eval(parser.compilest(ast))) ''' eval_input testlist test or_test and_test not_test comparison expr xor_expr and_expr shift_expr arith_expr term factor power atom NUMBER '1' PLUS '+' term factor power atom NUMBER '3' NEWLINE '' ENDMARKER '' 6 [Finished in 0.2s] '''
arg = l[1] print command, arg print(convert_to_s(test)) convert_to_binwhy LOAD_FAST argument PYTHON BYTECODE(test) print print '***' print import parser #st = parser.expr('a + 5') # eval st = parser.suite('a = 5') # exec print parser.isexpr(st) print parser.issuite(st) code = parser.compilest(st) dis.disassemble(code) print dir(code) #code = st.compile('file.py') # http://docs.python.org/library/inspect.html print print 'argc : ', code.co_argcount # number of arguments (not including * or ** args) print 'consts : ', code.co_consts # tuple of constants used in the bytecode print 'names : ', code.co_names # tuple of names of local variables print 'nlocals : ', code.co_nlocals # number of local variables print 'code : ', code.co_code # string of raw compiled bytecode print 'var names : ', code.co_varnames # tuple of names of arguments and local variables print 'stack size :', code.co_stacksize # virtual machine stack space required print eval(code) print a
def test_compile_suite(self): st = parser.suite('x = 2; y = x + 3') code = parser.compilest(st) globs = {} exec(code, globs) self.assertEquals(globs['y'], 5)
def ParseAndCompileUserFunctionString(self, inString): # shift user functions into numpy namespace at run time, do not import time numpySafeTokenList = [] for key in list(self.functionDictionary.keys()): numpySafeTokenList += self.functionDictionary[key] for key in list(self.constantsDictionary.keys()): numpySafeTokenList += self.constantsDictionary[key] # to shift user functions such as "power" into the numpy namespace "numpy.power" for evaluation for token in numpySafeTokenList: exec(token + " = numpy." + token) # no blank lines of text, StringIO() allows using file methods on text stringToConvert = "" rawData = StringIO.StringIO(inString).readlines() for line in rawData: stripped = line.strip() if len(stripped) > 0: # no empty strings if stripped[0] != "#": # no comment-only lines stringToConvert += stripped + "\n" # convert brackets to parentheses stringToConvert = stringToConvert.replace("[", "(").replace("]", ")") if stringToConvert == "": raise Exception("You must enter some function text for the software to use.") if -1 != stringToConvert.find("="): raise Exception('Please do not use an equals sign "=" in your text.') st = parser.expr(stringToConvert) tup = st.totuple() tokens = self.GetTokensFromTupleParsingHelper(tup) if "^" in tokens: raise Exception( 'The caret symbol "^" is not recognized by the parser, please substitute double asterisks "**" for "^".' ) if "ln" in tokens: raise Exception( "The parser uses log() for the natural log function, not ln(). Please use log() in your text." ) if "abs" in tokens: raise Exception("The parser uses fabs() for the absolute value, not abs(). Please use fabs() in your text.") if "EXP" in tokens: raise Exception( "The parser uses lower case exp(), not upper case EXP(). Please use lower case exp() in your text." ) if "LOG" in tokens: raise Exception( "The parser uses lower case log(), not upper case LOG(). Please use lower case log() in your text." ) # test for required reserved tokens tokenNames = list(set(tokens) - set(numpySafeTokenList)) if "X" not in tokenNames: raise Exception('You must use a separate upper case "X" in your function to enter a valid function of X.') if "Y" not in tokenNames: raise Exception('You must use a separate upper case "Y" in your function to enter a valid function of Y.') self._coefficientDesignators = sorted(list(set(tokenNames) - set(["X", "Y"]))) if len(self._coefficientDesignators) == 0: raise Exception( "I could not find any equation parameter or coefficient names, please check the function text" ) # now compile code object using safe tokens self.safe_dict = dict([(k, locals().get(k, None)) for k in numpySafeTokenList]) # now compile code object using safe tokens with integer conversion self.safe_dict = dict([(k, locals().get(k, None)) for k in numpySafeTokenList]) # convert integer use such as (3/2) into floats such as (3.0/2.0) st = parser.expr(stringToConvert) stList = parser.st2list(st) stList = self.RecursivelyConvertIntStringsToFloatStrings(stList) st = parser.sequence2st(stList) # later evals re-use this compiled code for improved performance in EvaluateCachedData() methods self.userFunctionCodeObject = parser.compilest(st)