
As part of the registry work, Im toying with the idea of a standard "win32 exception" error in the Python core. The reasons why I think a standard exception would be useful are: * Single body of code that knows how to raise these exceptions. Eg, whenever an extension module needs to report that a Win32 API function failed, they can use the core routines to create the exception object - just like they can with OSError. This ensures consistency, and saves each extension module author from reinventing the wheel. * No confusion about what exception Python programmers should catch. In the same way that "OSError" will be thrown any time the C runtime library fails, the "Win32Error" exception will be thrown whenever a Win32 API function (called directly) fails. This has come up now that I am looking at a "win32reg" (or "_win32reg") module for inclusion in Python 1.6. It makes sense to me that rather than creating specific exceptions for each new module of this ilk, we define a single exception able to be shared by any core or 3rd party module that needs it. Ideally, this exception should derive from "EnvironmentError" - however, this is pretty specific to the OSError mechanics. The other alternatives are to create a Win32Error that derives directly from "StandardError", or to introduce an intermediate "PlatformError". The Win32 extensions have been doing this for ages (ie, every win32*.pyd module shares and raises the same exception object) and IMO it is a good thing. If we do go this route, the Win32 exceptions could also share this exception object, which is, IMO, also a good thing (in the same way that extension modules now can already raise OSError without a need to redefine the semantics each time) Does anyone have thoughts on this? Is it a good thing or a bad thing? Have-I-made-the-comparison-to-OSError-enough?-ly, Mark.

[Mark Hammond]
As part of the registry work, Im toying with the idea of a standard "win32 exception" error in the Python core.
Sounds good to me, but if & only if it's a subclass of OSError (why? because nothing else makes sense <wink>). I added UnboundLocalError as a subclass of NameError (in the CVS tree), so you can mimic what that did. IIRC, for the benefit of the old "string-based exceptions" option hack, UnboundLocalError reverts to NameError if class-based exceptions are disabled ...

"TP" == Tim Peters <tim_one@email.msn.com> writes:
TP> Sounds good to me, but if & only if it's a subclass of OSError I agree (and I think Mark's been given some ideas about how to accomplish this). TP> (why? because nothing else makes sense <wink>). I added TP> UnboundLocalError as a subclass of NameError (in the CVS TP> tree), so you can mimic what that did. IIRC, for the benefit TP> of the old "string-based exceptions" option hack, TP> UnboundLocalError reverts to NameError if class-based TP> exceptions are disabled ... I wouldn't worry about string-based standard exceptions. Didn't we decide to get rid of these (and -X) for 1.6 at IPC8? -Barry

On Mon, 7 Feb 2000, Barry A. Warsaw wrote:
I wouldn't worry about string-based standard exceptions. Didn't we decide to get rid of these (and -X) for 1.6 at IPC8?
In that case, installations should freeze exceptions.py into the binary, otherwise all hell *will* break loose... -- Moshe Zadka <mzadka@geocities.com>. INTERNET: Learn what you know. Share what you don't.

Moshe Zadka wrote:
I think we got agreement on that too (in some import related thread on this list). Hmmm, well I can't find exceptions.py mentioned specifically. But I do find the BDFL advocating writing as much as possible of the start-up code in Python (eg, the equivalent of getpath.c) and freezing it in. In his absence, it makes sense for us to include exceptions.py in that statement <wink>. - Gordon

On Mon, 7 Feb 2000, Gordon McMillan wrote:
Of course then you have a bootstapping issue (how to write the first interpreter. Probably, need some C code to get it started: but that C code would only be used in compiling the interpreter, not in the interpreter that gets installed...) -- Moshe Zadka <mzadka@geocities.com>. INTERNET: Learn what you know. Share what you don't.

Tim Peters writes:
Which reminds us once again of the old -X problem. Will this still be present in 1.6? I'd vote to remove it if this weren't a dictatorship. I don't see that it serves any useful purpose at this point. -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> Corporation for National Research Initiatives

