Comparing expressions with eval function - python

I have write code in Python 3 in the following format :
def function1()
def function2()
def function3()
def main()
Then I call the main :
main()
The function eval() it's into my main() also.
The purpose of my code is to getting two expressions and returns whether they are equals or not.
For example :
answer = """ A ← A * 3"""
my_input = """ A ← 3 * A"""
Comparing these expressions the result must be "Equals" ( or True ).
I'm getting the error below :
Traceback (most recent call last):
File "my_path", line 218, in <module>
main()
File "my_path", line 200, in main
if eval(a) == eval(b) and eval(c) == eval(d) :
File "<string>", line 2
^
SyntaxError: unexpected EOF while parsing
Do I need to import something ?
Or to re-arrange the functions ?
I'm here to understand, not to solve the issue.
Thanks.

Related

Syntax error with exec call to an object in Python 3

I really don't understand what causes the problem, could someone point it out for me please?
with shelve.open(obj_path) as obj:
for as_num in obj['as_number_list']: # ignore warning, obj['as_number_list'] is a list
temp = charge_as(obj['as_' + str(as_num)]) # temp is an object
as_test = temp # doing like this is ok
print(type(as_test))
exec("as_{}_obj = {}".format(as_num, temp)) # **error here**
And it gives syntax error like this:
<class 'instruments.AS'>
Traceback (most recent call last):
File "...", line 45, in <module>
exec("as_{}_obj = {}".format(as_num, temp))
File "<string>", line 1
as_1_obj = <instruments.AS object at 0x000002A86732E290>
^
SyntaxError: invalid syntax
I tried
exec("as_{}_obj = {}".format(as_num, temp.__dict__))
no error is shown but now as_{}_obj is of class 'dict' instead of class 'instruments.AS'
line 45:
exec("as_{}_obj = temp".format(as_num))

SyntaxError: Invalid syntax? Eval() [duplicate]

This question already has answers here:
Why must "exec" (and not "eval") be used for Python import statements?
(3 answers)
Closed 3 years ago.
Basically I am doing a POC against python eval security issue, but I am getting below error:
Traceback (most recent call last):
File "exploit.py", line 11, in <module>
a = paste()
File "exploit.py", line 6, in paste
if eval('%s > 1' % a):
File "<string>", line 1
import os;os.system('pwd') > 1
^
SyntaxError: invalid syntax
Code:
import datetime
def paste():
a = "import os;os.system('pwd')"
if eval('%s > 1' % a):
print a
else:
#create_brew(request.json)
return None, 201
a = paste()
print a
can anyone help me how to import libraries in-line?
eval works in expressions.
Use exec to execute a statement [import is a statement]
Also note, you cannot assign exec to a variable.
>> exec('import os;data = os.getcwd()')
>> print(data)
>> # /path/of/you/cwd
You may use the variable data to continue with your tests.
Taking the liberty to edit your code as follow:
def paste():
data = None
exec('import os;data = os.getcwd()')
if data:
return data
else:
return None, 201
a = paste()
print(a)

While using the python library rply, I get an unexpected token error when parsing more than one line. How can I fix this?

