class MutableOpaquePseudoMapping__init_new_key_only__Value_Ref_Weak_KeysTripleDictionary(
        IMutableOpaquePseudoMapping__init_new_key_only__WeakKeyPathDictionary__init
):
    r'''
    key_path = (keys_via_valued_eq, keys_via_id_eq, keys_via_weakref)
    #'''
    __slots__ = ()

    @classmethod
    @override
    def check_key_path(cls, key_path, /, *, init_vs_mix_vs_get):
        'key_path4init/key_path4get -> None'
        check_tuple(key_path, sz=3)
        (keys_via_valued_eq, keys_via_id_eq, keys_via_weakref) = key_path
        check_tuple(keys_via_valued_eq)
        check_tuple(keys_via_id_eq)
        check_tuple(keys_via_weakref)
        #for key_via_valued_eq in keys_via_valued_eq: check_type_le(Hashable, key_via_valued_eq)
        for key_via_valued_eq in keys_via_valued_eq:
            check_Hashable__shallow(key_via_valued_eq)
        del key_via_valued_eq
        for key_via_weakref in keys_via_weakref:
            check_Weakable(key_via_weakref)
        del key_via_weakref
        return
class MutableOpaquePseudoMapping__init_new_key_only__WeakRefDictionary(
        IMutableOpaquePseudoMapping__init_new_key_only__WeakKeyPathDictionary__init
):
    __slots__ = ()

    @classmethod
    @override
    def check_key_path(cls, key_path, /, *, init_vs_mix_vs_get):
        'key_path4init/key_path4get -> None'
        check_Weakable(key_path)
        return
class IMutableOpaquePseudoMapping__init_new_key_only__WeakKeyPathDictionary(
        IMutableOpaquePseudoMapping__init_new_key_only):
    r'''
    mapping<key_path4get, value>:
        __this_impl_mapping__ = valued_key_path -> (key_path4store, weakable_id2weak_ref_with_callback, value)
        # not: weakable_set :: WeakSet
        # not: id2weakable :: WeakValueDictionary
        # now: weakable_id2weak_ref_with_callback :: dict<id(weakable), weakref.ref(weakable, lambda _:__this_impl_mapping__.__delitem__(valued_key_path))>


    key_path4init/key_path4get -> valued_key_path <: Hashable
        #actual key
    key_path4get -> valued_key_path <: Hashable

    key_path4init -> Iter Weakable
        #auto remove if any weakable dead
    key_path4init -> key_path4store

    key_path4store -> unordered_iter_weakables__no_duplicates -> key_path4get -> bool
        #eqv for detect logic-error
        #   SHOULD_HOLD: eqv<key_path4store+(w() for w in weakable_id2weak_ref_with_callback.values()), key_path4get> <==> eq<valued_key_path, valued_key_path>

    init_vs_mix_vs_get:
        init:False
        mix:None
        get:True
    #'''
    __slots__ = ()

    @classmethod
    @abstractmethod
    def check_key_path(cls, key_path, /, *, init_vs_mix_vs_get):
        'key_path4init/key_path4get -> None'
        #def check_key_path(cls, key_path, /, *, init_vs_get:bool):
        #def check_key_path(cls, key_path, /):
        check_Weakable(key_path)
        return
 def check_key(cls, k, /):
     check_Weakable(k)
     if not le_AddrAsHash(type(k)): raise TypeError
 def check_key(cls, k, /):
     check_Weakable(k)
     return
 def check_key(cls, k, /):
     check_Weakable(k)
     #no:check_Hashable__shallow(k)
     return
    '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
    '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__',
    '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__',
    '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
    '__repr__', '__reversed__', '__setattr__', '__setitem__', '__sizeof__',
    '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl',
    '_commit_removals', '_scrub_removals', 'clear', 'copy', 'get', 'items',
    'keyrefs', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'
]


class WeakableDict(dict):
    __slots__ = '__weakref__'


check_Weakable(WeakableDict())


def mk_callback4auto_discard_WeakableDict_key(wd, k, /):
    check_type_is(WeakableDict, wd)
    wd = weakref.ref(wd)

    def callback(_, /):
        nonlocal wd
        #print('callback')
        #bug:wd = wd()
        #   wd become local var
        if wd is None:
            return
        d = wd()
        wd = None