On Mon, 7 Feb 2000, Fred L. Drake, Jr. wrote:
Don't think of it as "-X", think of it as "could not find exceptions.py, reverting to string exceptions" (or whatever the error message is). Be sure it won't change to "could not find exceptions.py, I don't think I feel like running" -- Moshe Zadka <mzadka@geocities.com>. INTERNET: Learn what you know. Share what you don't.

"MZ" == Moshe Zadka <moshez@math.huji.ac.il> writes:
MZ> Don't think of it as "-X", think of it as "could not find MZ> exceptions.py, reverting to string exceptions" (or whatever MZ> the error message is). Be sure it won't change to "could not MZ> find exceptions.py, I don't think I feel like running" Absolutely. If string-based standard exceptions are removed for 1.6, we need a fool-proof way of getting exceptions.py. Remember, my first attempt at this stuff made that Python code a BACS[*] that got exec'd. I'm sure there are better ways of doing that now, and I think exceptions.py has settled down enough to warrant cooling it for 1.6. -Barry [*] Big Ass C String

On Mon, 7 Feb 2000, Barry A. Warsaw wrote:
To possibly improve startup time and heap-memory usage, I added a feature into 1.5.2 that applies to freezing code. Specifically, a code object no longer requires a PyStringObject for the bytecodes. Any object exporting the buffer interface will work. This means that you don't have to copy the bytecodes onto the heap before using them. However, before this part can work properly, some special un-marshalling would need to happen. Currently, frozen code is a marshalled code object. When that is unmarshalled, the bytes will be copied. Instead, it would be nice to call PyCode_New() manually with all the various parameters and a "code" argument that is a PyBufferObject that points to the BACS. The alternative is to beef up the PyMarshal stuff so that it knows it can create buffers that point into a passed-in PyStringObject. Just some rambling thoughts... Cheers, -g -- Greg Stein, http://www.lyra.org/

On Tue, 8 Feb 2000, Fredrik Lundh wrote:
Why C? Implement it in Python and freeze the sucker. We all know that Python is much more maintainable. With a few simple changes, we can also make this freeze process very straight-forward and part of the standard build process. There are quite a few things that could be done in Python, then just frozen into the binary. Just wait until I start arguing for the parser and compiler to be written in Python, frozen in, and we dump their C equivalents... :-) Cheers, -g -- Greg Stein, http://www.lyra.org/

Why C? Implement it in Python and freeze the sucker.
size and performance. exception classes are installed during initialization of the python interpreter, and they all need to be made available for C code anyway. (in fact, the new code isn't that much larger than the code needed to copy stuff from exceptions.py) </F>

Actually, in this case, I'd vote for C too. My reason is stability. The process to freeze exceptions.py into the core will always be more fragile than the process to compile C code. --Guido van Rossum (home page: http://www.python.org/~guido/)

On Wed, 16 Feb 2000, Guido van Rossum wrote:
Heretic! :-) All right... I guess that I'm just gonna have to see if I can disprove your assertion :-) Cheers, -g -- Greg Stein, http://www.lyra.org/

Guido van Rossum wrote:
incomplete proof-of-concept implementation available here. see webpage and FIXME's in the code for more info: http://w1.132.telia.com/~u13208596/exceptions.htm </F>

I haven't looked at /F's code yet, but I've been thinking about doing something very similar for JPython. I think it'll be easier to freeze it in Java than in C. -Barry

