Show More
@@ -1,128 +1,144 b'' | |||||
1 | """Implementation of magic functions that control various automatic behaviors. |
|
1 | """Implementation of magic functions that control various automatic behaviors. | |
2 | """ |
|
2 | """ | |
3 | #----------------------------------------------------------------------------- |
|
3 | #----------------------------------------------------------------------------- | |
4 | # Copyright (c) 2012 The IPython Development Team. |
|
4 | # Copyright (c) 2012 The IPython Development Team. | |
5 | # |
|
5 | # | |
6 | # Distributed under the terms of the Modified BSD License. |
|
6 | # Distributed under the terms of the Modified BSD License. | |
7 | # |
|
7 | # | |
8 | # The full license is in the file COPYING.txt, distributed with this software. |
|
8 | # The full license is in the file COPYING.txt, distributed with this software. | |
9 | #----------------------------------------------------------------------------- |
|
9 | #----------------------------------------------------------------------------- | |
10 |
|
10 | |||
11 | #----------------------------------------------------------------------------- |
|
11 | #----------------------------------------------------------------------------- | |
12 | # Imports |
|
12 | # Imports | |
13 | #----------------------------------------------------------------------------- |
|
13 | #----------------------------------------------------------------------------- | |
14 |
|
14 | |||
15 | # Our own packages |
|
15 | # Our own packages | |
16 | from IPython.core.magic import Bunch, Magics, magics_class, line_magic |
|
16 | from IPython.core.magic import Bunch, Magics, magics_class, line_magic | |
17 | from IPython.testing.skipdoctest import skip_doctest |
|
17 | from IPython.testing.skipdoctest import skip_doctest | |
18 | from logging import error |
|
18 | from logging import error | |
19 |
|
19 | |||
20 | #----------------------------------------------------------------------------- |
|
20 | #----------------------------------------------------------------------------- | |
21 | # Magic implementation classes |
|
21 | # Magic implementation classes | |
22 | #----------------------------------------------------------------------------- |
|
22 | #----------------------------------------------------------------------------- | |
23 |
|
23 | |||
24 | @magics_class |
|
24 | @magics_class | |
25 | class AutoMagics(Magics): |
|
25 | class AutoMagics(Magics): | |
26 | """Magics that control various autoX behaviors.""" |
|
26 | """Magics that control various autoX behaviors.""" | |
27 |
|
27 | |||
28 | def __init__(self, shell): |
|
28 | def __init__(self, shell): | |
29 | super(AutoMagics, self).__init__(shell) |
|
29 | super(AutoMagics, self).__init__(shell) | |
30 | # namespace for holding state we may need |
|
30 | # namespace for holding state we may need | |
31 | self._magic_state = Bunch() |
|
31 | self._magic_state = Bunch() | |
32 |
|
32 | |||
33 | @line_magic |
|
33 | @line_magic | |
34 | def automagic(self, parameter_s=''): |
|
34 | def automagic(self, parameter_s=''): | |
35 | """Make magic functions callable without having to type the initial %. |
|
35 | """Make magic functions callable without having to type the initial %. | |
36 |
|
36 | |||
37 | Without arguments toggles on/off (when off, you must call it as |
|
37 | Without arguments toggles on/off (when off, you must call it as | |
38 | %automagic, of course). With arguments it sets the value, and you can |
|
38 | %automagic, of course). With arguments it sets the value, and you can | |
39 | use any of (case insensitive): |
|
39 | use any of (case insensitive): | |
40 |
|
40 | |||
41 | - on, 1, True: to activate |
|
41 | - on, 1, True: to activate | |
42 |
|
42 | |||
43 | - off, 0, False: to deactivate. |
|
43 | - off, 0, False: to deactivate. | |
44 |
|
44 | |||
45 | Note that magic functions have lowest priority, so if there's a |
|
45 | Note that magic functions have lowest priority, so if there's a | |
46 | variable whose name collides with that of a magic fn, automagic won't |
|
46 | variable whose name collides with that of a magic fn, automagic won't | |
47 | work for that function (you get the variable instead). However, if you |
|
47 | work for that function (you get the variable instead). However, if you | |
48 | delete the variable (del var), the previously shadowed magic function |
|
48 | delete the variable (del var), the previously shadowed magic function | |
49 | becomes visible to automagic again.""" |
|
49 | becomes visible to automagic again.""" | |
50 |
|
50 | |||
51 | arg = parameter_s.lower() |
|
51 | arg = parameter_s.lower() | |
52 | mman = self.shell.magics_manager |
|
52 | mman = self.shell.magics_manager | |
53 | if arg in ('on', '1', 'true'): |
|
53 | if arg in ('on', '1', 'true'): | |
54 | val = True |
|
54 | val = True | |
55 | elif arg in ('off', '0', 'false'): |
|
55 | elif arg in ('off', '0', 'false'): | |
56 | val = False |
|
56 | val = False | |
57 | else: |
|
57 | else: | |
58 | val = not mman.auto_magic |
|
58 | val = not mman.auto_magic | |
59 | mman.auto_magic = val |
|
59 | mman.auto_magic = val | |
60 | print('\n' + self.shell.magics_manager.auto_status()) |
|
60 | print('\n' + self.shell.magics_manager.auto_status()) | |
61 |
|
61 | |||
62 | @skip_doctest |
|
62 | @skip_doctest | |
63 | @line_magic |
|
63 | @line_magic | |
64 | def autocall(self, parameter_s=''): |
|
64 | def autocall(self, parameter_s=''): | |
65 | """Make functions callable without having to type parentheses. |
|
65 | """Make functions callable without having to type parentheses. | |
66 |
|
66 | |||
67 | Usage: |
|
67 | Usage: | |
68 |
|
68 | |||
69 | %autocall [mode] |
|
69 | %autocall [mode] | |
70 |
|
70 | |||
71 | The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the |
|
71 | The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the | |
72 | value is toggled on and off (remembering the previous state). |
|
72 | value is toggled on and off (remembering the previous state). | |
73 |
|
73 | |||
74 | In more detail, these values mean: |
|
74 | In more detail, these values mean: | |
75 |
|
75 | |||
76 | 0 -> fully disabled |
|
76 | 0 -> fully disabled | |
77 |
|
77 | |||
78 | 1 -> active, but do not apply if there are no arguments on the line. |
|
78 | 1 -> active, but do not apply if there are no arguments on the line. | |
79 |
|
79 | |||
80 | In this mode, you get:: |
|
80 | In this mode, you get:: | |
81 |
|
81 | |||
82 | In [1]: callable |
|
82 | In [1]: callable | |
83 | Out[1]: <built-in function callable> |
|
83 | Out[1]: <built-in function callable> | |
84 |
|
84 | |||
85 | In [2]: callable 'hello' |
|
85 | In [2]: callable 'hello' | |
86 | ------> callable('hello') |
|
86 | ------> callable('hello') | |
87 | Out[2]: False |
|
87 | Out[2]: False | |
88 |
|
88 | |||
89 | 2 -> Active always. Even if no arguments are present, the callable |
|
89 | 2 -> Active always. Even if no arguments are present, the callable | |
90 | object is called:: |
|
90 | object is called:: | |
91 |
|
91 | |||
92 | In [2]: float |
|
92 | In [2]: float | |
93 | ------> float() |
|
93 | ------> float() | |
94 | Out[2]: 0.0 |
|
94 | Out[2]: 0.0 | |
95 |
|
95 | |||
96 | Note that even with autocall off, you can still use '/' at the start of |
|
96 | Note that even with autocall off, you can still use '/' at the start of | |
97 | a line to treat the first argument on the command line as a function |
|
97 | a line to treat the first argument on the command line as a function | |
98 | and add parentheses to it:: |
|
98 | and add parentheses to it:: | |
99 |
|
99 | |||
100 | In [8]: /str 43 |
|
100 | In [8]: /str 43 | |
101 | ------> str(43) |
|
101 | ------> str(43) | |
102 | Out[8]: '43' |
|
102 | Out[8]: '43' | |
103 |
|
103 | |||
104 | # all-random (note for auto-testing) |
|
104 | # all-random (note for auto-testing) | |
105 | """ |
|
105 | """ | |
106 |
|
106 | |||
|
107 | valid_modes = { | |||
|
108 | 0: "Off", | |||
|
109 | 1: "Smart", | |||
|
110 | 2: "Full", | |||
|
111 | } | |||
|
112 | ||||
|
113 | def errorMessage() -> str: | |||
|
114 | error = "Valid modes: " | |||
|
115 | for k, v in valid_modes.items(): | |||
|
116 | error += str(k) + "->" + v + ", " | |||
|
117 | error = error[:-2] # remove tailing `, ` after last element | |||
|
118 | return error | |||
|
119 | ||||
107 | if parameter_s: |
|
120 | if parameter_s: | |
|
121 | if not parameter_s in map(str, valid_modes.keys()): | |||
|
122 | error(errorMessage()) | |||
|
123 | return | |||
108 | arg = int(parameter_s) |
|
124 | arg = int(parameter_s) | |
109 | else: |
|
125 | else: | |
110 | arg = 'toggle' |
|
126 | arg = 'toggle' | |
111 |
|
127 | |||
112 |
if not arg in ( |
|
128 | if not arg in (*list(valid_modes.keys()), "toggle"): | |
113 | error('Valid modes: (0->Off, 1->Smart, 2->Full') |
|
129 | error(errorMessage()) | |
114 | return |
|
130 | return | |
115 |
|
131 | |||
116 |
if arg in ( |
|
132 | if arg in (valid_modes.keys()): | |
117 | self.shell.autocall = arg |
|
133 | self.shell.autocall = arg | |
118 | else: # toggle |
|
134 | else: # toggle | |
119 | if self.shell.autocall: |
|
135 | if self.shell.autocall: | |
120 | self._magic_state.autocall_save = self.shell.autocall |
|
136 | self._magic_state.autocall_save = self.shell.autocall | |
121 | self.shell.autocall = 0 |
|
137 | self.shell.autocall = 0 | |
122 | else: |
|
138 | else: | |
123 | try: |
|
139 | try: | |
124 | self.shell.autocall = self._magic_state.autocall_save |
|
140 | self.shell.autocall = self._magic_state.autocall_save | |
125 | except AttributeError: |
|
141 | except AttributeError: | |
126 | self.shell.autocall = self._magic_state.autocall_save = 1 |
|
142 | self.shell.autocall = self._magic_state.autocall_save = 1 | |
127 |
|
143 | |||
128 |
print("Automatic calling is:", |
|
144 | print("Automatic calling is:", list(valid_modes.values())[self.shell.autocall]) |
General Comments 0
You need to be logged in to leave comments.
Login now