From 079a59bd7546520223aa59086e893eb571c05687 2014-04-17 01:12:06 From: George Titsworth Date: 2014-04-17 01:12:06 Subject: [PATCH] Added new capability to the `%load` magic to search the user's namespace for modules, classes, or functions and inspects those to load source. Currently, the `-n` argument must be passed to `%load` to enable this capability. --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 97efe87..32d7f44 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -3089,7 +3089,7 @@ class InteractiveShell(SingletonConfigurable): lines = self.history_manager.get_range_by_str(range_str, raw=raw) return "\n".join(x for _, _, x in lines) - def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True): + def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False): """Get a code string from history, file, url, or a string or macro. This is mainly used by magic functions. @@ -3156,11 +3156,31 @@ class InteractiveShell(SingletonConfigurable): elif os.path.isdir(os.path.expanduser(tgt)): raise ValueError("'%s' is a directory, not a regular file." % target) + if search_ns: + obj = None + parts = target.split(".") + try: + if len(parts) >= 1: + obj = self.user_ns[parts[0]] + + for new_obj in parts[1:]: + obj = getattr(obj, new_obj) + + if obj: + + code = oinspect.getsource(obj) + return code + except Exception: + # Either the value wa't in th user_ns or the objects could + # not be inspected. It still might load below, so just pass. + pass + try: # User namespace codeobj = eval(target, self.user_ns) except Exception: raise ValueError(("'%s' was not found in history, as a file, url, " "nor in the user namespace.") % target) + if isinstance(codeobj, string_types): return codeobj elif isinstance(codeobj, Macro): diff --git a/IPython/core/magics/code.py b/IPython/core/magics/code.py index 35c16de..fd869d7 100644 --- a/IPython/core/magics/code.py +++ b/IPython/core/magics/code.py @@ -272,7 +272,8 @@ class CodeMagics(Magics): Usage:\\ %load [options] source - where source can be a filename, URL, input history range or macro + where source can be a filename, URL, input history range, macro, or + element in the user namespace Options: @@ -285,6 +286,8 @@ class CodeMagics(Magics): -y : Don't ask confirmation for loading source above 200 000 characters. + -n : Include the user's namespace when searching for source code. + This magic command can either take a local filename, a URL, an history range (see %history) or a macro as argument, it will prompt for confirmation before loading source with more than 200 000 characters, unless @@ -297,14 +300,18 @@ class CodeMagics(Magics): %load -r 5-10 myscript.py %load -r 10-20,30,40: foo.py %load -s MyClass,wonder_function myscript.py + %load -n MyClass + %load -n my_module.wonder_function """ - opts,args = self.parse_options(arg_s,'ys:r:') + opts,args = self.parse_options(arg_s,'yns:r:') if not args: raise UsageError('Missing filename, URL, input history range, ' - 'or macro.') + 'macro, or element in the user namespace.') + + search_ns = 'n' in opts - contents = self.shell.find_user_code(args) + contents = self.shell.find_user_code(args, search_ns=search_ns) if 's' in opts: try: