Syntax error with exec call in Python - python

Quick python question about the exec command. I'm have Python 2.7.6 and am trying to make use of the exec to run some code stored in a .txt file. I've run into a syntax error and am not entirely sure what is causing it.
Traceback (most recent call last):
File "/Users/XYZ/Desktop/parser.py", line 46, in <module>
try_code(block)
File "<string>", line 1
x = 'Hello World!'
^
SyntaxError: invalid syntax
I initially thought it was complaining about carriage returns, but when I tried to edit them .replace them with ' ' I still received this error message. I've tried variations to see what appears to be the issue and it always declares the error as the first ' or " the program encounters when it runs exec.
Here is the try_code(block) method
def try_code(block):
exec block
And the main body of the program
inputFile = open('/Users/XYZ/Desktop/test.txt', 'r+')
starter = False
finished = False
check = 1
block = ""
for val in inputFile:
starter = lookForStart(val)
finished = lookForEnd(val)
if lookForStart:
check = 1
elif finished:
try_code(block)
if check == 1:
check = 0
elif finished == False:
block = block + val
Basically I'm trying to import a file (test.txt) and then look for some embedded code in it. To make it easier I surrounded it with indicators, thus starter and finished. Then I concatenate all the hidden code into one string and call try_code on it. Then try_code attempts to execute it (it does make it there, check with print statements) and fails with the Syntax error.
As a note it works fine if I have hidden something like...
x = 5
print x
so whatever the problem is appears to be dealing with strings for some reason.
EDIT
It would appear that textedit includes some extra characters that aren't displayed normally. I rewrote the test file in a different text editor (text wrangler) and it would seem that the characters have disappeared. Thank you all very much for helping me solve my problem, I appreciate it.

It is a character encoding issue. Unless you've explicitly declared character encoding of your Python source code at the top of the file; it is 'ascii' by default on Python 2.
The code that you're trying to execute contains non-ascii quotes:
>>> print b'\xe2\x80\x98Hello World\xe2\x80\x99'.decode('utf-8')
‘Hello World’
To fix it; use ordinary single quotes instead: 'Hello World'.
You can check that block doesn't contain non-ascii characters using decode method: block.decode('ascii') it raises an exception if there are.
A gentle introduction into the topic: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
by Joel Spolsky.

Related

python giving a E501: line too long error

