3

What is the best way to ignore IPython magic when running scripts using the python interpreter?

I often include IPython magic in my script files because it work with the code interactively. For example, with the autoreload magic, I don't have to keep reload-ing the modules after I make some changes and fix bugs:

%load_ext autoreload
%autoreload 2

However, when I try to run this script using a usual python interpreter, I get an error:

  File "<string>", line 1
    %load_ext autoreload
    ^
SyntaxError: invalid syntax

Wrapping IPython magic inside an if statement does not work, because incorrect syntax is detected before the file is actually ran.


So what is the best way to get python to ignore IPython magic?

It's annoying to have to change your scripts whenever you want to run then in python, pdb, sphinx, etc.

ostrokach
  • 17,993
  • 11
  • 78
  • 90

5 Answers5

3

For all tools that can read from standard input you could use grep to remove any magic lines and pipe the result into python:

grep -v '^%' magicscript.ipy | python

Works well as a bash alias:

alias pynomagic='( grep -v "^%" | python ) < '
pynomagic magicscript.ipy

Tools like pdb that only accept filenames could be called like this (bash again):

pdb <(grep -v '^%' magicscript.ipy)
dmaticzka
  • 106
  • 1
  • 3
  • I am running my code inside the Spyder IDE using the `runfile` and `debugfile` commands, so `grep` does not really help, but it might be useful for someone else :). – ostrokach May 31 '15 at 16:57
3

In case this helps anyone.

At least for Databricks, when syncing a notebook with a .py file in Github, a magic function can be specified with a specially formatted comment. Like this:

# MAGIC %run ./my_external_file

Casper Lehmann
  • 475
  • 2
  • 13
2

You should load such magic in your config file, not in your scripts! It is just not valid Python.

Put the following in your ~/.ipython/profile_default/ipython_config.py:

c = get_config()
c.InteractiveShellApp.extensions = ['autoreload']
c.InteractiveShellApp.exec_lines = ['%autoreload 2']
c.InteractiveShellApp.exec_lines.append('print("Warning: disable autoreload in ipython_config.py to improve performance.")')
Roland Smith
  • 42,427
  • 3
  • 64
  • 94
  • Hmmm. I was hoping there would be a way to do this on a per-file basis. `autoreload` was just an example. There are cases where I make a plot using rpy2 magic, or save some sql code to a file using %%file magic. I just want python to ignore IPython code blocks. – ostrokach May 31 '15 at 20:27
  • 1
    @ostrokach One possible solution I thought up was to write a script to replace the `python` command. This script would "clean" the files before handing them over to the "real" python. *But that would probably also affect IPython!* So that won't work. (Unless you could configure IPython to call the "real" python directly.) In the final analysis, IPython commands are just not valid Python. – Roland Smith May 31 '15 at 20:50
1
  1. Create a template file named simplepython.tpl. Copy the below statements.

    {% extends 'python.tpl'%}
    {% block codecell %}
    {{  super().replace('get_ipython','#get_ipython') if "get_ipython" in super() else super() }}
    {% endblock codecell %}
    
  2. Save simplepython.tpl.

  3. Type in command line:

    jupyter nbconvert --to python 'IPY Notebook' --template=simplepython.tpl --stdout

zx485
  • 28,498
  • 28
  • 50
  • 59
0

Spyder gives warning (as given in the picture below), when a coder use this type of code and says that it is not a valid Python code.

So, in order to use IPython magics, saving files with the .ipy extension may be a solution.

Spyder screenshot

kbayram
  • 1
  • 3