Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use contextlib.contextmanager with a classmethod?

See the below Python 3.10 snippet:

import contextlib

class Foo:
    @contextlib.contextmanager
    @classmethod
    def state(cls):
        try:
            yield
        finally:
            pass

with Foo.state():
    pass

It throws a TypeError:

Traceback (most recent call last):
  File "/path/to/code/play/quick_play.py", line 12, in <module>
    with Foo.state():
  File "/path/to/.pyenv/versions/3.10.5/lib/python3.10/contextlib.py", line 281, in helper
    return _GeneratorContextManager(func, args, kwds)
  File "/path/to/.pyenv/versions/3.10.5/lib/python3.10/contextlib.py", line 103, in __init__
    self.gen = func(*args, **kwds)
TypeError: 'classmethod' object is not callable

Is it possible to decorate a classmethod with contextlib.contextmanager? And if yes, how can it be done?

like image 377
Intrastellar Explorer Avatar asked May 18 '26 12:05

Intrastellar Explorer


1 Answers

This should work:

import contextlib

class Foo:
    @classmethod
    @contextlib.contextmanager
    def state(cls):
        try:
            print("A")
            yield
            print("C")
        finally:
            pass

with Foo.state():
    print("B")

This prints A B C.

like image 167
Albert Avatar answered May 20 '26 00:05

Albert