Decorator factory for methods in Magics subclasses.
(
magic_kind: _MagicSpec,
)
| 192 | |
| 193 | |
| 194 | def _method_magic_marker( |
| 195 | magic_kind: _MagicSpec, |
| 196 | ) -> Callable[[_F | str], _F | Callable[[_F], _F]]: |
| 197 | """Decorator factory for methods in Magics subclasses.""" |
| 198 | |
| 199 | validate_type(magic_kind) |
| 200 | |
| 201 | # This is a closure to capture the magic_kind. We could also use a class, |
| 202 | # but it's overkill for just that one bit of state. |
| 203 | def magic_deco(arg: _F | str) -> _F | Callable[[_F], _F]: |
| 204 | retval: _F | Callable[[_F], _F] |
| 205 | if callable(arg): |
| 206 | # "Naked" decorator call (just @foo, no args) |
| 207 | func = arg |
| 208 | name = func.__name__ |
| 209 | retval = arg |
| 210 | record_magic(magics, magic_kind, name, name) |
| 211 | elif isinstance(arg, str): |
| 212 | # Decorator called with arguments (@foo('bar')) |
| 213 | name = arg |
| 214 | |
| 215 | def mark(func: _F, *a: Any, **kw: Any) -> _F: |
| 216 | record_magic(magics, magic_kind, name, func.__name__) |
| 217 | return func |
| 218 | |
| 219 | retval = mark |
| 220 | else: |
| 221 | raise TypeError("Decorator can only be called with string or function") |
| 222 | return retval |
| 223 | |
| 224 | # Ensure the resulting decorator has a usable docstring |
| 225 | magic_deco.__doc__ = _docstring_template.format("method", magic_kind) |
| 226 | return magic_deco |
| 227 | |
| 228 | |
| 229 | def _function_magic_marker( |
no test coverage detected
searching dependent graphs…