https://pantsbuild.org/ logo
#development
Title
# development
h

hundreds-breakfast-49010

10/27/2020, 8:35 PM
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

hundreds-father-404

10/27/2020, 8:37 PM
Hm, I don’t think so. What’s the motivation?
f

flat-zoo-31952

10/27/2020, 8:42 PM
you could use the yielded context object to do this
f

fast-nail-55400

10/27/2020, 8:42 PM
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

flat-zoo-31952

10/27/2020, 8:45 PM
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-breakfast-49010

10/27/2020, 8:46 PM
@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

flat-zoo-31952

10/27/2020, 8:47 PM
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

hundreds-breakfast-49010

10/27/2020, 8:48 PM
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

flat-zoo-31952

10/27/2020, 8:48 PM
you could also just do this with a decorator and try/finally
h

hundreds-breakfast-49010

10/27/2020, 8:49 PM
I'm not sure I understand how you might do this with a decorator
f

flat-zoo-31952

10/27/2020, 8:50 PM
i'd probably have to see in context
in any case, good luck, and may your stack traces be legible 🤞
h

hundreds-breakfast-49010

10/27/2020, 8:56 PM
thanks 🙂
w

witty-crayon-22786

10/27/2020, 9:03 PM
probably not with a contextmanager, but you can with a coroutine
but it would be a bit unusual for this usecase i think.