22from __future__ import annotations
33
44import functools
5+ import weakref
56from dataclasses import dataclass
67from typing import Any , Callable , Optional
78
@@ -22,7 +23,13 @@ def register(self) -> Callable[[], None]:
2223 from marimo ._runtime .output import _output
2324
2425 # Dictionary to store display objects by ID
25- display_objects : dict [str , Any ] = {}
26+ display_objects : weakref .WeakValueDictionary [str , Any ] = (
27+ weakref .WeakValueDictionary ()
28+ )
29+
30+ def clear_display_objects () -> None :
31+ """Clear all stored display objects."""
32+ display_objects .clear ()
2633
2734 old_display = IPython .display .display
2835 old_update_display = getattr (IPython .display , "update_display" , None )
@@ -61,6 +68,9 @@ def display(*objs: Any, **kwargs: Any) -> Optional[DisplayHandle]:
6168 # Store the object if display_id is provided
6269 if display_id is not None :
6370 display_objects [display_id ] = output_value
71+ # Clean up old display objects if we have too many
72+ if len (display_objects ) > 1000 : # Arbitrary limit
73+ clear_display_objects ()
6474
6575 _output .append (output_value )
6676
@@ -110,6 +120,7 @@ def update_display(
110120 pass
111121
112122 def unpatch () -> None :
123+ clear_display_objects () # Clean up on unpatch
113124 IPython .display .display = old_display # type: ignore
114125 if old_update_display is not None :
115126 IPython .display .update_display = old_update_display # type: ignore
0 commit comments