For the practice, I decided to work on a simple language. When only a single line, my say(); command works fine, but when I do two says in a row, I get an error.
For Parsing I'm using rply. I was following this (https://blog.usejournal.com/writing-your-own-programming-language-and-compiler-with-python-a468970ae6df) guide. I've searched extesively but I cant find a solution.
This is the python code:
from rply import ParserGenerator
from ast import Int, Sum, Sub, Say, String
class Parser():
def __init__(self):
self.pg = ParserGenerator(
# A list of all token names accepted by the parser.
['INTEGER', 'SAY', 'OPEN_PAREN', 'CLOSE_PAREN',
'SEMI_COLON', 'SUM', 'SUB', 'STRING']
)
def parse(self):
#self.pg.production('say : SAY OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
def say(p):
return Say(p[2])
#self.pg.production('expression : expression SUM expression')
#self.pg.production('expression : expression SUB expression')
def expression(p):
left = p[0]
right = p[2]
operator = p[1]
if operator.gettokentype() == 'SUM':
return Sum(left, right)
elif operator.gettokentype() == 'SUB':
return Sub(left, right)
#self.pg.production('expression : INTEGER')
def int(p):
return Int(p[0].value)
#self.pg.production('expression : STRING')
def string(p):
return String(p[0].value)
#self.pg.error
def error_handler(token):
raise ValueError("Ran into a %s where it wasn't expected" % token.gettokentype())
def get_parser(self):
return self.pg.build()
When I run my program with the input of:
say("yo");
It works fine and return yo.
However, when I input:
say("yo");
say("yoyo");
I expect it to return yo yoyo, but instead I get this error:
C:\Users\gdog1\Desktop\proj\intparser.py:42: ParserGeneratorWarning: 4
shift/reduce conflicts
return self.pg.build()
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.3\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "C:/Users/gdog1/Desktop/proj/main.py", line 20, in <module>
parser.parse(tokens).eval()
File "C:\Python27\lib\site-packages\rply\parser.py", line 60, in parse
self.error_handler(lookahead)
File "C:\Users\gdog1\Desktop\proj\intparser.py", line 39, in error_handler
raise ValueError("Ran into a %s where it wasn't expected" %
token.gettokentype())
ValueError: Ran into a SAY where it wasn't expected
Your grammar describes a single command:
say : SAY OPEN_PAREN expression CLOSE_PAREN SEMI_COLON
So that is what the parser accepts.
If you want the input to consist of multiple commands, you need to write a grammar which describes that input:
program :
program : program say
As the error, says its with the below line:
raise ValueError("Ran into a %s where it wasn't expected" % token.gettokentype())
Change it as below and check:
raise ValueError('Ran into a %s where it wasn't expected' % (token.gettokentype()))

Implementing C-like assert

I'm trying to implement an assert function. How can I get the text of the failing condition into the error message? If I have to parse it from the backtrace, can I portably rely on anything about the format of frames?
AssertionError is just like any other exception in python, and assert is a simple statement that is equivalent to
if __debug__:
if not expression: raise AssertionError
or
if __debug__:
if not expression1: raise AssertionError(expression2)
so you can add a second parameter to your assertion to have additional output
from sys import exc_info
from traceback import print_exception
# assertions are simply exceptions in Python
try:
assert False, "assert was false"
except AssertionError:
print_exception(*exc_info())
outputs
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
AssertionError: assert was false
If you're sure the expression to test is secure you could do something like this:
File my_assert.py:
import sys
def my_assert(condition):
caller = sys._getframe(1)
if not eval(condition, caller.f_globals, caller.f_locals):
raise AssertionError(repr(condition) + " on line " +
str(caller.f_lineno) + ' in ' +
caller.f_code.co_name)
File test_my_assert.py:
from my_assert import my_assert
global_var = 42
def test():
local_var = 17
my_assert('local_var*2 < global_var') # OK
my_assert('local_var > global_var')
test()
Output:
Traceback (most recent call last):
File "test_my_assert.py", line 10, in <module>
test()
File "test_my_assert.py", line 8, in test
my_assert('local_var > global_var')
File "my_assert.py", line 8, in my_assert
caller.f_code.co_name)
AssertionError: 'local_var > global_var' on line 8 in test
My very hackish solution:
def my_assert(condition):
if not eval(condition):
# error stuff
Then use it by placing the condition in quotation marks. It is then a string that can be printed in the error message.
Or, if you want it to actually raise an AssertionError:
def my_assert(condition):
if not eval(condition):
raise AssertionError(condition)

Parsing python with PLY

I'm trying to write a python parser, and in my opiniion it could parse an "if statement" but it doesn't.
It shows me a "syntax error" message.
Can someone tell me what I'm doing wrong?
Thanks in advance.
The code is here: https://github.com/narke/py2neko
I modified the input string like this:
s = '''if 5:
print 10
else:
print 20 \n'''
check_syntax(s)
and the output is:
Syntax error at '5'
atom: 10
factor None
None
cmp: None None
atom: 20
factor None
None
cmp: None None
simple_stmt: None
From your code:
s = "if 5:\n"
check_syntax(s)
if 5:\n is not valid syntax because it is not a complete if statement. You need to provide a suite (code to execute) if the expression is True. For example:
>>> if 5:
...
File "<stdin>", line 2
^
IndentationError: expected an indented block
>>> compile('if 5:\n', '<string>', 'exec')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
if 5:
^
SyntaxError: unexpected EOF while parsing
>>> compile('if 5:\n print 5', '<string>', 'exec')
<code object <module> at 0xb7f60530, file "<string>", line 2>

Categories

Resources