Show More
@@ -104,7 +104,40 b' def validate_type(magic_kind):' | |||
|
104 | 104 | magic_kinds, magic_kind) |
|
105 | 105 | |
|
106 | 106 | |
|
107 | def _magic_marker(magic_kind): | |
|
107 | # The docstrings for the decorator below will be fairly similar for the two | |
|
108 | # types (method and function), so we generate them here once and reuse the | |
|
109 | # templates below. | |
|
110 | _docstring_template = \ | |
|
111 | """Decorate the given {0} as {1} magic. | |
|
112 | ||
|
113 | The decorator can be used: | |
|
114 | ||
|
115 | i) without arguments: it will create a {1} magic named as the {0} being | |
|
116 | decorated:: | |
|
117 | ||
|
118 | @deco | |
|
119 | def foo(...) | |
|
120 | ||
|
121 | will create a {1} magic named `foo`. | |
|
122 | ||
|
123 | ii) with one string argument: which will be used as the actual name of the | |
|
124 | resulting magic:: | |
|
125 | ||
|
126 | @deco('bar') | |
|
127 | def foo(...) | |
|
128 | ||
|
129 | will create a {1} magic named `bar`. | |
|
130 | """ | |
|
131 | ||
|
132 | # These two are decorator factories. While they are conceptually very similar, | |
|
133 | # there are enough differences in the details that it's simpler to have them | |
|
134 | # written as completely standalone functions rather than trying to share code | |
|
135 | # and make a single one with convoluted logic. | |
|
136 | ||
|
137 | def _method_magic_marker(magic_kind): | |
|
138 | """Decorator factory for methods in Magics subclasses. | |
|
139 | """ | |
|
140 | ||
|
108 | 141 | validate_type(magic_kind) |
|
109 | 142 | |
|
110 | 143 | # This is a closure to capture the magic_kind. We could also use a class, |
@@ -116,14 +149,12 b' def _magic_marker(magic_kind):' | |||
|
116 | 149 | # "Naked" decorator call (just @foo, no args) |
|
117 | 150 | func = arg |
|
118 | 151 | name = func.func_name |
|
119 | func.magic_name = name | |
|
120 | 152 | retval = decorator(call, func) |
|
121 | 153 | record_magic(magics, magic_kind, name, name) |
|
122 | 154 | elif isinstance(arg, basestring): |
|
123 | 155 | # Decorator called with arguments (@foo('bar')) |
|
124 | 156 | name = arg |
|
125 | 157 | def mark(func, *a, **kw): |
|
126 | func.magic_name = name | |
|
127 | 158 | record_magic(magics, magic_kind, name, func.func_name) |
|
128 | 159 | return decorator(call, func) |
|
129 | 160 | retval = mark |
@@ -132,12 +163,17 b' def _magic_marker(magic_kind):' | |||
|
132 | 163 | "string or function") |
|
133 | 164 | return retval |
|
134 | 165 | |
|
166 | # Ensure the resulting decorator has a usable docstring | |
|
167 | magic_deco.__doc__ = _docstring_template.format('method', magic_kind) | |
|
135 | 168 | return magic_deco |
|
136 | 169 | |
|
137 | 170 | |
|
138 | 171 | def _function_magic_marker(magic_kind): |
|
172 | """Decorator factory for standalone functions. | |
|
173 | """ | |
|
174 | ||
|
139 | 175 | validate_type(magic_kind) |
|
140 | ||
|
176 | ||
|
141 | 177 | # This is a closure to capture the magic_kind. We could also use a class, |
|
142 | 178 | # but it's overkill for just that one bit of state. |
|
143 | 179 | def magic_deco(arg): |
@@ -172,15 +208,17 b' def _function_magic_marker(magic_kind):' | |||
|
172 | 208 | "string or function") |
|
173 | 209 | return retval |
|
174 | 210 | |
|
211 | # Ensure the resulting decorator has a usable docstring | |
|
212 | magic_deco.__doc__ = _docstring_template.format('function', magic_kind) | |
|
175 | 213 | return magic_deco |
|
176 | 214 | |
|
177 | 215 | |
|
178 | 216 | # Create the actual decorators for public use |
|
179 | 217 | |
|
180 | 218 | # These three are used to decorate methods in class definitions |
|
181 | line_magic = _magic_marker('line') | |
|
182 | cell_magic = _magic_marker('cell') | |
|
183 | line_cell_magic = _magic_marker('line_cell') | |
|
219 | line_magic = _method_magic_marker('line') | |
|
220 | cell_magic = _method_magic_marker('cell') | |
|
221 | line_cell_magic = _method_magic_marker('line_cell') | |
|
184 | 222 | |
|
185 | 223 | # These three decorate standalone functions and perform the decoration |
|
186 | 224 | # immediately. They can only run where get_ipython() works |
General Comments 0
You need to be logged in to leave comments.
Login now