Show More
@@ -452,6 +452,36 b' class MagicsManager(Configurable):' | |||||
452 | setattr(self.user_magics, name, meth) |
|
452 | setattr(self.user_magics, name, meth) | |
453 | record_magic(self.magics, 'line', name, meth) |
|
453 | record_magic(self.magics, 'line', name, meth) | |
454 |
|
454 | |||
|
455 | def register_alias(self, alias_name, magic_name, magic_kind='line'): | |||
|
456 | """Register an alias to a magic function. | |||
|
457 | ||||
|
458 | The alias is an instance of :class:`MagicAlias`, which holds the | |||
|
459 | name and kind of the magic it should call. Binding is done at | |||
|
460 | call time, so if the underlying magic function is changed the alias | |||
|
461 | will call the new function. | |||
|
462 | ||||
|
463 | Parameters | |||
|
464 | ---------- | |||
|
465 | alias_name : str | |||
|
466 | The name of the magic to be registered. | |||
|
467 | ||||
|
468 | magic_name : str | |||
|
469 | The name of an existing magic. | |||
|
470 | ||||
|
471 | magic_kind : str | |||
|
472 | Kind of magic, one of 'line' or 'cell' | |||
|
473 | """ | |||
|
474 | ||||
|
475 | # `validate_type` is too permissive, as it allows 'line_cell' | |||
|
476 | # which we do not handle. | |||
|
477 | if magic_kind not in magic_kinds: | |||
|
478 | raise ValueError('magic_kind must be one of %s, %s given' % | |||
|
479 | magic_kinds, magic_kind) | |||
|
480 | ||||
|
481 | alias = MagicAlias(self.shell, magic_name, magic_kind) | |||
|
482 | setattr(self.user_magics, alias_name, alias) | |||
|
483 | record_magic(self.magics, magic_kind, alias_name, alias) | |||
|
484 | ||||
455 | # Key base class that provides the central functionality for magics. |
|
485 | # Key base class that provides the central functionality for magics. | |
456 |
|
486 | |||
457 | class Magics(object): |
|
487 | class Magics(object): | |
@@ -615,3 +645,45 b' class Magics(object):' | |||||
615 | if fn not in self.lsmagic(): |
|
645 | if fn not in self.lsmagic(): | |
616 | error("%s is not a magic function" % fn) |
|
646 | error("%s is not a magic function" % fn) | |
617 | self.options_table[fn] = optstr |
|
647 | self.options_table[fn] = optstr | |
|
648 | ||||
|
649 | class MagicAlias(object): | |||
|
650 | """Store a magic alias. | |||
|
651 | ||||
|
652 | An alias is determined by its magic name and magic kind. Lookup | |||
|
653 | is done at call time, so if the underlying magic changes the alias | |||
|
654 | will call the new function. | |||
|
655 | ||||
|
656 | Use the :meth:`MagicsManager.register_alias` method or the | |||
|
657 | `%alias_magic` magic function to create and register a new alias. | |||
|
658 | """ | |||
|
659 | def __init__(self, shell, magic_name, magic_kind): | |||
|
660 | self.shell = shell | |||
|
661 | self.magic_name = magic_name | |||
|
662 | self.magic_kind = magic_kind | |||
|
663 | ||||
|
664 | self._in_call = False | |||
|
665 | ||||
|
666 | @property | |||
|
667 | def pretty_target(self): | |||
|
668 | """A formatted version of the target of the alias.""" | |||
|
669 | return '%s%s' % (magic_escapes[self.magic_kind], self.magic_name) | |||
|
670 | ||||
|
671 | @property | |||
|
672 | def __doc__(self): | |||
|
673 | return "Alias for `%s`." % self.pretty_target | |||
|
674 | ||||
|
675 | def __call__(self, *args, **kwargs): | |||
|
676 | """Call the magic alias.""" | |||
|
677 | fn = self.shell.find_magic(self.magic_name, self.magic_kind) | |||
|
678 | if fn is None: | |||
|
679 | raise UsageError("Magic `%s` not found." % self.pretty_target) | |||
|
680 | ||||
|
681 | # Protect against infinite recursion. | |||
|
682 | if self._in_call: | |||
|
683 | raise UsageError("Infinite recursion detected; " | |||
|
684 | "magic aliases cannot call themselves.") | |||
|
685 | self._in_call = True | |||
|
686 | try: | |||
|
687 | return fn(*args, **kwargs) | |||
|
688 | finally: | |||
|
689 | self._in_call = False |
General Comments 0
You need to be logged in to leave comments.
Login now