On 9/22/2011 6:21 AM, Gavin Panella wrote:

On Python 2.6 and 3.1 the following code works fine:
     class Foo(object):
         @classmethod
         def __enter__(cls):
             print("__enter__")
         @classmethod
         def __exit__(cls, exc_type, exc_value, traceback):
             print("__exit__")

     with Foo: pass

This could be regarded as a bug, see below.

However, in 2.7 and 3.2 I get:

     Traceback (most recent call last):
       File "<stdin>", line 1, in<module>
     AttributeError: __exit__

type(Foo) == type and type has no such attribute.

Unless otherwise specified, 'method' typically means 'instance method'. In particular, the '__xxx__' special methods are (all?) (intended to be) instance methods, which is to say, functions that are attributes of an object's class. So it is normal to look for special methods on the class (and superclasses) of an object rather than starting with the object itself. For instance, when executing 'a+b', the interpreter never looks for __add__ as an attribute of a itself (in a.__dict__)
but starts the search looking for with type(a).__add__

Is this a regression or a deliberate change? Off the top of my head I
can't think that this pattern is particularly useful, but it seems
like something that ought to work.

I suspect there was a deliberate change to correct an anomaly, though this might have been done as part of some other change. As Thomas noted, *instances* of Foo work and as Mei noted, making Foo an instance of a (meta)class with the needed methods also works.

--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to