Fredrik writes:
any reason you can't just throw OSError exceptions?
Mainly cos the error numbers are different - (eg, compare "errno.h" with "winerror.h" OSError really should be named CRTError. I dont think it makes much sense to have 2 different error numbering schemes use the same exception... I guess we _could_ tho - I still lean towards a new one, but other opinions would be good... Mark.

On Mon, 7 Feb 2000, Mark Hammond wrote:
Um...my Windows programing experience is thankfully little, but I seem to remember every "big collection" of function works with a different error handler (the sockets with WSA...error...() is the example which comes to mind). The OSError is very UNIX-oriented, in that it assumes a monolithic OS with consistent errors. This problem will probably also come up when (in a century or so) I manage to get Python working on Hurd. How about, for windows, to derive "many" error classes from OSError on Win32, and always return the right one? On the other hand, Mark will correct me if I'm talking nonsense Windows-wise <wink> -- Moshe Zadka <mzadka@geocities.com>. INTERNET: Learn what you know. Share what you don't.

[Moshe writes:]
How about, for windows, to derive "many" error classes from OSError on Win32, and always return the right one?
Another alternative would be to derive from EnvironmentError. I would then like to change the __str__ method from: ... return '[Errno %s] %s: %s' % (self.errno, self.strerror, ... to return '[%s %s] %s: %s' % (self.getdesc(), self.errno, self.strerror, Where getdesc() returns "OS Error", "IO Error" or "Win32 error" respectively. This all comes down to Guido tho. I believe he is away, so if he doesnt respond Ill simply send him a summary of the discussions and he can decide lickety-split! Mark.

[/F]
any reason you can't just throw OSError exceptions?
[Mark]
Mainly cos the error numbers are different - (eg, compare "errno.h" with "winerror.h" OSError really should be named CRTError.
There's nothing to stop a new CRTError class being derived from OSError, leaving OSError platform-neutral. This would just be vanilla OO refactoring in the face of new requirements, and existing code wouldn't know the difference. You should subclass from OSError so that code that cares about portability can catch OSError specifically instead of needing to be modified every time someone with a new OS wants to add a class of error specific to that OS.
I dont think it makes much sense to have 2 different error numbering schemes use the same exception...
No, I agree that does not. But it makes perfect sense for a subclass to override its parent's numbering scheme (and even more sense to make "numbering scheme" an abstract property of the parent to be implemented by its subclasses).

Im looking for closure on the Win32 specific exception. Summary for those that missed the thread: * I would like a standard exception for Win32 specific errors. The new hopefully-to-be-standard "win32reg" module could make use of it, the win32 extensions could switch to it. It is, in my mind at least, analogous to OSError. * I proposed deriving the new exception from EnvironmentError, like OSError is. * Fredrik replied with "why not use OSError then?". I answered "due to the numbering systems being different" * Tim agreed that they should be different exceptions if they use different numbering, but pointed out it could still be OSError with creative exception hierarchies. So, in summary, no one disagreed, and the only open issue was the exception hierarchy. My initial proposal called for: StandardError: -> EnvironmentError: -> IOError -> OSError -> Win32Error Which would generally lead to people writing "except Win32Error:" Tim's suggestion (as I understand it) was: StandardError: -> EnvironmentError: -> IOError -> OSError -> CRTError (new - is what os.error would use) -> Win32Error (new) which would lead to people writing "except IOError:" I still like my idea better - fits better with the existing "IOError", and doesnt cause confusion with the change from os.error being OSError to os.error being CRTError. Guido: Can you first make a "yes/no" decision, then (if necessary <wink>) an either/or one? Thanks, Mark.

Im looking for closure on the Win32 specific exception. Summary for those that missed the thread:
My apologies. I *did* miss the thread. I think this is a reasonable request.
I see no merit in adding CRTError -- that's an abstraction that's only relevant to C developers on Windows. I do like it better if Win32Error derives from OSError. Shouldn't it be just WinError or WindowsError? I don't see why a different exception should be used for Win64.
which would lead to people writing "except IOError:"
I don't understand this -- Win32Error isn't derived from IOError.
OK, this is a definite Yes. The either/or I'm still open on. --Guido van Rossum (home page: http://www.python.org/~guido/)

[Guido]
Oops - I meant OSError. What I meant is that people will say: try: win32reg.Something() except IOError, ... Rather than the specific error. This makes our specific Windows exception, basically, an internal mechanism to get the error messages lined up with the error number. Not that this is a problem, but I just thought it worth mentioning. OK - so lets go with: WindowsError(OSError): ... If no one complains, I will submit the relevant patches to Exception.py along with my win32reg.c (I can leave string-based exceptions out, yes?) Mark.

[Mark Hammond]
Yes! Note that you're the joker who brought up CRTError: I only mentioned the *possibility* of refactoring to OSError CRTError WindowsError to shut you up <wink>.
Is the -X switch going away? If so, sure. If not, you probably can't. I'd be delighted if -X went away (the purpose it served has expired).

Yes, -X is going away. --Guido van Rossum (home page: http://www.python.org/~guido/)

[Mark Hammond]
As part of the registry work, Im toying with the idea of a standard "win32 exception" error in the Python core.
Sounds good to me, but if & only if it's a subclass of OSError (why? because nothing else makes sense <wink>). I added UnboundLocalError as a subclass of NameError (in the CVS tree), so you can mimic what that did. IIRC, for the benefit of the old "string-based exceptions" option hack, UnboundLocalError reverts to NameError if class-based exceptions are disabled ...

"TP" == Tim Peters <tim_one@email.msn.com> writes:
TP> Sounds good to me, but if & only if it's a subclass of OSError I agree (and I think Mark's been given some ideas about how to accomplish this). TP> (why? because nothing else makes sense <wink>). I added TP> UnboundLocalError as a subclass of NameError (in the CVS TP> tree), so you can mimic what that did. IIRC, for the benefit TP> of the old "string-based exceptions" option hack, TP> UnboundLocalError reverts to NameError if class-based TP> exceptions are disabled ... I wouldn't worry about string-based standard exceptions. Didn't we decide to get rid of these (and -X) for 1.6 at IPC8? -Barry

On Mon, 7 Feb 2000, Barry A. Warsaw wrote:
I wouldn't worry about string-based standard exceptions. Didn't we decide to get rid of these (and -X) for 1.6 at IPC8?
In that case, installations should freeze exceptions.py into the binary, otherwise all hell *will* break loose... -- Moshe Zadka <mzadka@geocities.com>. INTERNET: Learn what you know. Share what you don't.

Moshe Zadka wrote:
I think we got agreement on that too (in some import related thread on this list). Hmmm, well I can't find exceptions.py mentioned specifically. But I do find the BDFL advocating writing as much as possible of the start-up code in Python (eg, the equivalent of getpath.c) and freezing it in. In his absence, it makes sense for us to include exceptions.py in that statement <wink>. - Gordon

On Mon, 7 Feb 2000, Gordon McMillan wrote:
Of course then you have a bootstapping issue (how to write the first interpreter. Probably, need some C code to get it started: but that C code would only be used in compiling the interpreter, not in the interpreter that gets installed...) -- Moshe Zadka <mzadka@geocities.com>. INTERNET: Learn what you know. Share what you don't.

Tim Peters writes:
Which reminds us once again of the old -X problem. Will this still be present in 1.6? I'd vote to remove it if this weren't a dictatorship. I don't see that it serves any useful purpose at this point. -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> Corporation for National Research Initiatives

On Mon, 7 Feb 2000, Fred L. Drake, Jr. wrote:
Don't think of it as "-X", think of it as "could not find exceptions.py, reverting to string exceptions" (or whatever the error message is). Be sure it won't change to "could not find exceptions.py, I don't think I feel like running" -- Moshe Zadka <mzadka@geocities.com>. INTERNET: Learn what you know. Share what you don't.

"MZ" == Moshe Zadka <moshez@math.huji.ac.il> writes:
MZ> Don't think of it as "-X", think of it as "could not find MZ> exceptions.py, reverting to string exceptions" (or whatever MZ> the error message is). Be sure it won't change to "could not MZ> find exceptions.py, I don't think I feel like running" Absolutely. If string-based standard exceptions are removed for 1.6, we need a fool-proof way of getting exceptions.py. Remember, my first attempt at this stuff made that Python code a BACS[*] that got exec'd. I'm sure there are better ways of doing that now, and I think exceptions.py has settled down enough to warrant cooling it for 1.6. -Barry [*] Big Ass C String

On Mon, 7 Feb 2000, Barry A. Warsaw wrote:
To possibly improve startup time and heap-memory usage, I added a feature into 1.5.2 that applies to freezing code. Specifically, a code object no longer requires a PyStringObject for the bytecodes. Any object exporting the buffer interface will work. This means that you don't have to copy the bytecodes onto the heap before using them. However, before this part can work properly, some special un-marshalling would need to happen. Currently, frozen code is a marshalled code object. When that is unmarshalled, the bytes will be copied. Instead, it would be nice to call PyCode_New() manually with all the various parameters and a "code" argument that is a PyBufferObject that points to the BACS. The alternative is to beef up the PyMarshal stuff so that it knows it can create buffers that point into a passed-in PyStringObject. Just some rambling thoughts... Cheers, -g -- Greg Stein, http://www.lyra.org/

On Tue, 8 Feb 2000, Fredrik Lundh wrote:
Why C? Implement it in Python and freeze the sucker. We all know that Python is much more maintainable. With a few simple changes, we can also make this freeze process very straight-forward and part of the standard build process. There are quite a few things that could be done in Python, then just frozen into the binary. Just wait until I start arguing for the parser and compiler to be written in Python, frozen in, and we dump their C equivalents... :-) Cheers, -g -- Greg Stein, http://www.lyra.org/

Why C? Implement it in Python and freeze the sucker.
size and performance. exception classes are installed during initialization of the python interpreter, and they all need to be made available for C code anyway. (in fact, the new code isn't that much larger than the code needed to copy stuff from exceptions.py) </F>

Actually, in this case, I'd vote for C too. My reason is stability. The process to freeze exceptions.py into the core will always be more fragile than the process to compile C code. --Guido van Rossum (home page: http://www.python.org/~guido/)

On Wed, 16 Feb 2000, Guido van Rossum wrote:
Heretic! :-) All right... I guess that I'm just gonna have to see if I can disprove your assertion :-) Cheers, -g -- Greg Stein, http://www.lyra.org/

Guido van Rossum wrote:
incomplete proof-of-concept implementation available here. see webpage and FIXME's in the code for more info: http://w1.132.telia.com/~u13208596/exceptions.htm </F>

I haven't looked at /F's code yet, but I've been thinking about doing something very similar for JPython. I think it'll be easier to freeze it in Java than in C. -Barry

Fredrik writes:
any reason you can't just throw OSError exceptions?
Mainly cos the error numbers are different - (eg, compare "errno.h" with "winerror.h" OSError really should be named CRTError. I dont think it makes much sense to have 2 different error numbering schemes use the same exception... I guess we _could_ tho - I still lean towards a new one, but other opinions would be good... Mark.

On Mon, 7 Feb 2000, Mark Hammond wrote:
Um...my Windows programing experience is thankfully little, but I seem to remember every "big collection" of function works with a different error handler (the sockets with WSA...error...() is the example which comes to mind). The OSError is very UNIX-oriented, in that it assumes a monolithic OS with consistent errors. This problem will probably also come up when (in a century or so) I manage to get Python working on Hurd. How about, for windows, to derive "many" error classes from OSError on Win32, and always return the right one? On the other hand, Mark will correct me if I'm talking nonsense Windows-wise <wink> -- Moshe Zadka <mzadka@geocities.com>. INTERNET: Learn what you know. Share what you don't.

[Moshe writes:]
How about, for windows, to derive "many" error classes from OSError on Win32, and always return the right one?
Another alternative would be to derive from EnvironmentError. I would then like to change the __str__ method from: ... return '[Errno %s] %s: %s' % (self.errno, self.strerror, ... to return '[%s %s] %s: %s' % (self.getdesc(), self.errno, self.strerror, Where getdesc() returns "OS Error", "IO Error" or "Win32 error" respectively. This all comes down to Guido tho. I believe he is away, so if he doesnt respond Ill simply send him a summary of the discussions and he can decide lickety-split! Mark.

[/F]
any reason you can't just throw OSError exceptions?
[Mark]
Mainly cos the error numbers are different - (eg, compare "errno.h" with "winerror.h" OSError really should be named CRTError.
There's nothing to stop a new CRTError class being derived from OSError, leaving OSError platform-neutral. This would just be vanilla OO refactoring in the face of new requirements, and existing code wouldn't know the difference. You should subclass from OSError so that code that cares about portability can catch OSError specifically instead of needing to be modified every time someone with a new OS wants to add a class of error specific to that OS.
I dont think it makes much sense to have 2 different error numbering schemes use the same exception...
No, I agree that does not. But it makes perfect sense for a subclass to override its parent's numbering scheme (and even more sense to make "numbering scheme" an abstract property of the parent to be implemented by its subclasses).

Im looking for closure on the Win32 specific exception. Summary for those that missed the thread: * I would like a standard exception for Win32 specific errors. The new hopefully-to-be-standard "win32reg" module could make use of it, the win32 extensions could switch to it. It is, in my mind at least, analogous to OSError. * I proposed deriving the new exception from EnvironmentError, like OSError is. * Fredrik replied with "why not use OSError then?". I answered "due to the numbering systems being different" * Tim agreed that they should be different exceptions if they use different numbering, but pointed out it could still be OSError with creative exception hierarchies. So, in summary, no one disagreed, and the only open issue was the exception hierarchy. My initial proposal called for: StandardError: -> EnvironmentError: -> IOError -> OSError -> Win32Error Which would generally lead to people writing "except Win32Error:" Tim's suggestion (as I understand it) was: StandardError: -> EnvironmentError: -> IOError -> OSError -> CRTError (new - is what os.error would use) -> Win32Error (new) which would lead to people writing "except IOError:" I still like my idea better - fits better with the existing "IOError", and doesnt cause confusion with the change from os.error being OSError to os.error being CRTError. Guido: Can you first make a "yes/no" decision, then (if necessary <wink>) an either/or one? Thanks, Mark.

Im looking for closure on the Win32 specific exception. Summary for those that missed the thread:
My apologies. I *did* miss the thread. I think this is a reasonable request.
I see no merit in adding CRTError -- that's an abstraction that's only relevant to C developers on Windows. I do like it better if Win32Error derives from OSError. Shouldn't it be just WinError or WindowsError? I don't see why a different exception should be used for Win64.
which would lead to people writing "except IOError:"
I don't understand this -- Win32Error isn't derived from IOError.
OK, this is a definite Yes. The either/or I'm still open on. --Guido van Rossum (home page: http://www.python.org/~guido/)

[Guido]
Oops - I meant OSError. What I meant is that people will say: try: win32reg.Something() except IOError, ... Rather than the specific error. This makes our specific Windows exception, basically, an internal mechanism to get the error messages lined up with the error number. Not that this is a problem, but I just thought it worth mentioning. OK - so lets go with: WindowsError(OSError): ... If no one complains, I will submit the relevant patches to Exception.py along with my win32reg.c (I can leave string-based exceptions out, yes?) Mark.

[Mark Hammond]
Yes! Note that you're the joker who brought up CRTError: I only mentioned the *possibility* of refactoring to OSError CRTError WindowsError to shut you up <wink>.
Is the -X switch going away? If so, sure. If not, you probably can't. I'd be delighted if -X went away (the purpose it served has expired).

Yes, -X is going away. --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (10)
-
Barry A. Warsaw
-
Fred L. Drake, Jr.
-
Fredrik Lundh
-
Fredrik Lundh
-
Gordon McMillan
-
Greg Stein
-
Guido van Rossum
-
Mark Hammond
-
Moshe Zadka
-
Tim Peters