1
1
import asyncio
2
2
import time
3
+ import weakref
3
4
from collections import defaultdict
4
5
from collections .abc import Mapping
5
6
from typing import Any , Callable , DefaultDict , Dict , Iterable , List , Optional , Set , Tuple , Union
10
11
MAX_PROPAGATION_TIME = 0.01
11
12
12
13
bindings : DefaultDict [Tuple [int , str ], List ] = defaultdict (list )
13
- bindable_properties : Dict [Tuple [int , str ], Any ] = {}
14
+ bindable_properties : Dict [Tuple [int , str ], weakref . finalize ] = {}
14
15
active_links : List [Tuple [Any , str , Any , str , Callable [[Any ], Any ]]] = []
15
16
16
17
@@ -149,11 +150,19 @@ def __set__(self, owner: Any, value: Any) -> None:
149
150
if has_attr and not value_changed :
150
151
return
151
152
setattr (owner , '___' + self .name , value )
152
- bindable_properties [( id ( owner ), self .name )] = owner
153
+ self ._register ( owner )
153
154
_propagate (owner , self .name )
154
155
if value_changed and self ._change_handler is not None :
155
156
self ._change_handler (owner , value )
156
157
158
+ def _register (self , owner : Any ) -> None :
159
+ registry_key = (id (owner ), str (self .name ))
160
+
161
+ def try_unregister () -> None :
162
+ bindable_properties .pop (registry_key , None )
163
+
164
+ bindable_properties .setdefault (registry_key , weakref .finalize (owner , try_unregister ))
165
+
157
166
158
167
def remove (objects : Iterable [Any ]) -> None :
159
168
"""Remove all bindings that involve the given objects.
@@ -174,9 +183,11 @@ def remove(objects: Iterable[Any]) -> None:
174
183
]
175
184
if not binding_list :
176
185
del bindings [key ]
177
- for (obj_id , name ), obj in list (bindable_properties .items ()):
178
- if id (obj ) in object_ids :
179
- del bindable_properties [(obj_id , name )]
186
+ for registry_key , finalizer in list (bindable_properties .items ()):
187
+ obj_id , _ = registry_key
188
+ if obj_id in object_ids :
189
+ del bindable_properties [registry_key ]
190
+ finalizer .detach ()
180
191
181
192
182
193
def reset () -> None :
0 commit comments