Symbolic errno values in error messages

Hi, I spent some time googleing for "OSError 4" before it occurred to me that "4" was actually an irrelevant implementation detail. As soon as I searched for "EINTR", I found exactly what I was looking for. (not really but this is another story) I jumped to the conclusion that OSError.__str__() should return the symbolic error number instead of the integer value. I was about to write a patch but I just noticed that OSError and friends are implemented in C so I guess it will be a bit harder than expected. The error message comes from EnvironmentError.__str__() which is implemented by EnvironmentError_str() in Objects/exceptions.c. A Python implementation could have replaced self.errno in the format string args by errno.errorcode[self.errno]. However, it's not clear to me if there is such a mapping available in C. Since my fix is not as trivial as I expected, I ask for advice regarding the following questions: 1) Should OSError.__str__() print the symbolic name of errno? 2) Where can I find the symbolic name in C? Best regards, -- Yannick Gingras

Yannick Gingras <ygingras <at> ygingras.net> writes: ..
1) Should OSError.__str__() print the symbolic name of errno?
+1 for the change
2) Where can I find the symbolic name in C?
Use standard C library char* strerror(int errnum) function. You can see an example usage in Modules/posixmodule.c (posix_strerror).

Alexander Belopolsky wrote:
Yannick Gingras <ygingras <at> ygingras.net> writes:
2) Where can I find the symbolic name in C?
Use standard C library char* strerror(int errnum) function. You can see an example usage in Modules/posixmodule.c (posix_strerror).
I don't believe that would provide adequate Windows support. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org

On Sat, 17 May 2008 00:15:23 +1000, Nick Coghlan <ncoghlan@gmail.com> wrote:
Alexander Belopolsky wrote:
Yannick Gingras <ygingras <at> ygingras.net> writes:
2) Where can I find the symbolic name in C?
Use standard C library char* strerror(int errnum) function. You can see an example usage in Modules/posixmodule.c (posix_strerror).
I don't believe that would provide adequate Windows support.
It's not C, but maybe it's interesting to look at anyway: http://twistedmatrix.com/trac/browser/trunk/twisted/python/win32.py?rev=2168... However, neither strerror nor the linked code gives out symbolic names for errnos. They both produce messages like "Interrupted system call", whereas the symbolic name would be "EINTR". Modules/errnomodule.c might be worth looking at, although its solution is somewhat disappointing. Jean-Paul

On Fri, May 16, 2008 at 10:15 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
Alexander Belopolsky wrote: ..
Use standard C library char* strerror(int errnum) function. You can see an example usage in Modules/posixmodule.c (posix_strerror).
I don't believe that would provide adequate Windows support.
Until recently, python had its own cross-platform implementation of strerror, but it was removed because it was deemed redundant. This tells me that it should work on windows. On the other hand, IOError object and in fact EnvironmentError object already has strerror member which is printed when available:
try: ... open('/') ... except Exception,e: ... pass ... print e [Errno 21] Is a directory
So now I am not sure what OP is proposing. Do you want to replace 21 with EISDIR in the above?

"Alexander Belopolsky" <alexander.belopolsky@gmail.com> writes:
try: ... open('/') ... except Exception,e: ... pass ... print e [Errno 21] Is a directory
So now I am not sure what OP is proposing. Do you want to replace 21 with EISDIR in the above?
Yes, that's what I had in mind. -- Yannick Gingras

On Fri, May 16, 2008 at 10:52 AM, Yannick Gingras <ygingras@ygingras.net> wrote:
print e [Errno 21] Is a directory
So now I am not sure what OP is proposing. Do you want to replace 21 with EISDIR in the above?
Yes, that's what I had in mind.
In this case, I have a more drastic proposal. Lets change EnvironmentError errno attribute (myerrno in C) to string. 'EXYZ' strings can be interned, which will make them more efficient than integers for lookups and comparisons (to literals). A half-way and backward compatible solution would be to stick 'EXYZ' code at the end of the args tuple and add an errnosym attribute.

On 2008-05-16 17:02, Alexander Belopolsky wrote:
On Fri, May 16, 2008 at 10:52 AM, Yannick Gingras <ygingras@ygingras.net> wrote:
print e [Errno 21] Is a directory
So now I am not sure what OP is proposing. Do you want to replace 21 with EISDIR in the above? Yes, that's what I had in mind.
In this case, I have a more drastic proposal. Lets change EnvironmentError errno attribute (myerrno in C) to string.
-1 You never want to change an integer field to a string.
'EXYZ' strings can be interned, which will make them more efficient than integers for lookups and comparisons (to literals). A half-way and backward compatible solution would be to stick 'EXYZ' code at the end of the args tuple and add an errnosym attribute.
Actually, you don't have to put it into any tuple. Just add it to the error object as attribute. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, May 16 2008)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611

