API Reference
weak_proxy

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

NameTypeDescription
objA dbzero managed objectThe 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_proxy does 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.
  • Tagging and Queries: Weak proxies can be used with dbzero.as_tag() and dbzero.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 dbzero collections (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 == 123

Handling 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]