Description
Garbage collecting the space a body was added to causes the body's _space
proxy to die. But, the Body.space
property does not catch or check whether the proxy is alive, unlike the Shape.space
property.
Additionally, the Body.sleep/sleep_with_group
methods might not work as intended when the space is deleted.
Example:
import pymunk as pm
space = pm.Space()
body = pm.Body()
space.add(body)
del space
print(body.space)
Traceback (most recent call last):
File "C:\Users\...\main.py", line 10, in <module>
print(body.space)
^^^^^^^^^^
File "C:\Users\...\pymunk\body.py", line 425, in space
return self._space._get_self() # ugly hack because of weakref
^^^^^^^^^^^^^^^^^^^^^
ReferenceError: weakly-referenced object no longer exists
Suggestion:
I think it is better to use weakref.ref
instead of weakref.proxy
.
When there is no space to reference, use a None
returning callable (types.NoneType
, lambda: None
, weakref(set())
). (In my own package, I use the latter that is cached as a global.) Then, having a deleted space is treated the same as not having a space in the first place.
Conveniently, the return type is already Optional[Space]
.
- if self._space is not None:
- try:
- return self._space._get_self() # ugly hack because of weakref
- except ReferenceError:
- return None
- else:
- return None
+ return self._space()
(Internal code might now use .space
instead of ._space
so it doesn't need to invoke the weakref itself.)