diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 97efe87..98b924a 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,18 @@ 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: + # Inspect namespace to load object source + object_info = self.object_inspect(target, detail_level=1) + if object_info['found'] and object_info['source']: + return object_info['source'] + 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: diff --git a/docs/source/interactive/qtconsole.rst b/docs/source/interactive/qtconsole.rst index d6397ae..0394569 100644 --- a/docs/source/interactive/qtconsole.rst +++ b/docs/source/interactive/qtconsole.rst @@ -57,6 +57,17 @@ for playing with examples from documentation, such as matplotlib. ...: ...: plt.show() +The ``%load`` magic can also load source code from objects in the user or +global namespace by invoking the ``-n`` option. + +.. sourcecode:: ipython + + In [1]: import hello_world + ...: %load -n hello_world.say_hello + + In [3]: def say_hello() : + ...: print("Hello World!") + Inline Matplotlib ================= diff --git a/docs/source/whatsnew/pr/load_from_namespace.rst b/docs/source/whatsnew/pr/load_from_namespace.rst new file mode 100644 index 0000000..25d33b7 --- /dev/null +++ b/docs/source/whatsnew/pr/load_from_namespace.rst @@ -0,0 +1,6 @@ +Adds object inspection to %load magic so that source for objects in user or global namespaces can be loaded. To enable searching the namespace, use the ``-n`` option. + +.. sourcecode:: ipython + + In [1]: %load -n my_module.some_function +