While trying to input my API key python is giving me a line too long code
E501: line too long
What I have is
notifications_client = NotificationsAPIClient(aaaaaaa_aaaaaaaa-11aa1a1a-aa11-111a-aaaa-11111aaa1a1a-aa11a1a1-0aa1-11a1-1111-1aa111a0a111)
For obvious reasons I have changed the API key to have only a's 1's and 0's but how can I break up this line of code so I no longer get this error?
E501 is a linter error, not a Python interpreter error. Your code, in theory, should work just fine. If you want to prevent this error, simply break the value up (assuming it's a string ... you don't make that clear):
my_key = ('aaaaaaa_aaaaaaaa-11aa1a1a-aa11-111a-aaaa-'
'11111aaa1a1a-aa11a1a1-0aa1-11a1-1111-'
'1aa111a0a111')
notifications_client = NotificationsAPIClient(my_key)
E501 is not a python error, rather than a PEP8 error. Meaning your line is longer than 80 chars (in your case it's 137 chars long).
Your editor or runtime are verifying that your code is correct by PEP8 rules and that's why you are getting this "error". Your Python code has actually no errors at all.
If you want your code to be PEP8 compliant I suggest:
Extract the API key to a local variable.
If it's still too long you can break up the string into multiple lines
Here is an example:
API_KEY = 'aaaaaaa_aaaaaaaa-11aa1a1a-aa11-111a' \
'-aaaa-11111aaa1a1a-aa11a1a1-0aa1-' \
'11a1-1111-1aa111a0a111'
notifications_client = NotificationsAPIClient(API_KEY)
Use \ to break your line. Like;
notifications_client = NotificationsAPIClient(aaaaaaa_aaaaaaaa-11aa1a1a-\
aa11-111a-aaaa-11111aaa1a1a-\
aa11a1a1-0aa1-11a1-1111-1aa111a0a111)
Option which doesn't involved breaking the string literal:
notifications_client = NotificationsAPIClient(
"kkkkkkkkkkkkkeeeeeeeeeeeeeeeeeeeeeeeeeeyyyyyyyyyyyyyyyyyyyyy"
)
So long as your key is <73 (minus scope indentation) characters long. If not, you'll have to split it.

How to tell if a single line of python is syntactically valid?

It is very similar to this:
How to tell if a string contains valid Python code
The only difference being instead of the entire program being given altogether, I am interested in a single line of code at a time.
Formally, we say a line of python is "syntactically valid" if there exists any syntactically valid python program that uses that particular line.
For instance, I would like to identify these as syntactically valid lines:
for i in range(10):
x = 1
Because one can use these lines in some syntactically valid python programs.
I would like to identify these lines as syntactically invalid lines:
for j in range(10 in range(10(
x =++-+ 1+-
Because no syntactically correct python programs could ever use these lines
The check does not need to be too strict, it just need to be good enough to filter out obviously bogus statements (like the ones shown above). The line is given as a string, of course.
This uses codeop.compile_command to attempt to compile the code. This is the same logic that the code module does to determine whether to ask for another line or immediately fail with a syntax error.
import codeop
def is_valid_code(line):
try:
codeop.compile_command(line)
except SyntaxError:
return False
else:
return True
It can be used as follows:
>>> is_valid_code('for i in range(10):')
True
>>> is_valid_code('')
True
>>> is_valid_code('x = 1')
True
>>> is_valid_code('for j in range(10 in range(10(')
True
>>> is_valid_code('x = ++-+ 1+-')
False
I'm sure at this point, you're saying "what gives? for j in range(10 in range(10( was supposed to be invalid!" The problem with this line is that 10() is technically syntactically valid, at least according to the Python interpreter. In the REPL, you get this:
>>> 10()
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
10()
TypeError: 'int' object is not callable
Notice how this is a TypeError, not a SyntaxError. ast.parse says it is valid as well, and just treats it as a call with the function being an ast.Num.
These kinds of things can't easily be caught until they actually run.
If some kind of monster managed to modify the value of the cached 10 value (which would technically be possible), you might be able to do 10(). It's still allowed by the syntax.
What about the unbalanced parentheses? This fits the same bill as for i in range(10):. This line is invalid on its own, but may be the first line in a multi-line expression. For example, see the following:
>>> is_valid_code('if x ==')
False
>>> is_valid_code('if (x ==')
True
The second line is True because the expression could continue like this:
if (x ==
3):
print('x is 3!')
and the expression would be complete. In fact, codeop.compile_command distinguishes between these different situations by returning a code object if it's a valid self-contained line, None if the line is expected to continue for a full expression, and throwing a SyntaxError on an invalid line.
However, you can also get into a much more complicated problem than initially stated. For example, consider the line ). If it's the start of the module, or the previous line is {, then it's invalid. However, if the previous line is (1,2,, it's completely valid.
The solution given here will work if you only work forward, and append previous lines as context, which is what the code module does for an interactive session. Creating something that can always accurately identify whether a single line could possibly exist in a Python file without considering surrounding lines is going to be extremely difficult, as the Python grammar interacts with newlines in non-trivial ways. This answer responds with whether a given line could be at the beginning of a module and continue on to the next line without failing.
It would be better to identify what the purpose of recognizing single lines is and solve that problem in a different way than trying to solve this for every case.
I am just suggesting, not sure if going to work... But maybe something with exec and try-except?
code_line += "\n" + ("\t" if code_line[-1] == ":" else "") + "pass"
try:
exec code_line
except SyntaxError:
print "Oops! Wrong syntax..."
except:
print "Syntax all right"
else:
print "Syntax all right"
Simple lines should cause an appropriate answer

Why does the python interpreter prompt with ... for a comment "#"?

In the Python interpreter, if I put in a # for a comment, why does it prompt with ...? I expected a >>> prompt.
e.g.,
>>> # my comment
... x = 4
>>> x
4
>>> # my comment
... foo
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: name 'foo' is not defined
Here's my educated guess about what is going on; I haven't actually looked at Python's REPL code. As you know, the Python interactive shell uses the ... prompt when it is expecting further input based on having parsed the contents of the preceding line(s).
For example:
>>> if True:
...
... because if ... :<newline> must be followed by an indented block according to the lexical structure of Python.
Notice that you can trigger the same slightly odd behavior with a line that is empty except for whitespace, e.g.:
>>> <space><enter>
...
According to the lexical rules of Python, in most contexts a line that contains only whitespace should not be treated as a pass statement, or an empty block, but it should be handled as if it didn't appear at all. Take this example (with | to emphasize the lack of whitespace at the end of each line):
if False:|
|
print "Foo"|
# comment|
print "Bar"|
|
print "Baz"|
If you run this code, it will print only Baz. The first two print statements are treated as part of the same block despite the fact that there are non-indented empty or comment-only lines before, after, and in the middle of them.
Basically, when the Python interpreter reads a line that is blank or contains only a comment, it pretends it didn't read any line at all. The interactive interpreter basically follows this behavior: it's waiting for input, and if it gets no input, it asks for more input. Hence the ... continued input prompt.
It appears that the case of a totally blank line (line=='' after chopping off the EOL character(s)) is special-cased into the interactive interpreter, but that this special-casing is not extended to lines which contain only comments and/or whitespace.
It is the prompt, just like when you type in def foo () : and press enter, it puts an ellipsis (...) and with some prompts automatically tabs for you. It's just it's way of saying that it is accepting that you are doing something over multiple lines.

while loop in python gives syntax error

I am very new to python, this is my first program that I am trying.
This function reads the password from the standard input.
def getPassword() :
passwordArray =[]
while 1:
char = sys.stdin.read(1)
if char == '\\n':
break
passwordArray.append(char)
return passwordArray
print (username)
print (URL)
getting this error:
Problem invoking WLST - Traceback (innermost last):
(no code object) at line 0
File "/scratch/aime/work/stmp/wlstCommand.py", line 10
while 1:
^
SyntaxError: invalid syntax
Your indentation is not correct. Your while should be indented the same as the line above it.
Python uses indentation to "separate" stuff and the thing with that is you need to have the same kind of indentation across the file. Having a fixed kind of indentation in the code you write is good practice. You might want to consider a tab or four spaces(The later being the suggestion in the PEP8 style guide)
Python is sensitive and depended on indentation. If it complains "invalid Format", that is better than "invalid syntax".

Python and Tkinter: Function madness

I'm trying to write myself a program that calculates a function taken from a Tk.Entry().
The problem is, when I try to run my display() function
(it runs Tkinter, sets up the window, and calls root.Mainloop()),
I get parse errors coming from eval() from a function that is supposed to be called only if the user inputs all of the variables and presses a button (the button's command).
The function uses eval(variable), while variable is entry.get().
What am I doing wrong here?
def cfunc(_n,_f,_t0,_tn,):
xbase=[]
tbase=[]
t=0
n2=eval(_n) #Stuff happens here, cfunc gets entry_n.get() as arguments.
f2=_f #Also, tabs are correct in the original.
tmin2=eval(_t0)
tmax2=eval(_tn)
tr=tmax2-tmin2
sk = tr / n2
i2=tmin2
Also, error:
File "Q:\Py\counter.py", line 89, in
cfunc
n2=eval(_n) File "", line 0
^ SyntaxError: unexpected EOF while parsing
You haven't shown us the code that causes the error (the value of _n) so we can only guess. A couple words of advice:
the error message is telling you the problem: unexpected eof. That means there's a missing closing quote or brace or something like that. The parser got to the end of the "file" (the string being eval'd) before it got the characters it expected.
put a print statement immediately before an eval, and use some special characters to delimit it (eg: puts ">>>$_n<<<") so you can tell precisely what is in the string being eval'd, including any leading or trailing spaces.

Categories