Skip to content


Add drop_by_id method to shell, to remove variables added by extensions. #889

wants to merge 1 commit into from

2 participants

IPython member

This was prompted by the revived physics extension. Extensions can drop a lot of variables into the user namespace. Ideally, if the extension is unloaded, those variables should disappear, but only if the names haven't been rebound.

This works as a counterpart to ip.push(). The idea is that an extension can work like this:

myvars = dict(a=foo(), b=bar(), c=baz())

def load_ipython_extension(ip):

def unload_ipython_extension(ip):
IPython member

merged with rebase to avoid recursive merge for just one commit. thx!

@fperez fperez closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 32 additions and 1 deletion.
  1. +18 −0 IPython/core/
  2. +14 −1 IPython/core/tests/
18 IPython/core/
@@ -1264,6 +1264,24 @@ def push(self, variables, interactive=True):
for name,val in vdict.iteritems():
config_ns[name] = val
+ def drop_by_id(self, variables):
+ """Remove a dict of variables from the user namespace, if they are the
+ same as the values in the dictionary.
+ This is intended for use by extensions: variables that they've added can
+ be taken back out if they are unloaded, without removing any that the
+ user has overwritten.
+ Parameters
+ ----------
+ variables : dict
+ A dictionary mapping object names (as strings) to the objects.
+ """
+ for name, obj in variables.iteritems():
+ if name in self.user_ns and self.user_ns[name] is obj:
+ del self.user_ns[name]
+ self.user_ns_hidden.pop(name, None)
# Things related to object introspection
15 IPython/core/tests/
@@ -179,4 +179,17 @@ def test_bad_custom_tb_return(self):
io.stderr = save_stderr
+ def test_drop_by_id(self):
+ ip = get_ipython()
+ myvars = {"a":object(), "b":object(), "c": object()}
+ ip.push(myvars, interactive=False)
+ for name in myvars:
+ assert name in ip.user_ns, name
+ assert name in ip.user_ns_hidden, name
+ ip.user_ns['b'] = 12
+ ip.drop_by_id(myvars)
+ for name in ["a", "c"]:
+ assert name not in ip.user_ns, name
+ assert name not in ip.user_ns_hidden, name
+ assert ip.user_ns['b'] == 12
+ ip.reset()
Something went wrong with that request. Please try again.