From 7fe0542a80deb98932d3ec559473022447f8a3a7 Mon Sep 17 00:00:00 2001 From: Anson Mansfield Date: Wed, 18 Feb 2026 11:56:43 -0500 Subject: [PATCH] weakref: Implement atop `_weakref` primitives. Signed-off-by: Anson Mansfield --- python-stdlib/weakref/manifest.py | 3 ++ python-stdlib/weakref/weakref.py | 54 +++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 python-stdlib/weakref/manifest.py create mode 100644 python-stdlib/weakref/weakref.py diff --git a/python-stdlib/weakref/manifest.py b/python-stdlib/weakref/manifest.py new file mode 100644 index 000000000..461c5a63b --- /dev/null +++ b/python-stdlib/weakref/manifest.py @@ -0,0 +1,3 @@ +metadata(version="0.0.1") + +module("weakref.py", opt=3) diff --git a/python-stdlib/weakref/weakref.py b/python-stdlib/weakref/weakref.py new file mode 100644 index 000000000..48c67a7fd --- /dev/null +++ b/python-stdlib/weakref/weakref.py @@ -0,0 +1,54 @@ +import _weakref +import micropython + + +class _weakref_entry: + def __init__(self, parent, obj): + self.parent = parent + + if not hasattr(obj, "__dict__") and not hasattr(obj, "__weakref__"): + raise TypeError("cannot create weak reference to '{}' object".format(type(obj).__name__)) + + # linked list ensures this will always be part of the same cyclic isolate as the original object + self.next = obj + try: + getattr(obj, "__weakref__").next = self + except (KeyError, AttributeError): + setattr(obj, "__weakref__", self) + + def __del__(self): + p = self.parent + p(None) + if p.__callback__ is not None: + micropython.schedule(p.__callback__, p) + +class ref(_weakref.ref): + def __init__(self, obj, callback=None): + super().__init__(obj) + self.__callback__ = callback + _weakref_entry(self, obj) + +class finalize: + def __init__(self, obj, func, *args, **kwargs): + self._func = func + self._args = args + self._kwargs = kwargs + self._ref = ref(obj, self) + + @property + def alive(self): + return self._ref() is not None + + def peek(self): + obj = self._ref() + if obj is not None: + return (obj, self._func, self._args, self._kwargs) + + def detach(self): + ret = self.peek() + self._ref(None) + return ret + + def __call__(self, r=None): + return self._func(*self._args, **self._kwargs) +