@@ -564,6 +564,9 @@ def register_lazy(
564564 self .lazy_magics [name ] = fully_qualified_name
565565 kinds = magic_kinds if magic_kind == "line_cell" else (magic_kind ,)
566566 for kind in kinds :
567+ existing = self .magics [kind ].get (name )
568+ if existing is not None and not isinstance (existing , LazyMagic ):
569+ continue
567570 self .magics [kind ][name ] = LazyMagic (self , fully_qualified_name , kind , name )
568571
569572 def load_lazy (self , magic_name : str ) -> None :
@@ -590,7 +593,10 @@ def load_lazy(self, magic_name: str) -> None:
590593 if sep :
591594 from importlib import import_module
592595
593- self .register (getattr (import_module (module_name ), class_name ))
596+ self ._register (
597+ (getattr (import_module (module_name ), class_name ),),
598+ lazy_spec = spec ,
599+ )
594600 else :
595601 assert self .shell is not None
596602 self .shell .run_line_magic ("load_ext" , spec )
@@ -645,6 +651,22 @@ def register(self, *magic_objects: type[Magics] | Magics) -> None:
645651 ----------
646652 *magic_objects : one or more classes or instances
647653 """
654+ self ._register (magic_objects , lazy_spec = None )
655+
656+ def _register (
657+ self ,
658+ magic_objects : tuple [type [Magics ] | Magics , ...],
659+ lazy_spec : str | None ,
660+ ) -> None :
661+ """Back end of :meth:`register`.
662+
663+ `lazy_spec` is the spec being resolved when this registration is the
664+ result of a lazy load, and None when the caller asked for it
665+ explicitly. A lazily loaded class only fills in the names it is still
666+ the declared provider of: a magic somebody registered for real -- as
667+ IPykernel does with ``%edit`` -- outranks a declaration, whichever
668+ happens to be loaded last.
669+ """
648670 # Start by validating them to ensure they have all had their magic
649671 # methods registered at the instance level
650672 for m in magic_objects :
@@ -661,7 +683,16 @@ def register(self, *magic_objects: type[Magics] | Magics) -> None:
661683 # table of callables
662684 self .registry [m .__class__ .__name__ ] = m
663685 for mtype in magic_kinds :
664- self .magics [mtype ].update (m .magics [mtype ])
686+ table = self .magics [mtype ]
687+ for magic_name , func in m .magics [mtype ].items ():
688+ if lazy_spec is not None :
689+ existing = table .get (magic_name )
690+ if existing is not None and not (
691+ isinstance (existing , LazyMagic )
692+ and existing .spec == lazy_spec
693+ ):
694+ continue
695+ table [magic_name ] = func
665696
666697 def register_function (
667698 self ,
0 commit comments