Refactoring of the magics system and implementation of cell magics #1732

Merged
merged 103 commits into from May 27, 2012

Conversation

Projects
None yet
6 participants
Owner

fperez commented May 14, 2012

This IS now ready to merge!

Implement cell-level magics, with support in all frontends. In all text consoles the behavior is similar to that for other interactive code: one blank line signals the end of the cell. In the notebook, such limitation doesn't exist, of course.

The final version is slightly different from the original IPEP (#1611): we do not allow separate implementations of line and cell magics with the same name. Instead, a single function with signature def f(line, cell=None) (with self if done as a method) will have to be called and distinguish whether the call is line-magic or cell-magic based on whether cell is None or a string.

All tests now pass on my machine, so this is good to go for full review.

Owner

ellisonbg commented May 15, 2012

What I think is important is that from the user's perspective there can be cell and line magics with the same name. We don't want to have to have separate %timeit and %timeit_cell magics. I do think that is important? Are you saying you want to back pedal on that? Or are you saying that you want to change the API for implementing those different magics.

In terms of the implementation, I think you should do whatever makes it easiest to accomplish this with minimal complexity and code bloat - even if it doesn't follow the IPEP.

If you feel like you don't have time to support cell magics with the same name right now, then let's come up with a design that will allow us to add that in later without breaking the API we put in place now.

Owner

fperez commented May 16, 2012

@ellisonbg, sorry for not being clear enough: there's nothing to worry user-side, it's just that in order to implement a magic that can be used both as %f and %%f, we'll have to write a function with the signature

@line_cell_magic
def f(self, line, cell=None):
  if cell is None:
    do_line_stuff(line)
  else:
    do_line_and_cell_stuff(line, cell)

instead of being able to use separate implementations for the line-only and cell-only parts. So I don't think it's a big deal. I'll add this new decorator.

It's just that I'm finding I need to have a single namespace, so that a magic name X maps to only one function, whether it's line-only, cell-only or line-and-cell. The management of truly disjoint line and cell namespaces was proving to be an ever-growing tangle of complexity.

Does that make sense?

Owner

ellisonbg commented May 18, 2012

Yes, this makes sense. While it is a bit of a pain for people writing
magics, it is not too bad. I think the compromise makes sense if it
simplifies the implementation code, which it sounds like it does.

On Tue, May 15, 2012 at 10:14 PM, Fernando Perez
reply@reply.github.com
wrote:

@ellisonbg, sorry for not being clear enough: there's nothing to worry user-side, it's just that in order to implement a magic that can be used both as %f and %%f, we'll have to write a function with the signature

@line_cell_magic
def f(self, line, cell=None):
 if cell is None:
   do_line_stuff(line)
 else:
   do_line_and_cell_stuff(line, cell)

instead of being able to use separate implementations for the line-only and cell-only parts.  So I don't think it's a big deal.  I'll add this new decorator.

It's just that I'm finding I need to have a single namespace, so that a magic name X maps to only one function, whether it's line-only, cell-only or line-and-cell.  The management of truly disjoint line and cell namespaces was proving to be an ever-growing tangle of complexity.

Does that make sense?


Reply to this email directly or view it on GitHub:
#1732 (comment)

Brian E. Granger
Cal Poly State University, San Luis Obispo
bgranger@calpoly.edu and ellisonbg@gmail.com

Owner

minrk commented May 22, 2012

PR #1630 now touches the parallelmagic extension (silent keyword had to be added to run_cell), which will obviously conflict with this. The necessary change was quite tiny, but I included a fair amount of cleanup since that file gets neglected and had gone very stale (docstrings were simply wrong, and not updated since Twisted days, and the run_code override is entirely unnecessary). Should I rollback the cleanup, so resolving conflicts is easier, and doesn't add to the scale of this guy?

Owner

fperez commented May 22, 2012

Hey guys (esp. @ellisonbg & @minrk), this has proved to be a fair bit more time-consuming than I was hoping for, but there's now light at the end of the tunnel. At this point, I'm getting the full test suite to pass again (modulo an occasional zmq failure that I only see intermittently and never in isolation, and which is unrelated to magics, so I hope it will get fixed elsewhere).

Note that I still don't actually have the real %%cell syntax implemented, but now this branch again has (to the best of my knowledge) a fully working IPython again. So you can review all this code as a working unit.

I'll now focus on getting the actual cell syntax working. I think it should go comparatively quickly, considering that all the infrastructure is now in place. But I've learned to be cautious with this beast now, so no promises :) I'll work on that tomorrow.

