auto.py
144 lines
| 4.7 KiB
| text/x-python
|
PythonLexer
Fernando Perez
|
r6965 | """Implementation of magic functions that control various automatic behaviors. | ||
Fernando Perez
|
r6964 | """ | ||
#----------------------------------------------------------------------------- | ||||
# Copyright (c) 2012 The IPython Development Team. | ||||
# | ||||
# Distributed under the terms of the Modified BSD License. | ||||
# | ||||
# The full license is in the file COPYING.txt, distributed with this software. | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
# Our own packages | ||||
Fernando Perez
|
r6973 | from IPython.core.magic import Bunch, Magics, magics_class, line_magic | ||
Fernando Perez
|
r6964 | from IPython.testing.skipdoctest import skip_doctest | ||
Pierre Gerold
|
r22092 | from logging import error | ||
Fernando Perez
|
r6964 | |||
#----------------------------------------------------------------------------- | ||||
# Magic implementation classes | ||||
#----------------------------------------------------------------------------- | ||||
Fernando Perez
|
r6973 | @magics_class | ||
Fernando Perez
|
r6964 | class AutoMagics(Magics): | ||
"""Magics that control various autoX behaviors.""" | ||||
def __init__(self, shell): | ||||
super(AutoMagics, self).__init__(shell) | ||||
# namespace for holding state we may need | ||||
self._magic_state = Bunch() | ||||
@line_magic | ||||
def automagic(self, parameter_s=''): | ||||
"""Make magic functions callable without having to type the initial %. | ||||
Steven Maude
|
r23873 | Without arguments toggles on/off (when off, you must call it as | ||
Fernando Perez
|
r6964 | %automagic, of course). With arguments it sets the value, and you can | ||
use any of (case insensitive): | ||||
- on, 1, True: to activate | ||||
- off, 0, False: to deactivate. | ||||
Note that magic functions have lowest priority, so if there's a | ||||
variable whose name collides with that of a magic fn, automagic won't | ||||
work for that function (you get the variable instead). However, if you | ||||
delete the variable (del var), the previously shadowed magic function | ||||
becomes visible to automagic again.""" | ||||
arg = parameter_s.lower() | ||||
mman = self.shell.magics_manager | ||||
if arg in ('on', '1', 'true'): | ||||
val = True | ||||
elif arg in ('off', '0', 'false'): | ||||
val = False | ||||
else: | ||||
val = not mman.auto_magic | ||||
mman.auto_magic = val | ||||
Thomas Kluyver
|
r13348 | print('\n' + self.shell.magics_manager.auto_status()) | ||
Fernando Perez
|
r6964 | |||
@skip_doctest | ||||
@line_magic | ||||
def autocall(self, parameter_s=''): | ||||
"""Make functions callable without having to type parentheses. | ||||
Usage: | ||||
%autocall [mode] | ||||
The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the | ||||
value is toggled on and off (remembering the previous state). | ||||
In more detail, these values mean: | ||||
0 -> fully disabled | ||||
1 -> active, but do not apply if there are no arguments on the line. | ||||
In this mode, you get:: | ||||
In [1]: callable | ||||
Out[1]: <built-in function callable> | ||||
In [2]: callable 'hello' | ||||
------> callable('hello') | ||||
Out[2]: False | ||||
2 -> Active always. Even if no arguments are present, the callable | ||||
object is called:: | ||||
In [2]: float | ||||
------> float() | ||||
Out[2]: 0.0 | ||||
Note that even with autocall off, you can still use '/' at the start of | ||||
a line to treat the first argument on the command line as a function | ||||
and add parentheses to it:: | ||||
In [8]: /str 43 | ||||
------> str(43) | ||||
Out[8]: '43' | ||||
# all-random (note for auto-testing) | ||||
""" | ||||
Lightyagami1
|
r26591 | valid_modes = { | ||
0: "Off", | ||||
1: "Smart", | ||||
2: "Full", | ||||
} | ||||
def errorMessage() -> str: | ||||
error = "Valid modes: " | ||||
for k, v in valid_modes.items(): | ||||
error += str(k) + "->" + v + ", " | ||||
error = error[:-2] # remove tailing `, ` after last element | ||||
return error | ||||
Fernando Perez
|
r6964 | if parameter_s: | ||
Lightyagami1
|
r26591 | if not parameter_s in map(str, valid_modes.keys()): | ||
error(errorMessage()) | ||||
return | ||||
Fernando Perez
|
r6964 | arg = int(parameter_s) | ||
else: | ||||
arg = 'toggle' | ||||
Lightyagami1
|
r26591 | if not arg in (*list(valid_modes.keys()), "toggle"): | ||
error(errorMessage()) | ||||
Fernando Perez
|
r6964 | return | ||
Lightyagami1
|
r26591 | if arg in (valid_modes.keys()): | ||
Fernando Perez
|
r6964 | self.shell.autocall = arg | ||
else: # toggle | ||||
if self.shell.autocall: | ||||
self._magic_state.autocall_save = self.shell.autocall | ||||
self.shell.autocall = 0 | ||||
else: | ||||
try: | ||||
self.shell.autocall = self._magic_state.autocall_save | ||||
except AttributeError: | ||||
self.shell.autocall = self._magic_state.autocall_save = 1 | ||||
Lightyagami1
|
r26591 | print("Automatic calling is:", list(valid_modes.values())[self.shell.autocall]) | ||