Python question: is there a way to write a Python ...
# development
h
Python question: is there a way to write a Python
contextmanager
that can accept some kind of output from the context and do something with it after the
yield
statement?
h
Hm, I don’t think so. What’s the motivation?
f
you could use the yielded context object to do this
f
You could have the context object have a attribute or method to set a value, then use that value
Copy code
@dataclass
class Context:
  foo: Optional[str]

@contextmanager
def some_context_making_func()
  obj = Context(None)
  yield obj
  print(f"output: {obj.foo}")

with some_context_making_func() as obj:
  obj.foo = "some output"
f
or make the context object callable:
Copy code
@contextmanager
def record_calls():
    calls = []
    yield lambda *args, **kwds: calls.append((args, kwds))
    for call in calls:
        print(call)

with record_calls() as record:
    for i, c in enumerate('abc'):
        record(**{c: i})
h
@hundreds-father-404 motivation is that I'd like to turn the paired calls of
_start_run
and
_finish_run
in
local_pants_runner.py
into a context
but
_finish_run
needs the
engine_result
as an argument
f
for a context manager, you'll need to do this via the context object, or i guess you could subclass
BaseException
(kinda cheating but the stdlib does it with
StopIteration
, so who am i to judge)
h
using a lambda in the
yield
that modifies a data structure in the context seems like a reasonably succinct way to do this, thanks for the suggestion
👍 1
f
you could also just do this with a decorator and try/finally
h
I'm not sure I understand how you might do this with a decorator
f
i'd probably have to see in context
in any case, good luck, and may your stack traces be legible 🤞
h
thanks 🙂
w
probably not with a contextmanager, but you can with a coroutine
but it would be a bit unusual for this usecase i think.