Files
RustPython/extra_tests/snippets/stdlib_weakref.py
Copilot 7e637e8cbd Add __callback__ property to weakref type (#7590)
* Initial plan

* Add __callback__ property to PyWeak for weakref compatibility

Add get_callback() method to PyWeak in core.rs that safely reads the
callback field under the stripe lock. Expose it as a read-only
__callback__ property on the weakref type, matching CPython behavior:
- Returns the callback function when one was provided and referent is alive
- Returns None when no callback was provided
- Returns None after the referent has been collected
- Raises AttributeError on assignment (read-only)

Remove @unittest.expectedFailure from test_callback_attribute and
test_callback_attribute_after_deletion in test_weakref.py.

Add regression tests to extra_tests/snippets/stdlib_weakref.py.

Agent-Logs-Url: https://github.com/RustPython/RustPython/sessions/a8689daa-4476-4645-a935-0e13c7f7bb42

Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com>

* Fix ruff formatting in stdlib_weakref.py snippet

Agent-Logs-Url: https://github.com/RustPython/RustPython/sessions/4995198f-e083-4dac-823a-166fcf54adc4

Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com>
2026-04-13 23:58:58 +09:00

54 lines
945 B
Python

from _weakref import proxy, ref
from testutils import assert_raises
class X:
pass
a = X()
b = ref(a)
assert callable(b)
assert b() is a
# Test __callback__ property
assert b.__callback__ is None, (
"weakref without callback should have __callback__ == None"
)
callback = lambda r: None
c = ref(a, callback)
assert c.__callback__ is callback, "weakref with callback should return the callback"
# Test __callback__ is read-only
try:
c.__callback__ = lambda r: None
assert False, "Setting __callback__ should raise AttributeError"
except AttributeError:
pass
# Test __callback__ after referent deletion
x = X()
cb = lambda r: None
w = ref(x, cb)
assert w.__callback__ is cb
del x
assert w.__callback__ is None, "__callback__ should be None after referent is collected"
class G:
def __init__(self, h):
self.h = h
g = G(5)
p = proxy(g)
assert p.h == 5
del g
assert_raises(ReferenceError, lambda: p.h)