Skip to content

Enhancement: Allow weakrefs to be created to Litestar instances #4186

@charles-dyfis-net

Description

@charles-dyfis-net

Summary

The Python standard library has facilities for creating weak references to objects, allowing them to be accessed without prohibiting garbage collection.

To be compatible with this facility, when a type defines __slots__, it must include __weakref__ in the list of permitted slots. This is not presently the case for Litestar's types.

Basic Example

As an example of a facility where weakrefs have value, consider a test suite wherein a variety of differently-configured application instances may be created, where one wishes to have cached httpx clients to use to invoke those instances. A WeakKeyDictionary[Litestar, httpx.AsyncClient] would be an appropriate tool to store clients for these applications, automatically deleting any client should an instance it's attached to be garbage collected, if weakrefs could be created for Litestar objects.

Concretely:

from weakref import WeakKeyDictionary
import httpx
import litestar

client_cache: WeakKeyDictionary[litestar.Litestar, httpx.AsyncClient] = WeakKeyDictionary()

def client_for_app(app: litestar.Litestar) -> httpx.AsyncClient:
    if (retval := client_cache.get(app, default=None)) is not None:
        return retval
    transport = httpx.ASGITransport(app=app)
    client_cache[app] = retval = httpx.AsyncClient(transport=transport)
    return retval

This is not currently possible, because weakref.WeakKeyDictionary()[litestar.Litestar()] = None fails with TypeError: cannot create weak reference to 'Litestar' object. Amending either Litestar.__slots__ or Router.__slots__ to contain '__weakref__' would resolve this.

Drawbacks and Impact

Slightly increases memory usage. Would break compatibility with any preexisting code that already subclasses Litestar and adds a __weakref__ slot without checking whether that slot already exists.

Unresolved questions

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    AcceptedChange or enhancement is accepted for development.EnhancementThis is a new feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions