This question already has answers here:
SyntaxError inconsistency in Python?
(2 answers)
Closed 5 years ago.
try:
x===x
except SyntaxError:
print "You cannot do that"
outputs
x===x
^
SyntaxError: invalid syntax
this does not catch it either
try:
x===x
except:
print "You cannot do that"
Other errors like NameError, ValueError, are catchable.
Thoughts?
System specs:
import sys
print(sys.version)
->
2.7.5 (default, Mar 9 2014, 22:15:05)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)]
You can only catch SyntaxError if it's thrown out of an eval, exec, or import operation.
>>> try:
... eval('x === x')
... except SyntaxError:
... print "You cannot do that"
...
You cannot do that
This is because, normally, the interpreter parses the entire file before executing any of it, so it detects the syntax error before the try statement is executed. If you use eval or its friends to cause more code to be parsed during the execution of the program, though, then you can catch it.
I'm pretty sure this is in the official manual somewhere, but I can't find it right now.
SyntaxErrors get raised when the file/code is parsed, not when that line of code is executed. The reason for this is simple -- If the syntax is wrong at a single point in the code, the parser can't continue so all code after that line is un-parseable.
In other words, you can only catch syntax errors when python is trying to parse something. This includes exec, eval, import:
>>> try:
... import junk
... except SyntaxError:
... print "Woo"
...
Woo
and various things regarding ast and the like.
Note that the python tutorial even distinguishes between SyntaxError and other exceptions although the distinction isn't as clear as the tutorial makes it seem (since you can in fact catch SyntaxError if you know when they get raised).
Related
The following is the code to evaluate Excel formulae using Ruby. Only SUM function is shown here. I implemented this function in two languages Ruby and Python
Python 3.10.0
def SUM(a,b):
return a+b
for i in range(int(input())):
s=input()
if s[0]!="=":
print("INVALID")
else:
try:
print(eval(s.replace('=','')))
except:
print("INVALID")
Ruby 3.0.2
def SUM a,b
a+b
end
gets
puts $<.map{
if !_1[/^=/]
:INVALID
else
eval(_1.tr(?=,'')) rescue :INVALID
end
}
Consider the following inputs
Input 1
4
=SUM(8, 99)
=SUM(343, -b1)
=SUM(-8, -99)
=SUM(101 , -25) + 6
Input 2
3
SUM(4, 1)
=SUM(5, 1
=SuM(2, 1)
For Input 1 both Ruby and Python codes work perfectly. They both catch the error b1 not defined and hence go to except or rescue
But for input 2, only Python code works perfectly while Ruby fails to catch the error ) missing (in 3rd line). It doesn't go to rescue. I tried using begin and resuce too. But nothing. How to rescue these kind of errors in Ruby?
in ruby rescue by default only rescues subclasses of StandardError. This works for most cases, because most stuff that you would want to rescue is a descendant of that class (NoMethodError, RuntimeError, ArgumentError and so on), and most stuff that you don't want to rescue (NoMemoryError, SyntaxError, SystemExit and so on) are not.
In your case, eval("SUM(5, 1") is missing a parentheses. It's a syntax error and ruby raises SyntaxError. Your rescue is looking for StandardError, which SyntaxError is not.
You could rescue all standard errors + syntax error or rescue all Exceptions, but do note that if you do rescue all Exceptions, then your program might be difficult to exit.
ctrl+c is Interrupt, which is a subclass of Exception and can be rescued.
kill on the process is a SignalException, which is a subclass of Exception and can be rescued.
begin
eval(_1.tr(?=,''))
rescue StandardError, SyntaxError
:INVALID
end
or
begin
eval(_1.tr(?=,''))
rescue Exception # I strongly advise against this
:INVALID
end
I have this little piece of code I wrote that isn't excepting the errors that could be thrown at it. Here's the code:
def println(stringint):
try:
print stringint
except (SyntaxError, NameError):
print "Invalid format."
I run the code from the python interpreter like this, and only like this:
>>> import pcl
>>> pcl.println("Hello")
Why aren't the errors being excepted? How can I catch the errors?
Those errors that has to do with syntax are parse level errors, which means, that are errors that take place before that particular code being interpreted.
The following arenĀ“t the same type of errors:
print("Hello) # Note the missing '"'
that
print(4/0) # Syntactically correct, but obviously an error.
Hence, syntax error can't be handled by the try -- except block.
See this answer for more detail: SyntaxError inconsistency in Python?
Your code works fine, "Hello" should raise neither an EOLError nor a NameError, because the quotes are closed, and it is a string.
This question already has answers here:
Can Syntax Errors be handled?
(2 answers)
Syntax error on print with Python 3 [duplicate]
(3 answers)
Closed 9 years ago.
I'm trying to write a block of code at the top of my programs that, if the program is accidentally run in Python 2.x, it will give an error message and quit, but if run in Python 3.x will run normally:
try:
print "Error: This program should only be run in Python 3."
raw_input('>')
exit()
except SyntaxError:
pass
print("I see you're running Python 3.")
# rest of program
This works correctly in Python 2.7 (i.e., it displays the error and quits), but when I run it in Python 3.3, I get a SyntaxError, even though I told it to have an exception.
File "version.py", line 2
print "This program should only be run in Python 3"
^
SyntaxError: invalid syntax
What am I missing?
SyntaxErrors are thrown at compile-time. You cannot catch them like runtime exceptions.
If you want to check python version, look at sys.version_info.
i.e.
import sys
if sys.version_info.major < 3:
sys.exit('This program should only be run in Python 3')
Here's a small example on how to do what you want:
import sys
if sys.version_info.major == 2:
print("Error: This program should only be run in Python 3.")
raw_input('>')
exit(0)
This code will run in python2 and python3. You don't need to use a try catch in that case. Since in python2, it happens that the ( and ) will have no effect since they aren't tuples. You can write that kind of thing and it will work in python2 and python3 without SyntaxError.
Consider the following code:
try:
if True a = 1 #It's missing a colon So it's a SyntaxError!!!!!!!
except SyntaxError:
print 'hey'
You'd expect it to print hey However It raises a SyntaxError, The same error I'm trying to avoid. So Can all Exceptions be handled using a try-except block? Well If SyntaxError's were an exception why is it included in the built-in exceptions? and finally how can I fix the above piece of code so that it handles the exception properly?
Note: I know what I'm trying to do Is utterly pointless and serves no real purpose
SyntaxError is a perfectly ordinary built-in exception. It is not special in any way. Only the circumstances of when it's (usually) thrown are a bit unusual.
A syntax error means that the code featuring said error cannot be parsed. It doesn't even begin to be a valid program, hence it cannot be executed. Therefore SyntaxError exceptions are raised before the program is run, and hence can't be caught from within the program.
More specifically, this exception is raised by the parser. Because the parser runs fully before the code is executed, rather then interleaved with it, a program can't catch its own syntax errors.
The parser itself is just another program though: Code invoking the parser can catch SyntaxErrors like every other exception (because it is like every other exception). Examples of "invoking the parser" include:
compile, exec, eval
import statements
Several functions in modules like ast, tokenizer, parser, etc.
Of course you need SyntaxError as a built-in exception - what else should be raised if the compiler/parser encounters a syntax error?
You're right that this error usually happens at compile time, which is before you're able to catch it (runtime). (And how would you recover from it?)
I can think of one exception, though:
>>> try:
... eval("hello =")
... except SyntaxError:
... print("Hey! Who's using eval() anyway??")
...
Hey! Who's using eval() anyway??
What is the difference between ',' and 'as' in except statements, eg:
try:
pass
except Exception, exception:
pass
and:
try:
pass
except Exception as exception:
pass
Is the second syntax legal in 2.6? It works in CPython 2.6 on Windows but the 2.5 interpreter in cygwin complains that it is invalid.
If they are both valid in 2.6 which should I use?
The definitive document is PEP-3110: Catching Exceptions
Summary:
In Python 3.x, using as is required to assign an exception to a variable.
In Python 2.6+, use the as syntax, since it is far less ambiguous and forward compatible with Python 3.x.
In Python 2.5 and earlier, use the comma version, since as isn't supported.
Yes it's legal. I'm running Python 2.6
try:
[] + 3
except Exception as x:
print "woo hoo"
>>>
woo hoo
Update: There is another reason to use the as syntax. Using , makes things a lot more ambiguous, as others have pointed out; and here's what makes the difference. As of Python 2.6, there is multicatch which allows you to catch multiple exceptions in one except block. In such a situation, it's more expressive and pythonic to say
except (exception1, exception2) as e
rather than to say
except (exception1, exception2), e
which would still work
the "as" syntax is the preferred one going forward, however if your code needs to work with older Python versions (2.6 is the first to support the new one) then you'll need to use the comma syntax.
If you want to support all python versions you can use the sys.exc_info() function like this:
try:
a = 1/'0'
except (ZeroDivisionError, TypeError):
e = sys.exc_info()[1]
print(e.args[0])
(source:http://python3porting.com/noconv.html)
As of Python 3.7 (not sure about other versions) the 'comma' syntax is not supported any more:
Source file exception_comma.py:
try:
result = 1/0
except Exception, e:
print("An error occurred")
exit(1)
exit(0)
$ python --version --> Python 2.7.10
$ python exception_comma.py
An error occurred
$ python3 --version --> Python 3.7.2
$ python3 exception_comma.py
File "exception_comma.py", line 3
except Exception, e:
^
SyntaxError: invalid syntax