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.
builtinsis not a normal module. It's loaded as part of the core interpreter; I doubtreloadactually does anything meaningful for it.sys,__main__,builtinsand 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."exec-ed code that stores tobuiltinson purpose? WTF?!? If it's just assigning values to its own globals, just create a newdictand then pass a reference to it toexecto populate, don't pollute the namespace of every Python module to do something terrible.