Re: Context manager with class methods
Terry Reedy wrote: it is normal to look for special methods on the class (and superclasses) of an object rather than starting with the object itself. I suspect there was a deliberate change to correct an anomaly, though this might have been done as part of some other change. It's a necessary consequence of the fact that new-style classes are also instances. Without it, there would be an ambiguity as to whether a special method defined the behaviour of instances of a class or of the class object itself. It also increases efficiency, because for those special methods that correspond to C-level type slots, you only have to look in the type slot to find an implementation of the method, rather than having to look in the instance dict first. -- Greg -- http://mail.python.org/mailman/listinfo/python-list
Context manager with class methods
Hi, 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 However, in 2.7 and 3.2 I get: Traceback (most recent call last): File stdin, line 1, in module AttributeError: __exit__ 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. Gavin. -- http://mail.python.org/mailman/listinfo/python-list
Re: Context manager with class methods
Am 22.09.2011 12:21 schrieb Gavin Panella: Hi, 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 However, in 2.7 and 3.2 I get: Traceback (most recent call last): File stdin, line 1, inmodule AttributeError: __exit__ Same here. But with Foo(): pass works, and that is more important and more logical. Thomas -- http://mail.python.org/mailman/listinfo/python-list
Re: Context manager with class methods
Gavin Panella wrote: Hi, 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 However, in 2.7 and 3.2 I get: Traceback (most recent call last): File stdin, line 1, in module AttributeError: __exit__ 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. This seems to work: class MetaWith (type): @classmethod def __enter__(cls): print(__enter__) @classmethod def __exit__(cls, exc_type, exc_value, traceback): print(__exit__) class With (object): __metaclass__ = MetaWith with With: pass Mel. -- http://mail.python.org/mailman/listinfo/python-list
Re: Context manager with class methods
Mel wrote: This seems to work: class MetaWith (type): @classmethod def __enter__(cls): print(__enter__) @classmethod def __exit__(cls, exc_type, exc_value, traceback): print(__exit__) class With (object): __metaclass__ = MetaWith with With: pass It seems to work equally well without the `@classmethod`s Mel. -- http://mail.python.org/mailman/listinfo/python-list
Re: Context manager with class methods
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, inmodule 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