Catch exceptions due to parentheses/brackets/braces mismatch in Ruby - python

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

Related

How to catch a SyntaxError when f-strings are implemented - when obsolete python is used

I am working on issue that I was thinking is a minor thing but I cannot get it to work.
As in the title - I wrote a program that requires usage of python3.6+ due to f-strings presence. My intention is to catch the SyntaxError when user for example have python3.5 on his OS.
My initial idea:
def main():
var = "more"
print(f'I like f-strings a lot and {var}')
if __name__ == "__main__":
if (sys.version_info.major == 3) and (sys.version_info.minor < 6):
print("This program requires python3.6 or newer")
print(old_python_error_message)
else:
print("Program starts...")
main()
The problem is that I still got that error before script even starts.
Reason - as far as I researched - is:
You can only catch SyntaxError if it's thrown out of an eval, exec, or import operation.
Link: Failed to catch syntax error python
I still have no idea how can I do that in f-strins usage case.
Thanks for your time
It looks like all you want to do on pre-3.6 versions is report an error and terminate the program, and you just want a more user-friendly error message than a SyntaxError stack trace. In that case, instead of trying to catch a SyntaxError, have an entry point file that doesn't use f-strings, and do the version check there, before loading any code that uses f-strings:
# entry point
import sys
if sys.version_info < (3, 6):
# report error, terminate program
else:
import whatever
whatever.main()

Is there a simple way to comment out or diable a python try statement without re-indenting

Problem:
Sometimes it is nice to be able to remove or apply a try statement temporarily. Is there a convenient way to disable the try statement without re-indenting?
For example, if there was a python block statement equivalent called "goForIt:" one could edit the word "try:" to "goForIt:" and it would just execute the block as though it were not wrapped in a "try" and ignore the "except" line too.
The problem I'm trying to solve is that while I want the try statement in production I want to be able to remove it temporarily while debugging to see the error traceback rather than have it trap and process the exception.
Currently I work around this by commenting out the "try" then re-indent the code in the block. Then comment out the entire "except" block. This seems clumsy.
Instead of removing the try, you could make the except re-raise the exception:
try:
raise ValueError('whoops')
except ValueError as e:
raise # <-- just put this here
print('caught')
This will raise the error, just as if it were not caught:
ValueError Traceback (most recent call last)
<ipython-input-146-a6be6779c161> in <module>
1 try:
----> 2 raise ValueError('whoops')
3 except ValueError as e:
4 raise
5 print('caught')
ValueError: whoops
I do not believe there is a way to fix this.
Is it adequate to catch the exception, print it out and, if wanted, end the program?
try:
# code
except Exception as e:
print(e)
# end program if wanted
If you want a none code solution you need to use an IDE or a good text editor.
I am using Visual Studio code where I can indent with a keyboard shortcut (Ctrl + ` in my case)
(This is not my answer, but the answer from Alani's comment. If credits, find the original comment under the question.)
The solution is good because it allows global replacement:
try: --> if 1: # try:
except --> if 0: # except
The 2nd one is a little unsure. Exact and full word match should be used, or replace twice (for except<space> and except:). Or you can fix error fast by hand if there is any.
The replacement back is sure.
I need now such solution to debug error in strawberry which is only printed. So I think I need deactivate all try/except structures in 3 libraries (strawberry + 2 libs for django).

Without version checking or `six`, how can I use `except MyError, e:` vs `except MyError as e` to work with Python 2&3?

I'm looking for a way to do this without checking for the Python version used.
Please refer to How to write exception reraising code that's compatible with both Python 2 and Python 3? for details about this, since this question extends that one.
Basically, I can generalize this as, "What if the method-based exception raises a language-based exception?"
According to Python try...except comma vs 'as' in except, the following show the right syntax for Python 3 and Python 2:
Python 3:
except MyError as e
Python 2, for versions 2.6+:
except MyError as e
#OR#
except MyError, e
Python 2.5-:
except MyError, e
A little background:
I have a sticky situation in which a script will need to be run on many an ancient Linux machine, in which a variety of different Python versions, including Python 2.5, will be used.
Unfortunately, I have to distribute this as a single, size limited file, which puts some constraints on how much importing I can do.
Also, I'm interested in the case in which one of these may misreport its version, or in code that can be used without necessarily checking for a version. This could be worked around, though, of course.
Your only option is to avoid the exception assignment and pull it out of the result for the sys.exc_info() function instead:
try:
# ...
except Exception: # note, no ", e" or "as e"
import sys
e = sys.exc_info()[1]
This'll work on Python 1.5 and up.
However, you'll likely to encounter other incompatibilities and difficulties; writing polyglot Python code (code that works on both Python 2.x and 3.x) is only really workable on Python 2.6 and up.

Can Syntax Errors be handled?

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??

How to catch IndentationError [duplicate]

This question already has answers here:
SyntaxError inconsistency in Python?
(2 answers)
Closed 5 years ago.
First of all - I don't have a problem with bad-indentated code and I have an idea of how does this exception works like.
I ask, if there is any way to catch IndentationError in code with a try/except block? For example, let's say I'm writing a test for a function written by someone else. I want to run it in try/except block and handle all warning he/she could make. I know, that it's not a best example, but the first one coming to my mind. Please, don't focus on an example, but rather on problem.
Let's look at the code:
try:
f()
except IndentationError:
print "Error"
print "Finished"
The function:
def f():
print "External function"
And the result is:
External function
Finished
And that's something, I'm ready to understand, becouse indentation in external function was consistant.
But when the function look like that:
def f():
print "External function"
print "with bad indentation"
The exception is unhandled:
print "with bad indentation"
^
IndentationError: unexpected indent
Is there any way to achieve it? I guess that's the matter of compiling, and as far I don't see any possibility to catch. Does the except IndentationError make any sense?
Yes, this can be done. However, the function under test would have to live in a different module:
# test1.py
try:
import test2
except IndentationError as ex:
print ex
# test2.py
def f():
pass
pass # error
When run, this correctly catches the exception. It is worth nothing that the checking is done on the entire module at once; I am not sure if there's a way to make it more fine-grained.
IndentationError is raised when the module is compiled. You can catch it when importing a module, since the module will be compiled on first import. You can't catch it in the same module that contains the try/except, because with the IndentationError, Python won't be able to finish compiling the module, and no code in the module will be run.
You could use a tool such as pylint, which will analyse your module and report bad indentation, as well as many other errors.

Categories

Resources