1

I've been storing variable information inside the builtins module and I want to clear all the variable information that is stored inside of it. I can't figure out how to do it though.

import importlib
import builtins
print("add" in dir(builtins))
builtins.add = "x"
print("add" in dir(builtins))
importlib.reload(builtins)
print("add" in dir(builtins))

This doesn't seem to work.

btomtom5
  • 842
  • 8
  • 16
  • 6
    "I've been storing variable information inside the builtins module" - jesus crap, ***why***? – user2357112 Mar 01 '16 at 03:58
  • `builtins` is not a normal module. It's loaded as part of the core interpreter; I doubt `reload` actually does anything meaningful for it. – ShadowRanger Mar 01 '16 at 03:59
  • 3
    BTW, per [the docs](https://docs.python.org/3/library/importlib.html#importlib.reload): "It is generally not very useful to reload built-in or dynamically loaded modules. Reloading `sys`, `__main__`, `builtins` and other key modules is not recommended. In many cases extension modules are not designed to be initialized more than once, and may fail in arbitrary ways when reloaded." – ShadowRanger Mar 01 '16 at 04:04
  • @user2357112 Yea, I realize what I am doing is not conventional. I am supplying a builtins module to a dictionary that is being passed into the global_env parameter of an exec function. Code from the exec function stores its global variables inside of builtins module naturally and I want a clean copy of the builtins module. – btomtom5 Mar 01 '16 at 04:05
  • 2
    @btomtom5: Okay, you're not making this seem any more sane. `exec`-ed code that stores to `builtins` on purpose? WTF?!? If it's just assigning values to its own globals, just create a new `dict` and then pass a reference to it to `exec` to populate, don't pollute the namespace of every Python module to do something terrible. – ShadowRanger Mar 01 '16 at 04:08
  • @ShadowRanger I feel like I have justified reason to do this. I am serializing many different types of python objects using the dill module except dill relies on the builtins to get class definitions. So when I try copying an object defined inside an exec function from outside the exec functions environment, I have to define the object twice. Once inside the builtins module and another time normally. After the object is copied, I clear the builtins module. But sometimes my program crashes before I can clean up after myself and I need a clean slate which is why I need to "reload' builtins. – btomtom5 Mar 01 '16 at 04:26

1 Answers1

1

reload does not clear a module's __dict__ before reloading it, so reloading a module doesn't affect any names you add to it that weren't originally part of the module.

It is essentially always better to avoid messing with the builtins module than to try to restore it after messing with it. That said, if you really want to do this, save a copy of builtins.__dict__ before messing with it so you can restore from the backup later:

# Before screwing with builtins:
builtins_backup = builtins.__dict__.copy()

# After screwing with builtins:
builtins.__dict__.clear()
builtins.__dict__.update(builtins_backup)

That's not going to be threadsafe if another thread comes in between the clear and the update, but trying to reload builtins is hardly in safe territory anyway.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • aah this makes sense. I appreciate this a lot! That being said, this does seem incredibly unstable and seems like bad practice as you suggested. I will use this to front functionality for now before I come up with a more stable solution. – btomtom5 Mar 01 '16 at 05:34