[Python-Dev] Exceptions and slicing

Thomas Heller theller at python.net
Wed Sep 20 21:38:39 CEST 2006


Brett Cannon schrieb:
> On 9/20/06, Thomas Heller <theller at python.net> wrote:
>>
>> Is it an oversight that exception instances do no longer support
>> slicing in Python 2.5?
>>
>> This code works in 2.4, but no longer in 2.5:
>>
>> try:
>>     open("", "r")
>> except IOError, details:
>>     print details[:]
> 
> 
> Technically, yes.  There is no entry in the sq_slice field for the
> PySequenceMethods struct.  Although you can get to the list of arguments by
> going through the 'args' attribute if you need a quick fix.

Well, Nick Coghlan pointed out in private email:

>> According to PEP 352 it should have at most been deprecated along with the 
>> rest of Exception.__getitem__:
>>
>> "This also means providing a __getitem__ method is unneeded for exceptions and 
>> thus will be deprecated as well."

> I have a fix in my checkout that I will check into the trunk shortly and
> into 25-maint as soon as Anthony unfreezes it.

I was not aware before I posted that tuple-unpacking of exceptions still works,
so this is another possibility:
    except WindowsError, (errno, message):


What I find worse about WindowsError especially is two things:

1. The __str__ of a WindowsError instance hides the 'real' windows
error number.  So, in 2.4 "print error_instance" would print
for example:

  [Errno 1002] Das Fenster kann die gesendete Nachricht nicht verarbeiten.
    
while in 2.5:

  [Error 22] Das Fenster kann die gesendete Nachricht nicht verarbeiten.

because the new mapping of windows error codes to posix error codes creates
EINVAL (22) when no corresponding posix error code exists.

2. How would one write portable exception handling for Python 2.4 and 2.5?

I have code like this:

try:
    do something
except WindowsError, details:
    if not details.errno in (TYPE_E_REGISTRYACCESS, TYPE_E_CANTLOADLIBRARY):
        raise

Doesn't work in 2.5 any longer, because I would have to use details.winerror
instead of e.errno.

The two portale possibilities I found are these, but neither is elegant imo:

  except WindowsError, (winerrno, message):
or
  except WindowsError, details:
      winerrno = details[0]

And the latter still uses __getitem__ which may go away according to PEP 352.

Thomas



More information about the Python-Dev mailing list