Context manager that stores a temporary context for __globals__

Currently, some mutations to __globals__ happen in ways that cause unexpected side effects. For example, this issue: issues/73858 trips people up and produces repetitive warnings across multiple libraries due to the way that catch_warnings uses the __warningregistry__ in __globals__.

Proposition
Context manager: isolated_env (or similar name) where:

  • At the time of calling, it gets a copy of __globals__
  • All calls to __globals__ from inside the context manager would go to an isolated copy so that __globals__ is not mutated

An alternative, possibly named isolate_global might accept arguments for only specific variables to be isolated e.g.:

with isolate_global('__warningregistry__'):
    with warnings.catch_warnings():
        ... # do something

I’m not 100% sure that the context manager is the right tool for this, although it felt most natural to reach for. I’ll also search for other use cases of mutating __globals__ and how people have worked with them.

This sounds like something that should be straightforward to implement in user code and doesn’t require special support. I guess you are thinking of adding something to the standard library? But it’s not clear to me where it would belong. I don’t think contextmanager itself makes much sense for it, for example.

I think the intent here is for a user to be able to force other functions e.g. library functions or third party functions to work only inside the isolated copy of __globals__.

Skimming the standard library I don’t see a natural place for it either

Do you expect this to be a deep or shallow copy? How would this behave? Specifically:

The current behaviour of catch_warnings() doesn’t actually change the caller’s globals in any way. What it does is change the warnings module itself. How would isolate_global work?

1 Like

Really? I currently can’t imagine a sensible solution that doesn’t involve highly invasive interpreter support, but maybe I am missing something. The many different __globals__ values are referenced from many different places, no? Each module has it’s own dictionary, each class and each function has it’s own reference. You would have to somehow change all of them.

Unless you mean that the mutations of the globals are tracked and undone, but that is not what op asked for.

yep, I missed that the globals are on a per module basis. I can’t think of a way for this to reasonably work. Is there a way to close this thread?

Adding [Closed by author] to the title should effectively do so.

Closed at author’s request.