diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_weakref.py b/graalpython/com.oracle.graal.python.test/src/tests/test_weakref.py index e47a8975d4..a78a036ad6 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_weakref.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_weakref.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -128,6 +128,34 @@ def test_weakref_object_type_support(): assert False, "should throw TypeError for unsupported objects" +def test_proxy_does_not_keep_object_alive(): + import gc + + class A: + attr = 42 + + a = A() + proxy = weakref.proxy(a) + ref = weakref.ref(a) + + assert proxy.attr == 42 + a = None + + for _ in range(10000): + gc.collect() + if ref() is None: + break + + assert ref() is None + assert "NoneType" in repr(proxy) + try: + getattr(proxy, "attr") + except ReferenceError: + pass + else: + assert False, "weakref proxy kept the object alive" + + def test_proxy_getitem(): class A: def __init__(self, collection): @@ -293,4 +321,4 @@ def __call__(self): a = A(42) proxy = weakref.proxy(a) assert callable(proxy) is True - assert proxy() == 42 \ No newline at end of file + assert proxy() == 42 diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/weakref/PProxyType.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/weakref/PProxyType.java index f39653ccde..325cfeee11 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/weakref/PProxyType.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/weakref/PProxyType.java @@ -46,16 +46,13 @@ public class PProxyType extends PythonBuiltinObject { - public final Object object; public final PReferenceType weakReference; - public PProxyType(Object cls, Shape instanceShape, Object object, PReferenceType weakReference) { + public PProxyType(Object cls, Shape instanceShape, PReferenceType weakReference) { super(cls, instanceShape); - assert (object != null); assert (weakReference != null); - this.object = object; this.weakReference = weakReference; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/weakref/ProxyTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/weakref/ProxyTypeBuiltins.java index e21082fc96..f8c7da9632 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/weakref/ProxyTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/weakref/ProxyTypeBuiltins.java @@ -190,7 +190,7 @@ static PProxyType newNode(VirtualFrame frame, Node inliningTarget, Object object PythonBuiltinClassType cls = PythonBuiltinClassType.PProxyType; Shape shape = cls.getInstanceShape(language); - return new PProxyType(cls, shape, object, weakReference); + return new PProxyType(cls, shape, weakReference); } } @@ -268,9 +268,13 @@ static Object repr(PProxyType self, @Cached ObjectNodes.GetIdNode getIdNode, @Cached TypeNodes.GetQualNameNode getQualNameNode, @Cached CastToJavaStringNode castToJavaStringNode) { - Object object = unwrap(self, inliningTarget); + Object object = self.weakReference.getPyObject(); long selfId = (long) getIdNode.execute(self); + if (object == PNone.NONE) { + long noneId = (long) getIdNode.execute(PNone.NONE); + return reprBoundary(selfId, noneId, "NoneType"); + } long objectId = (long) getIdNode.execute(object); TruffleString objectTypeNameTS = getQualNameNode.execute(inliningTarget, ((PythonObject) object).getPythonClass()); String objectTypeName = castToJavaStringNode.execute(objectTypeNameTS); diff --git a/graalpython/lib-python/3/test/test_file.py b/graalpython/lib-python/3/test/test_file.py index b6dfeb7e4c..9df5527869 100644 --- a/graalpython/lib-python/3/test/test_file.py +++ b/graalpython/lib-python/3/test/test_file.py @@ -7,7 +7,6 @@ import io import _pyio as pyio -from test import support from test.support import gc_collect from test.support.os_helper import TESTFN from test.support import os_helper @@ -25,7 +24,6 @@ def tearDown(self): self.f.close() os_helper.unlink(TESTFN) - @support.impl_detail("weakref nondeterministic GR-44850", graalpy=False) def testWeakRefs(self): # verify weak references p = proxy(self.f)