Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deleting space makes body.space raise ReferenceError #278

Closed
aatle opened this issue Mar 16, 2025 · 2 comments
Closed

Deleting space makes body.space raise ReferenceError #278

aatle opened this issue Mar 16, 2025 · 2 comments

Comments

@aatle
Copy link

aatle commented Mar 16, 2025

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.)

@aatle
Copy link
Author

aatle commented Mar 24, 2025

I forgot to mention, the above suggestion was also towards Shape._space, as it'll simplify the code, be consistent, and remove the need for Space._get_self().

@viblo
Copy link
Owner

viblo commented Mar 24, 2025

Ah of course. I thought about it but then forgot it before I had time to implement. Now its fixed (but again forgot the issue tag..)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants