Question: Here is a simplified Python code:  class Base: __possible_types__ = {} def __new__(cls, *args, **kwargs) -> type: # pop the `__type__` argument because it # should be passed to the class `__init__` type_ = kwargs.pop("__type__", None) if type_ is not None: possible_type = cls.__possible_types__.get(type_) if possible_type is not None: return possible_type(*args, **kwargs) return super().__new__(cls) def __init__(self, *args, **kwargs) -> None: print(f"{self.__class__.__name__}.__init__", args, kwargs) def __init_subclass__(cls) -> None: __possible_types__ = {} for parent in cls.__mro__[1:]: if issubclass(parent, Base): parent.__possible_types__[cls.__name__] = cls class Parent(Base): pass class Child(Parent): pass class Adult(Parent): pass should_be_child = Parent( name="bob", __type__="Child" ) print(should_be_child)  and here is the output: Child.__init__ () {'name': 'bob'} Child.__init__ () {'name': 'bob', '__type__': 'Child'} <__main__.Child object at 0x...>  A few questions  Why is __init__ called twice? How is the popped dict item (__type__) back in the second __init__ call? How do I solve this? 

Answer: The problem. Two distinct calls. Two disctinct calls for Child are made. One as result of the call to Parent(), and the other when you call possible_type(*args, **kwargs) inside Base's constructor. As possible_type e.g. Child does not override __new__, it inherits the first one available from its parents. That ultimately means that Parent( ..., __type__ = ...) calls to construct a Child in the process as Child is a subclass of Parent, possible_type(*args, **kwargs) gets called, which in turn calls __new__ with no subclasses of it's own and thus it does so failling the check, and calls yet again super's __new__. This is the reason with two distinct __init__ calls get made, and why it appears to be that __new__ is "leaking" the popped dict item __type__. When actually, it's only being passed to its parent's constructor but not Child's This is made clear with some strategically put "debugging" print()s class Base: __possible_types__ = {} def __new__(cls, *args, **kwargs) -> type: # pop the `__type__` argument because it # should be passed to the class `__init__` type_ = kwargs.pop("__type__", None) if type_ is not None: possible_type = cls.__possible_types__.get(type_) if possible_type is not None: return possible_type(*args, **kwargs) print(f"\n__new__ called {cls=}\n") return super().__new__(cls) def __init__(self, *args, **kwargs) -> None: print(f"{self.__class__.__name__}.__init__", args, kwargs) def __init_subclass__(cls) -> None: __possible_types__ = {} print(f"\n__init_subclass__ called {cls}") for parent in cls.__mro__[1:]: if issubclass(parent, Base): print(f"{parent=}") parent.__possible_types__[cls.__name__] = cls class Parent(Base): pass class Child(Parent): pass class Adult(Parent): pass should_be_child = Parent( name="bob", __type__="Child" ) print(should_be_child) should_be_adult = Parent( name="lisa", __type__="Adult" ) print(should_be_adult) should_be_just_parent = Parent( name="mark", __type__ = "isNotASubclass" ) print(should_be_just_parent)  Output: __init_subclass__ called <class '__main__.Parent'> parent=<class '__main__.Base'> __init_subclass__ called <class '__main__.Child'> parent=<class '__main__.Parent'> parent=<class '__main__.Base'> __init_subclass__ called <class '__main__.Adult'> parent=<class '__main__.Parent'> parent=<class '__main__.Base'> __new__ called cls=<class '__main__.Child'> Child.__init__ () {'name': 'bob'} Child.__init__ () {'name': 'bob', '__type__': 'Child'} <__main__.Child object at 0x000001CFC783EED0> __new__ called cls=<class '__main__.Adult'> Adult.__init__ () {'name': 'lisa'} Adult.__init__ () {'name': 'lisa', '__type__': 'Adult'} <__main__.Adult object at 0x000001CFC783EF10> __new__ called cls=<class '__main__.Parent'> Parent.__init__ () {'name': 'mark', '__type__': 'isNotASubclass'} <__main__.Parent object at 0x000001CFC783EE90>  As you see, it is Parents __init__ that's being called with __type__. And in the example I've given avobe, the code reaches print(f"\n__new__ called {cls=}\n") in very case, despite a subclass being detected and a new instance of that class being constructed. Quick-fix. A one-line edit. You can solve this by only making the call in the case that possible_types is None == True. class Base: __possible_types__ = {} def __new__(cls, *args, **kwargs) -> type: # pop the `__type__` argument because it # should be passed to the class `__init__` type_ = kwargs.pop("__type__", None) if type_ is not None: possible_type = cls.__possible_types__.get(type_) if possible_type is not None: return super().__new__(possible_type) # Modified line print(f"\n__new__ called {cls=}\n") return super().__new__(cls) def __init__(self, *args, **kwargs) -> None: print(f"{self.__class__.__name__}.__init__", args, kwargs) def __init_subclass__(cls) -> None: __possible_types__ = {} print(f"\n__init_subclass__ called {cls}") for parent in cls.__mro__[1:]: if issubclass(parent, Base): print(f"{parent=}") parent.__possible_types__[cls.__name__] = cls class Parent(Base): pass class Child(Parent): pass class Adult(Parent): pass should_be_child = Parent( name="bob", __type__="Child" ) print(should_be_child) should_be_adult = Parent( name="lisa", __type__="Adult" ) print(should_be_adult) should_be_just_parent = Parent( name="mark", __type__ = "isNotASubclass" ) print(should_be_just_parent)  Output: __init_subclass__ called <class '__main__.Parent'> parent=<class '__main__.Base'> __init_subclass__ called <class '__main__.Child'> parent=<class '__main__.Parent'> parent=<class '__main__.Base'> __init_subclass__ called <class '__main__.Adult'> parent=<class '__main__.Parent'> parent=<class '__main__.Base'> Child.__init__ () {'name': 'bob', '__type__': 'Child'} <__main__.Child object at 0x000002806AE4EF10> Adult.__init__ () {'name': 'lisa', '__type__': 'Adult'} <__main__.Adult object at 0x000002806AE4EE90> __new__ called cls=<class '__main__.Parent'> Parent.__init__ () {'name': 'mark', '__type__': 'isNotASubclass'} <__main__.Parent object at 0x000002806AE4EED0>  In this modified version only call gets made in every case, and the code only reaches print(f"\n__new__ called {cls=}\n") when no subclasses where found. Regarding further clarifications in juanpa.arivillaga's answer indeed 'hijackin' __new__ to make a factory patern is very error-prone, and could be simplified by insted implementing that pattern with a static or class method. A more "sound" solution. Implementing a factory pattern via a classmethod. class Base: __possible_types__ = {} def __init__(self, *args, **kwargs) -> None: print(f"{self.__class__.__name__}.__init__", args, kwargs) def __init_subclass__(cls) -> None: __possible_types__ = {} Base.__possible_types__[cls.__name__] = cls @classmethod def create_base(cls, *args, __type__, **kwargs): return cls.__possible_types__[__type__](*args, **kwargs) class Parent(Base): pass class Child(Parent): pass class Adult(Parent): pass should_be_child = Base.create_base( name="bob", __type__="Child" ) print(should_be_child) should_be_adult = Base.create_base( name="lisa", __type__="Adult" ) print(should_be_adult)  Output: Child.__init__ () {'name': 'bob'} <__main__.Child object at 0x0000020FB123ECD0> Adult.__init__ () {'name': 'lisa'} <__main__.Adult object at 0x0000020FB11A4ED0>