[Python-Dev] Proposed resolutions for open PEP 343 issues

Guido van Rossum guido at python.org
Tue Oct 25 18:14:29 CEST 2005

On 10/25/05, Nick Coghlan <ncoghlan at gmail.com> wrote:
> Almost there - this is the only issue I have left on my list :)
> > Why are you so keen on TypeError? I find AttributeError totally
> > appropriate. I don't see symmetry with for-loops as a valuable
> > property here. AttributeError and TypeError are often interchangeable
> > anyway.
> The reason I'm keen on TypeError is because 'abstract.c' uses it consistently
> when it fails to find a method to support a requested protocol.

Hm. abstract.c well predates the new type system. Slots and methods
weren't really unified back then, so TypeError made obvious sense at
the time.

But with the new unified types/classes, those TypeErrors are really
just delayed (or precomputed? depends on your POV) AttributeErrors.

> None of the abstract object methods currently raise AttributeError, and this
> property is fairly visible at the Python level because the abstract API's are
> used to implement many of the bytecodes and various builtin functions. Both
> for loops and the iter function, for example, get their current exception
> behaviour from PyObject_GetIter and PyIter_Next.
> Having had a look at mwh's patch, however, I've realised that going that way
> would only be possible if there were dedicated bytecodes for GET_CONTEXT,
> ENTER_CONTEXT and EXIT_CONTEXT (similar to the dedicated GET_ITER and FOR_ITER).
> Leaving the exception as AttributeError means that level of bytecode hacking
> isn't necessary (mwh's patch just emits a fairly normal try/finally statement,
> although it still modifies the bytecode to include LOAD_EXIT_ARGS).

Let's definitely not introduce new bytecodes just so we can raise a
different exception.

> So, the inconsistency with other syntactic protocols still bothers me, but I
> can live with AttributeError if you don't want to add three new bytecodes just
> to support PEP 343.

I think the consistency you are seeking is a mirage. The TypeErrors
stem from the pre-computation of the slot population, not from some
requirements to raise TypeError for failing to implement some required
built-in protocol. I wouldn't hold it against other implementations of
Python if they raised AttributeError in more situations.

It is true though that AttributeError is somewhat special. There are
lots of places (perhaps too many?) where an operation is defined using
something like "if the object has attribute __foo__, use it, otherwise
use some other approach".  Some operations explicitly check for
AttributeError in their attribute check, and let a different exception
bubble up the stack. Presumably this is done so that a bug in
somebody's __getattr__ implementation doesn't get masked by the
"otherwise use some other approach" branch. But this is relatively
rare; most calls to PyObject_GetAttr just clear the error if they have
a different approach available. In any case, I don't see any of this
as supporting the position that TypeError is somehow more appropriate.
An AttributeError complaining about a missing __enter__, __exit__ or
__context__ method sounds just fine. (Oh, and please don't go checking
for the existence of __exit__ before calling __enter__. That kind of
bug is found with even the most cursory testing.)

--Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-Dev mailing list