polib
polib copied to clipboard
[QUESTION] Why syntax errors are raised as IOError and not SyntaxError?
Originally reported by: Luis Alejandro Martínez Faneyth (Bitbucket: LuisAlejandro, GitHub: LuisAlejandro)
I've noticed that syntax errors are being raised as IOError, and i would like if there's a special reason for this.
This affects me because I can't access the line number of the syntax error because IOError does not have that attribute.
Specifically, here:
https://bitbucket.org/izi/polib/src/ac206f2b25956f95155fb1dcbc881068e3a15bfe/polib.py?at=default&fileviewer=file-view-default#polib.py-1382
I can't access current_line either in a try-except. And parsing the exception message with regex is not the best solution for me.
Thanks for your time.
- Bitbucket: https://bitbucket.org/izi/polib/issue/74
Original comment by David Jean Louis (Bitbucket: izi, GitHub: izimobil):
@LuisAlejandro I know it's been a long time, but do you still plan to send a pull request for this ? Thanks.
Original comment by Luis Alejandro Martínez Faneyth (Bitbucket: LuisAlejandro, GitHub: LuisAlejandro):
Excellent, i'll be reporting as soon as i can.
Original comment by David Jean Louis (Bitbucket: izi, GitHub: izimobil):
Yeah, we could subclass IOError in a POFileError class and add the relevant attributes (I strongly prefer this over monkeypatching IOError). If you're willing to help, please go ahead and submit a pull request with preferably tests where possible. Thanks in advance.
Original comment by Luis Alejandro Martínez Faneyth (Bitbucket: LuisAlejandro, GitHub: LuisAlejandro):
Perhaps you could add the attributes to the IOError instance like:
IOError.filename = self.instance.fpath
IOError.linenum = self.current_line
I dont know if "filename" and "linenum" are the names of the actual attributes of SyntaxError, you'll have to look out.
Or, perhaps you could make a custom exception for your library which subclasses IOError (POException?) and that way you can add these attributes and not brake others codebases. Subclassing IOError will trigger their exceptions the same way.
I'm willing to help if you decide to go for it.
Thanks.
Original comment by David Jean Louis (Bitbucket: izi, GitHub: izimobil):
There's no particular reason... it's just a bad exception choice that I made very long ago (10 years !).
The problem is that a lot of codebase and scripts are relying on this initial bad choice, fixing this behavior will break backwards compatibility, so unfortunately I can't change this :(
Original comment by David Jean Louis (Bitbucket: izi, GitHub: izimobil):
Yeah, we could subclass IOError in a POFileError class and add the relevant attributes (I strongly prefer this over monkeypatching IOError). If you're willing to help, please go ahead and submit a pull request with preferably tests where possible. Thanks in advance.
A simpler and perhaps better solution is for POFileError
to simply subclass from both IOError
and SyntaxError
. it would automatically have all the needed attributes from SyntaxError and still trigger any legacy code that expects an IOError:
class POFileSyntaxError(IOError, SyntaxError): pass
There, the new class is ready to be used throughout the code, with all the attributes from both its superclasses. Python's multiple inheritance is amazing!
@MestreLion : no, you can't do that, it would result in conflicts:
Python 3.9.1 (default, Dec 8 2020, 03:26:34)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo(SyntaxError, IOError):
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: multiple bases have instance lay-out conflict
Oh, bummer. I have used this strategy before, IIRC mixing KeyError
and IndexError
(it works) . I guess SyntaxError
cannot be mixed with others (IOError
plays nicely with other errors)