With class as contextmanager

Ethan Furman ethan at stoneleaf.us
Tue Jan 24 18:25:25 EST 2017


On 01/24/2017 02:35 PM, Ethan Furman wrote:
> On 01/24/2017 01:31 PM, This Wiederkehr wrote:

>> having a class definition:
>>
>> class Test():
>>
>> @classmethod
>> def __enter__(cls):
>>      pass
>>
>> @classmethod
>> def __exit__(cls, exception_type, execption_value, callback):
>>      pass
>>
>> now using this as a contextmanager does not work, even though Test is an
>> object and has the two required methods __enter__ and __exit__.
>
> It is not working because you are trying to use the class itself, and not it's instances, as a context manager (which also means you don't need classmethod):
>
> Wrong:
>
>    with Test:
>
> Correct:
>
>    with Test():
>
>> I am asking because I'd like to implement the clean up behaviour for
>> multiple instances directly into the class:
>>
>> with Test:
>>     testinstance1 = Test()
>>     testinstance2 = Test()
>> # on context exit Test.__exit__ should take care on cleaning up
>> testinstance1 and testinstance2.
>
> You might be able to make this work with a custom type (aka using a custom metaclass) -- but that could be a bunch of work.

Okay, here's the easy part:

--- 8< ----------------------------
class TestType(type):
     def __enter__(cls):
         pass
     def __exit__(cls, *args):
         pass

class Test(metaclass=TestType):
     pass

with Test:
     print('worked!')
--- 8< ----------------------------

Let us know how it turns out.

--
~Ethan~


More information about the Python-list mailing list