Skip to content


Subversion checkout URL

You can clone with
Download ZIP


#342: Try to recover as intelligently as possible if user calls magic(). #352

wants to merge 3 commits into from

2 participants


This was annoying me from the perspective of force-of-habit typing quit() (system install at the lab of IPython 0.8.3 (!!!!!) requires it) but in general, people typing some_magic() with automagic on and expecting results might be awfully surprised by the NameError that results.

This attempts to address the problem in the following way:

  • Check if whatever precedes the first paren in line_info.ifun is a magic, and of course is not shadowed by something in the user namespace
  • Throw out everything after the first paren, as well as the contents of line_info.the_rest (trying to sensibly convert function call syntax to magic-calling syntax in a general way doesn't seem prudent or possible)
  • Visually rewrite as ----> %some_magic so that the user has some clue that what he typed was interpreted as a magic but that the subsequent parenthesized arguments were ignored.

The result looks something like this:

In [6]: quit(5, 4, 3)
------> %quit

Ideally then, individual magics, if they require arguments, will complain about not receiving them, and in the process demonstrate their usage with the correct %foo bar baz way of calling them.

This pull request replaces #345.


How is this pull related to #345?


How is this pull related to #345?

It replaces it and solves the problem more generally. I meant to close the old pull request and in fact clicked the button to do so but was apparently the victim of a network hiccup. The Canadian inter-tubes are still thawing out from the winter, I guess...


OK, looking at the code I think I understand better. But I'm not convinced we should add more input handling logic of this kind. Basically, I think if someone types foo(), then they mean a python call, not a magic. Granted, it may take a little bit to realize that ipython offers two overlapping systems, one for "commands" (magics) and one for pure python code, but anyone using a tool like ipython should figure that out pretty quickly.

Now, as for #342, I think we can address that one slightly differently, but I need to play with some ideas.

But I'm reluctant to add even more text input special-casing, as much of our code on that front is already fairly brittle. What do you think?


BTW, I'm on IRC (freenode, #ipython) if you want to chat live on these two for a moment... That may be more efficient.


I'm not entirely sure, either. @tk suggested that magic() ought to map to %magic for more than just %quit and %exit, and I went further with magic(...) mapping to %magic, but that last step might be too far.

I'll hop on IRC, just need to download a client on this machine. :)


After discussing it with Fernando it was decided this was overkill, and #352 will be reopened.

@dwf dwf closed this
@damianavila damianavila referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
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 16 additions and 2 deletions.
  1. +16 −2 IPython/core/
18 IPython/core/
@@ -688,14 +688,19 @@ def check(self, line_info):
check_esc_chars. This just checks for automagic. Also, before
triggering the magic handler, make sure that there is nothing in the
user namespace which could shadow it."""
- if not or not hasattr(,'magic_'+line_info.ifun):
+ ifun = line_info.ifun
+ # Try to recover if someone mistakenly tries to call quit(),
+ # exit(), Exit(), guiref()... magicname plus paren...
+ is_magic_w_paren = hasattr(, 'magic_' + ifun.split('(', 1)[0])
+ if not or (not hasattr(,'magic_'+ifun)
+ and not is_magic_w_paren):
return None
# We have a likely magic method. Make sure we should actually call it.
if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
return None
- head = line_info.ifun.split('.',1)[0]
+ head = ifun.split('(', 1)[0].split('.',1)[0]
if is_shadowed(head,
return None
@@ -869,6 +874,15 @@ def handle(self, line_info):
"""Execute magic functions."""
ifun = line_info.ifun
the_rest = line_info.the_rest
+ # Try to accomodate magic calls with erroneous parens
+ if '(' in ifun:
+ ifun = ifun.split('(', 1)[0]
+ # Just ignore anything after the open paren. The auto_rewrite_input
+ # will make clear that the input was rewritten, and individual
+ # magics should print a useful error message that show how to call.
+ the_rest = ''
+ + ifun)
cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace,
make_quoted_expr(ifun + " " + the_rest))
return cmd
Something went wrong with that request. Please try again.