Owner

fperez commented May 22, 2012

On Tue, May 22, 2012 at 12:29 AM, Min RK
reply@reply.github.com
wrote:

PR #1630 now touches the parallelmagic extension (silent keyword had to be added to run_cell), which will obviously conflict with this.  The necessary change was quite tiny, but I included a fair amount of cleanup since that file gets neglected and had gone very stale (docstrings were simply wrong, and not updated since Twisted days, and the run_code override is entirely unnecessary).  Should I rollback the cleanup, so resolving conflicts is easier, and doesn't add to the scale of this guy?

Sure, I'd appreciate that so we can knock this monster in one shot.
It should be easy to revisit it once we've merged this, and I'll be
happy to help out if needed.

Owner

fperez commented May 22, 2012

Mmh, I wonder why I got @minrk's reply via email but it doesn't show up here on the website. Weird.

Owner

minrk commented May 22, 2012

@fperez - I see my note just fine (I posted it on here shortly before your ping, it's not a reply to it).

Owner

minrk commented May 22, 2012

Okay, parallelmagic changes in #1630 are now restricted to adding silent kwarg in two places. I will open a separate PR totally rewriting that file after both of these are merged.

Owner

ellisonbg commented May 22, 2012

@fperez, OK do you think we should start to review your branch now or is it not quite ready?

I have been reviewing the mergekernel branch and am going to focus on code review. My branch is done until I can rebase on top of your two branches and finish a few things.

Owner

fperez commented May 22, 2012

@ellisonbg, go for it. There will be a few more commits with the actual implementation of the cell magics that I'm working on now, but those should be few. If you want to be able to see those in isolation, we can also make them a separate PR later today or tomorrow, in case you go through this in full. At least now this branch works in full and has what I think is the final architecture for magics, modulo missing actual %% cell-level ones.

Owner

ellisonbg commented May 22, 2012

OK I will start on the review...

On Tue, May 22, 2012 at 11:54 AM, Fernando Perez
reply@reply.github.com
wrote:

@ellisonbg, go for it.  There will be a few more commits with the actual implementation of the cell magics that I'm working on now, but those should be few.  If you want to be able to see those in isolation, we can also make them a separate PR later today or tomorrow, in case you go through this in full.  At least now this branch works in full and has what I think is the final architecture for magics, modulo missing actual %% cell-level ones.


Reply to this email directly or view it on GitHub:
#1732 (comment)

Brian E. Granger
Cal Poly State University, San Luis Obispo
bgranger@calpoly.edu and ellisonbg@gmail.com

Owner

ellisonbg commented May 24, 2012

So I just wrote a simple %%cython_inline magic that passes the cell content to Cython.inline. Here is a notebook that shows this:

https://gist.github.com/2779717

But I am running into a problem. Currently, the return value of a magic is discarded. This means there is no way of getting the result of a computation done in a cell magic back to the user. I think this is something we are going to run into a lot as magics get more complicated and interesting. Any thoughts on getting the return value back to the user? This could also show up if a magic function returns something that has an interesting representation that displayhook/pyout should pick up.

Owner

ellisonbg commented May 24, 2012

Here is another version of a %%cython magic that uses pyximport:

https://gist.github.com/2779875

I think this one is more useful.

Owner

ellisonbg commented May 24, 2012

I have noticed a common mistake that is not handled very well currently. I keep forgetting to put in the extra % for cell magics. So I will type %cython rather than %%cython. The error message you get in this case is pretty ugly. How should we handle this type of user mistake?

Owner

fperez commented May 24, 2012

Could you try pulling again? I've just made a bunch of changes while
you were reviewing...

IPython/core/magics/osm.py
+ /home/tsuser/parent/child
+ """
+
+ #bkms = self.shell.persist.get("bookmarks",{})
@certik

certik May 24, 2012

Why is this line here? It looks like a leftover from some refactoring?

@fperez

fperez May 24, 2012

Owner

Yup, good catch. Fixed locally, will push later today. Thanks!

IPython/core/magics/code.py
+ filename = make_filename(args)
+ datafile = 1
+ warn('Could not find file where `%s` is defined.\n'
+ 'Opening a file named `%s`' % (args,filename))
@certik

certik May 24, 2012

There should be a space after a comma ((args, filename)), to be consistent.

IPython/core/magics/code.py
+ filename = make_filename(args)
+ if filename is None:
+ warn('The file `%s` where `%s` was defined cannot '
+ 'be read.' % (filename,data))
@certik

certik May 24, 2012

Space after the comma.

IPython/core/magics/namespace.py
+ vdtype = var.dtype
+
+ if vbytes < 100000:
+ print aformat % (vshape,vsize,vdtype,vbytes)
@certik

certik May 24, 2012

Space after commas?

IPython/core/magics/namespace.py
+ if vbytes < 100000:
+ print aformat % (vshape,vsize,vdtype,vbytes)
+ else:
+ print aformat % (vshape,vsize,vdtype,vbytes),
IPython/core/magics/osm.py
+
+ if bkms.has_key(ps):
+ target = bkms[ps]
+ print '(bookmark:%s) -> %s' % (ps,target)
@certik

certik May 24, 2012

Space after comma.

IPython/core/magics/osm.py
+ split = 'l' in opts
+ out = self.shell.getoutput(cmd, split=split)
+ if opts.has_key('v'):
+ print '%s ==\n%s' % (var,pformat(out))
@certik

certik May 24, 2012

Space after comma.

IPython/core/magics/osm.py
+ fmt = '%-'+str(size)+'s -> %s'
+ print 'Current bookmarks:'
+ for bk in bks:
+ print fmt % (bk,bkms[bk])
@certik

certik May 24, 2012

Space after comma.

IPython/extensions/storemagic.py
+ for var in vars:
+ justkey = os.path.basename(var)
+ # print 30 first characters from every var
+ print fmt % (justkey,repr(get(var,'<unavailable>'))[:50])
@certik

certik May 24, 2012

Space after comma.

IPython/core/magics/auto.py
+ else:
+ arg = 'toggle'
+
+ if not arg in (0, 1, 2,'toggle'):
@certik

certik May 24, 2012

Space after the last comma?

IPython/core/magics/basic.py
+ mode = parameter_s.split()[0][1:]
+ if mode == 'rest':
+ rest_docs = []
+ except:
@certik

certik May 24, 2012

What exception is this code trying to catch? IndexError? It should be explicit. I think that a general "try/except" clause like this is a bad programming style.

@fperez

fperez May 26, 2012

Owner

fixed, it looks like an IndexError. Note that this, and the other things you noted above, are remnants of code written ~ 10 years ago, when I was learning python as I developed IPython. So it should be no surprise to see some pretty awful stuff here :) But thanks a ton for the review!

certik commented May 24, 2012

I noticed the general "try/except" clause at couple more places -- I think it should be made explicit what exact exception(s) you are trying to catch.

IPython/frontend/terminal/embed.py
- from contextlib import nested
-except:
- from IPython.utils.nested_context import nested
+from contextlib import nested
@takluyver

takluyver May 24, 2012

Owner

We need to have our fallback import here (and in interactiveshell.py), as nested() is gone in Python 3. Once we drop support for 2.6, we can use multiple contexts in a single with statement anyway, so we won't need it.

@fperez

fperez May 26, 2012

Owner

Good catch! Fixed here and in interactiveshell.py, and added a comment explaining this so it doesn't happen again.

IPython/core/history.py
- you ca set this value in each, so that they are consistent.
+ By default, IPython will put the history database in the IPython
+ profile directory. If you would rather share one history among
+ profiles, you ca set this value in each, so that they are consistent.
@Carreau

Carreau May 25, 2012

Owner

you *can * , and double space before If line above.

@fperez

fperez May 26, 2012

Owner

BTW, I left the double-space, as it was deliberate. When text is typed in monospaced fonts without automatic line justification (as is the case in code), I like using the tow-spaces-after-period rule, as I do find it more readable. This topic is actually hotly debated, but I think that in code that is never flush-justified and is almost exclusively read in monospaced fonts, it is indeed an improvement. This approximates the behavior of high-quality typographic software such as LaTeX when it justifies paragraphs. LaTeX makes the space after periods larger than the average inter-word spacing assigned to that line (by roughly a factor of 2x, as best I can tell by inspecting LaTeX-generated PDFs under high magnification).

In summary, I go with Knuth :)

@minrk

minrk May 26, 2012

Owner

The whole double-space 'debate' is entirely irrelevant to monospace. Typewriters (and monospaced text in general) are the reason the double-space rule came into being in the first place. The 'debate' is about applying a practice meant for monospace inappropriately to variable-width type.

@fperez

fperez May 26, 2012

Owner

That's what I was trying to say, I guess :)

@minrk

minrk May 26, 2012

Owner

Oops, sorry! Though it would apply to folks who code in Helvetica ( I know of at least one).

@fperez

fperez May 26, 2012

Owner

I know one too, I just can't fathom it...

@@ -55,7 +55,7 @@
* Brian Granger
"""
#-----------------------------------------------------------------------------
-# Copyright (C) 2010-2011 The IPython Development Team
+# Copyright (C) 2010 The IPython Development Team
@Carreau

Carreau May 25, 2012

Owner

copyright 2010 -> 2012 ?

@fperez

fperez May 26, 2012

Owner

No, we discussed it and agreed that it made most sense to leave only the original year and stop having to update ranges. So in fact I've been removing end years as I go.

fperez added some commits May 8, 2012

Simplify logic of passing local scope to magics that need it.
Just use an argument rather than setting more global state.
Fix remaining test failures.
This completes the decoupling of the Magic class from the main
InteractiveShell one.  Finally! (it's been only 10 1/2 years...)

At this point, all tests pass (modulo two failures in zmq that were
there before and are not related to the magics work).

We can now start the rest of the work for cell level magics, including
a cleaner magic management architecture and breaking them up into
several classes.
Major restructuring of magics, breaking them up into separate classes.
This is the first step to get the new magic architecture in place,
with a new base class for magic functions.

At this point IPython does *not* run, but the changes are extensive
enough to warrant intermediate non-working commits.
Separate magic code into base file and implementation of magics.
Ran a first solid pass with Pyflakes to clean the code.
Add all decorators to tag magics.
Now all magics are properly tagged with our decorators and the
registration machinery is also up.
Add proper initialization of magics to main shell instance.
Not everything works yet, but with this, at least IPython starts
correctly again.
Remove unnecessary metaclass and allow registration of magic classes.
This lets us register uninstantiated magic classes as well, making the
init logic a bit cleaner in the main shell class.
IPython/extensions/storemagic.py
+
+from IPython.core.error import UsageError
+from IPython.core.fakemodule import FakeModule
+from IPython.core.magic import Magics, magics_class, line_magic
from IPython.core.plugin import Plugin
@ellisonbg

ellisonbg May 26, 2012

Owner

Let's get rid of the Plugin usage in this module.

@fperez

fperez May 27, 2012

Owner

Mhh, I was about to, but reading the code I see that it does in fact have one configurable variable that controls behavior. That's one use for the plugin that we can't replicate if we simply load the magics in manually. I don't use this much myself, but there are bound to be users of the functionality, so I think we should leave it be in the interest of not causing unnecessary end-user breakage.

@@ -38,6 +37,8 @@ def setup():
IPYTHONDIR = tempfile.mkdtemp()
env = dict(IPYTHONDIR=IPYTHONDIR)
+ if 'PYTHONPATH' in os.environ:
+ env['PYTHONPATH'] = os.environ['PYTHONPATH']
save_get_ipython_dir = path.get_ipython_dir
@ellisonbg

ellisonbg May 26, 2012

Owner

Need to cover the case where PYTHONPATH is not in os.environ.

@fperez

fperez May 26, 2012

Owner

Yup, fixed already in 681e926.

Owner

ellisonbg commented May 26, 2012

OK I have done a pretty good review. Most of my comments are inline, but magic.py was too big for that so we are my comments for that module:

magic.py

Add minimal docstrings for:

  • compress_dhist
  • magics_class
  • record_magic
  • validate_type
  • _magic_marker
  • _function_magic_marker

L210: should auto_magic have a default?

L216: Is there any reason to single out user_magics from the perspective of the
MagicManager class? I think it would be cleaner to call the following the
the MagicManger is instantiated in InteractiveShell::

mman.register(UserMagics)

That will clean up the code in MagicManager.

L239: register is really a public method and should have a full docstring.
L258: register_function is a public method and should have a full docstring.
L269: same with define_magic, even though it is deprecated.

Owner

fperez commented May 26, 2012

Great, thanks for the review! I'll go through these and will report.

Owner

fperez commented May 26, 2012

Test results for commit 681e926 merged into master
Platform: linux2

  • python2.7: OK

Not available for testing:

Owner

ellisonbg commented May 26, 2012

The completion support looks great!

Owner

fperez commented May 26, 2012

Thanks :) I'm calling it a night, will do the rest tomorrow. Thanks again for the careful review!

Owner

fperez commented May 26, 2012

@takluyver, if you have a minute, I'd greatly appreciate your eagle python3 eyes over this one. It's really huge, and given that test_pr isn't working for me on python3, I'm a bit worried about potential crimes I may have committed against py3.

Owner

takluyver commented May 26, 2012

Test results for commit b29fa5a merged into master
Platform: linux2

Not available for testing: python2.6

Owner

takluyver commented May 26, 2012

From that test run, there's nothing major, just a couple of places where you need to apply IPython.utils.py3compat.u_format(). I'll try to have a closer look at the code later.

Owner

ellisonbg commented May 27, 2012

I am working on the Cython magics and am finding that the following syntax doesn't work %%cython? for getting the docstring of cell magics.

Owner

fperez commented May 27, 2012

@ellisonbg, thanks for the report. I'm working on all this, I'll take care of it.

Owner

ellisonbg commented May 27, 2012

OK great. I have the Cython magic extension done. Should I wait
until this is merged to create a PR for it against master?

On Sat, May 26, 2012 at 5:21 PM, Fernando Perez
reply@reply.github.com
wrote:

@ellisonbg, thanks for the report. I'm working on all this, I'll take care of it.


Reply to this email directly or view it on GitHub:
#1732 (comment)

Brian E. Granger
Cal Poly State University, San Luis Obispo
bgranger@calpoly.edu and ellisonbg@gmail.com

Owner

fperez commented May 27, 2012

Yes, I think we should do the Cython, R and other such high-value magics we may want to ship with IPython, as PRs of their own, so the discussion can focus on their features alone.

fperez added some commits May 27, 2012

Clarify that automagic is only for line magics.
Cell magics should always be explicitly prefixed.
Add support for finding cell magics with ?/??.
Note that this doesn't yet cover the case where '%%cellm?' is typed,
only the case without any '%' markers.
Owner

fperez commented May 27, 2012

@ellisonbg, I've added support for cellmagic?, but without the explicit %% markers yet. That will come next, but this should get you going for now with the cython workflow. Let me know if you spot any problems. Just type cython?/??, and it should work fine.

Owner

ellisonbg commented May 27, 2012

Yep, it works as expected.

Owner

fperez commented May 27, 2012

OK @ellisonbg, I got the rest of the help combinations working with the magic syntax, so give it a beating and let me know if anything breaks.

fperez added some commits May 27, 2012

Complete documenting magic module, as per review.
Added full docstrings to all methods and functions, and restored the
original docstring for the deprecated `define_magic` method.
Owner

fperez commented May 27, 2012

@ellisonbg, I've just completed the documentation as per your non-inline review of magic.py above; pushed. I'm going to add a bit more of explanatory text here and there, but we're getting close.

Owner

fperez commented May 27, 2012

@ellisonbg, I think I'm done with all the items you'd noted. I'm going to look into the py3 stuff now that @takluyver reported, and we should be good to go.

Fix test failures under Python 3.
Refactored the test code a bit for better reuse of common functionality.
Owner

fperez commented May 27, 2012

OK @takluyver, as best I can tell, I'm also in good shape with Python 3 now, I've applied the compat fix you indicated. Thanks for that review!

fperez added some commits May 27, 2012

Document cell magics in %magic.
%magic is our main interactive explanation of the magic system, so
it's a good place to explain the system.
Owner

fperez commented May 27, 2012

I've just completed the documentation and added %%timeit as an example of a function that works both as line and cell magic. I'm going to do another pass over the whole thing, but unless anyone spots any more issues, this can go in as far as I'm concerned.

Owner

ellisonbg commented May 27, 2012

Great, merge away!

Sent from my iPad

On May 26, 2012, at 9:41 PM, Fernando Perezreply@reply.github.com wrote:

I've just completed the documentation and added %%timeit as an example of a function that works both as line and cell magic. I'm going to do another pass over the whole thing, but unless anyone spots any more issues, this can go in.


Reply to this email directly or view it on GitHub:
#1732 (comment)

Owner

fperez commented May 27, 2012

I've also added %%prun, which was easy and which I figured I'd want right away.

Update the main documentation with new magics API.
Added detailed description to the docs, as well as comprehensive
examples of magic creation with the new APIs.
Owner

fperez commented May 27, 2012

OK, I've added a bunch of documentation to the actual manual, with detailed examples. Last round of tests, and this goes in...

Owner

fperez commented May 27, 2012

Test results for commit 0876e92 (can't merge cleanly)
Platform: linux2

  • python2.7: OK
  • python3.2: OK (libraries not available: matplotlib pymongo qt tornado wx wx.aui zmq)

Not available for testing:

Owner

fperez commented May 27, 2012

Mmh, I'm not sure why test_pr said above it wouldn't merge cleanly, because it does. Things are looking pretty solid on both 2 and 3, so I'll go ahead and merge now. This is blocking too much stuff, we can (and will) continue to polish on master.

fperez added a commit that referenced this pull request May 27, 2012

Merge pull request #1732 from fperez/cellmagics
Refactoring of the magics system and implementation of cell magics.

This PR completely refactors the magic system, finally moving the magic objects to standalone, independent objects instead of being the mixin class we'd had since the beginning of IPython.  Now, a separate base class is provided in IPython.core.magic.Magics that users can subclass to create their own magics.  Decorators are also provided to create magics from simple functions without the need for object orientation.

All builtin magics now exist in a few subclasses that group together related functionality, and the new IPython.core.magics package has been created to organize this into smaller files.

This cleanup was the last major piece of deep refactoring needed from the original 2001 codebase.

Secondly, this PR introduces a new type of magic function, prefixed with `%%` instead of `%`, which operates at the cell level.  A cell magic receives two arguments: the line it is called on (like a line magic) and the body of the cell below it.

Cell magics are most natural in the notebook, but they also work in the terminal and qt console, with the usual approach of using a blank line to signal cell termination.

This PR closes #1611, or IPEP 1, where the design had been discussed.

@fperez fperez merged commit 61eb2ff into ipython:master May 27, 2012

Owner

takluyver commented May 27, 2012

test_pr examines the 'mergeable' field when it queries the Github API for the pull request. If we see it making a mistake again, I'll check that - it's possible that Github is misreporting it after a rebase, for instance.

Kudos for getting this done. Sorry I didn't have more time to look into it, but I'll do a bit of manual Python 3 testing now.

Owner

takluyver commented May 27, 2012

One small flaw I've noticed: if you start the Qt console, and type %ti<TAB>, it shows the new %%timeit as an option for tab completion, but it reduces the command at the prompt to the longest common prefix, which is now just %. It ought to be smarter about that. (This isn't specific to Python 3)

Owner

takluyver commented May 27, 2012

Everything I've tried with it in Python 3.2 works perfectly.

Owner

Carreau commented May 27, 2012

On Sun, May 27, 2012 at 11:40 AM, Thomas Kluyver <
reply@reply.github.com

wrote:

test_pr examines the 'mergeable' field when it queries the Github API for
the pull request. If we see it making a mistake again, I'll check that -
it's possible that Github is misreporting it after a rebase, for instance.

I've seen that sometime, and for me it seems that gihub api result is
updated only when the PR webpage is opened and the green button 'check'
that the pr is mergeable.

Kudos for getting this done. Sorry I didn't have more time to look into
it, but I'll do a bit of manual Python 3 testing now.


Reply to this email directly or view it on GitHub:
#1732 (comment)

Owner

takluyver commented May 27, 2012

On 27 May 2012 13:00, Bussonnier Matthias
reply@reply.github.com
wrote:

I've seen that sometime, and for me it seems that gihub api result is
updated only when the PR webpage is opened and the green button 'check'
that the pr is mergeable.

Ah, that could well be it. We'll keep an eye out for it, and if that
is the case, we'll drop github a line.

Owner

fperez commented May 27, 2012

@takluyver, thanks for catching the completion problem. Opened now as #1767.

@Carreau Carreau referenced this pull request May 29, 2012

Merged

restore loadpy to load #1784

fperez added a commit that referenced this pull request May 29, 2012

Merge pull request #1784 from Carreau/loadpycat2
Restore loadpy to load. 

closes #1783, just the part of #1606 eaten by #1732, where some code was accidentally removed.

certik commented May 30, 2012

Great job!

mattvonrocketstein pushed a commit to mattvonrocketstein/ipython that referenced this pull request Nov 3, 2014

Merge pull request #1732 from fperez/cellmagics
Refactoring of the magics system and implementation of cell magics.

This PR completely refactors the magic system, finally moving the magic objects to standalone, independent objects instead of being the mixin class we'd had since the beginning of IPython.  Now, a separate base class is provided in IPython.core.magic.Magics that users can subclass to create their own magics.  Decorators are also provided to create magics from simple functions without the need for object orientation.

All builtin magics now exist in a few subclasses that group together related functionality, and the new IPython.core.magics package has been created to organize this into smaller files.

This cleanup was the last major piece of deep refactoring needed from the original 2001 codebase.

Secondly, this PR introduces a new type of magic function, prefixed with `%%` instead of `%`, which operates at the cell level.  A cell magic receives two arguments: the line it is called on (like a line magic) and the body of the cell below it.

Cell magics are most natural in the notebook, but they also work in the terminal and qt console, with the usual approach of using a blank line to signal cell termination.

This PR closes #1611, or IPEP 1, where the design had been discussed.

mattvonrocketstein pushed a commit to mattvonrocketstein/ipython that referenced this pull request Nov 3, 2014

Merge pull request #1784 from Carreau/loadpycat2
Restore loadpy to load. 

closes #1783, just the part of #1606 eaten by #1732, where some code was accidentally removed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment