dbzero.weak_proxy(obj)
Creates a weak reference to a dbzero managed object. Weak references allow you to point to an object without increasing its reference count. This is crucial for preventing circular dependencies and for creating references that don't stop an object from being garbage-collected.
Its primary use case is to enable references to objects across different prefixes. dbzero normally forbids direct references between objects in separate prefixes to maintain data integrity. weak_proxy provides a safe way to bypass this restriction.
Parameters
| Name | Type | Description |
|---|---|---|
obj | A dbzero managed object | The target object to create a weak reference to. |
Returns
A special weak proxy object. This proxy behaves like the original object for most operations, such as attribute access, but it does not keep the original object alive.
Behavior and Side Effects
- Reference Counting: A
weak_proxydoes not increment the target object's reference count. This means the target can be garbage-collected if no other strong references point to it. - Expiration: When the target object is deleted, the weak proxy becomes expired.
- Accessing attributes on an expired proxy will raise a
dbzero.ReferenceError. - You can check if a proxy has expired using
dbzero.expired(proxy). - Even after expiration, the
dbzero.uuid()of the original object remains accessible through the proxy.
- Accessing attributes on an expired proxy will raise a
- Tagging and Queries: Weak proxies can be used with
dbzero.as_tag()anddbzero.find(), even if the proxy is expired. This allows you to maintain relationships and lookups after an object has been deleted. - Collections: Weak proxies can be seamlessly stored inside
dbzerocollections (dbzero.list,dbzero.set, etc.).
Examples
Creating a cross-prefix reference
Without weak_proxy, referencing an object from another prefix raises an error. weak_proxy solves this by creating a non-owning link.
# obj_1 is in the default prefix
obj_1 = MemoTestPxClass(123, prefix="default")
assert db0.getrefcount(obj_1) == 0
# Open a second prefix
db0.open("another-prefix", "rw")
# Create a weak reference to obj_1 from an object in "another-prefix"
obj_2 = MemoTestPxClass(db0.weak_proxy(obj_1), prefix="another-prefix")
# The reference count of obj_1 remains unchanged
assert db0.getrefcount(obj_1) == 0
# You can access the original object's data through the proxy
assert obj_2.value.value == 123Handling an expired reference
When the original object is deleted, the proxy expires, and trying to access its data will fail.
obj_1 = MemoTestPxClass(123)
# Create a weak proxy and assign it to another object's member
obj_2 = MemoTestPxClass(db0.weak_proxy(obj_1))
# Delete the original object
del obj_1
db0.commit()
# The proxy is now expired
assert db0.expired(obj_2.value) is True
# Trying to access the value through the expired proxy raises an error
with pytest.raises(db0.ReferenceError):
_ = obj_2.value.value
# However, you can still use the expired proxy for lookups
# For example, if we tagged an object with obj_1 before it was deleted
obj_3 = MemoTestPxClass(999)
db0.tags(obj_3).add(db0.as_tag(obj_1)) # Tagging happens before deletion in this setup
# We can still find obj_3 using the expired weak proxy
assert list(db0.find(db0.as_tag(obj_2.value))) == [obj_3]