On Fri, May 16, 2008 at 10:52 AM, Yannick Gingras <ygingras@ygingras.net> wrote:
"Alexander Belopolsky" <alexander.belopolsky@gmail.com> writes:
try: ... open('/') ... except Exception,e: ... pass ... print e [Errno 21] Is a directory
So now I am not sure what OP is proposing. Do you want to replace 21 with EISDIR in the above?
Yes, that's what I had in mind.
Then, check out EnvironmentError_str in Objects/exceptions.c. You should be able import the errno module and fetch its errorcode dictionary. -- Alexandre

"Alexandre Vassalotti" <alexandre@peadrop.com> writes:
So now I am not sure what OP is proposing. Do you want to replace 21 with EISDIR in the above?
Yes, that's what I had in mind.
Then, check out EnvironmentError_str in Objects/exceptions.c. You should be able import the errno module and fetch its errorcode dictionary.
It wasn't as hard as I expected. It's the first time that I play with the Python C API; I didn't expect the API to be that high level. I attached a patch to convert errno to its symbolic value when an EnvironmentError is printed. Should attach it to a ticket on bugs.python.org? I'm sure there is a style guide like PEP-8 for C code, feel free to point me to it because my patch is probably not fully style compliant. With Emacs, doing M-x c-set-style python doesn't seems to do the right thing. Are you all using a bunch of shared settings in you .emacs files? -- Yannick Gingras

Yannick Gingras schrieb:
"Alexandre Vassalotti" <alexandre@peadrop.com> writes:
So now I am not sure what OP is proposing. Do you want to replace 21 with EISDIR in the above?
Yes, that's what I had in mind.
Then, check out EnvironmentError_str in Objects/exceptions.c. You should be able import the errno module and fetch its errorcode dictionary.
It wasn't as hard as I expected. It's the first time that I play with the Python C API; I didn't expect the API to be that high level.
I attached a patch to convert errno to its symbolic value when an EnvironmentError is printed. Should attach it to a ticket on bugs.python.org?
I'm sure there is a style guide like PEP-8 for C code, feel free to point me to it because my patch is probably not fully style compliant.
With Emacs, doing
M-x c-set-style python
doesn't seems to do the right thing. Are you all using a bunch of shared settings in you .emacs files?
For new-style Python C files, this style definition works well: (c-add-style "python-new" '((indent-tabs-mode . nil) (fill-column . 78) (c-basic-offset . 4) (c-offsets-alist . ((substatement-open . 0) (inextern-lang . 0) (arglist-intro . +) (knr-argdecl-intro . +))) (c-hanging-braces-alist . ((brace-list-open) (brace-list-intro) (brace-list-close) (brace-entry-open) (substatement-open after) (block-close . c-snug-do-while))) (c-block-comment-prefix . "* ")) ) This is a very crude hook that auto-selects the C style depending on whether it finds a line starting with tab in the first 3000 characters in the file: (defun c-select-style () (save-excursion (if (re-search-forward "^\t" 3000 t) (c-set-style "python") (c-set-style "python-new")))) (add-hook 'c-mode-hook 'c-select-style) HTH, Georg

Until recently, python had its own cross-platform implementation of strerror, but it was removed because it was deemed redundant. This tells me that it should work on windows.
That conclusion is incorrect. It works on MSVCRT, but for this specific aspect, using MSVCRT is a bad idea (because it artificially renumbers system errors, just to provide an illusion for what Microsoft considers POSIX). Regards, Martin

On 2008-05-16 16:15, Nick Coghlan wrote:
Alexander Belopolsky wrote:
Yannick Gingras <ygingras <at> ygingras.net> writes:
2) Where can I find the symbolic name in C?
Use standard C library char* strerror(int errnum) function. You can see an example usage in Modules/posixmodule.c (posix_strerror).
I don't believe that would provide adequate Windows support.
Well, there's still the idea of a winerror module: http://bugs.python.org/issue1505257 Perhaps someone can pick it up and turn it into a (generated) C module ?! -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, May 16 2008)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611

Yannick Gingras wrote:
1) Should OSError.__str__() print the symbolic name of errno?
+1 (assuming the performance hit for doing so is incurred only when the exception is actually printed)
2) Where can I find the symbolic name in C?
Modules/errnomodule.c Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
participants (8)
-
"Martin v. Löwis"
-
Alexander Belopolsky
-
Alexandre Vassalotti
-
Georg Brandl
-
Jean-Paul Calderone
-
M.-A. Lemburg
-
Nick Coghlan
-
Yannick Gingras