[Python-Dev] On suppress()'s trail blazing (was Re: cpython: Rename contextlib.ignored() to contextlib.ignore())

Xavier Morel python-dev at masklinn.net
Thu Oct 17 21:30:04 CEST 2013


On 2013-10-17, at 20:55 , Oscar Benjamin wrote:
> On 17 October 2013 19:40, Xavier Morel <python-dev at masklinn.net> wrote:
>> I think there's already a significant split between context managers
>> which handle the lifecycle of a local resource (file, transaction) and
>> those which purport to locally alter global-ish state (cwd,
>> decimal.localcontext, logging.captureWarnings, redirect_stdout).
>> 
>> And the latter worries me (much more than the very localized behavior of
>> suppress) because I don't see any way to implement them safely and
>> correctly when mixing it with coroutines in today's Python (some of them
>> aren't even thread-safe), all of that while I expect coroutines will see
>> significantly more use in the very near future with yield from and
>> tulip's promotion of coroutine-style async.
> 
> I maybe misunderstanding how the  coroutine-style async works but I
> would have thought that it would be as simple as: don't use
> global-state-restoring-context-managers around statements that yield
> control

You have to know which contextmanagers to what and how, and avoid them
in these specific situations. I'm really bothered by these being unsafe
by default. Technically they're already broken but the chance of them
being used in such a context are low, whereas it wouldn't be unexpected
for a user to e.g. create a local decimal context in a coroutine and
*not* expect that local context to affect other coroutines running
concurrently.

> Context managers that actually save and restore *global* state are already
> not thread-safe

Hence my use of "global-ish", a global is process-local after all. A
threadlocal is greenlet-global (for the greenlets running in that
thread), and a greenlet-local is coroutine-global (although I don't
expect multiplexing coroutines inside greenlets to be common, the
natural consequence is that threadlocals are also coroutine-global).

> , so concluding they are also not coroutine-safe (or
> task-safe?) seems a small step.

Yes, but not necessarily a step most users will remember to take, and of
course the lack of thread-safety must be documented and noticed (as with
warnings.catch_warnings[0]). Although I agree that

> I'd be more worried about context manager that use thread-local state --
> there is no similar concept in Tulip.

indeed.

[0] not logging.captureWarnings() which I previously wrote,
    captureWarnings is not a context manager


More information about the Python-Dev mailing list