GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix `weakref.ref()` with a callback accepting non-weakrefable objects by jseop-lim · Pull Request #1266 · oracle/graalpython

Conversation

@jseop-lim

@jseop-lim jseop-lim commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #1256

ReferenceTypeNode.refTypeWithCallback, used by weakref.ref(obj, cb) and weakref.proxy(obj, cb), skipped the getWeaklistoffset() check that refType does for a None callback, so dict, list, int, None and other builtin objects got a weak reference. CPython checks _PyType_SUPPORTS_WEAKREFS before it looks at the callback (weakrefobject.c#L405-L415).

getBuiltinTypeWeaklistoffset was also missing collections.deque, array.array, mmap.mmap, _contextvars.Context, _queue.SimpleQueue, _struct.Struct and the typing.TypeVar family. These worked only with a callback, so the check alone would have rejected them. With the entries, they now accept a weak reference without a callback too, as on CPython.

AS-IS

>>> weakref.proxy({}, callback)
<weakproxy at 1415; to 'dict' at 1419>
>>> weakref.ref(None, callback)
<weakref at 1753773164; to 'NoneType' at 1613378103>
>>> weakref.ref(d)   # d = collections.deque()
TypeError: cannot create weak reference to 'collections.deque' object

TO-BE

>>> weakref.proxy({}, callback)
TypeError: cannot create weak reference to 'dict' object
>>> weakref.ref(None, callback)
TypeError: cannot create weak reference to 'NoneType' object
>>> weakref.ref(d)
<weakref at 0x10632dfd0; to 'collections.deque' at 0x106351b70>

(matching CPython)

Changes

  • Raise TypeError in refTypeWithCallback when the object's class is a PythonBuiltinClassType with a zero getWeaklistoffset(), as refType does.
  • Add deque, array, mmap, Context, SimpleQueue and Struct to getBuiltinTypeWeaklistoffset with their CPython 3.13 offsets, and TypeVar, TypeVarTuple, ParamSpec, ParamSpecArgs and ParamSpecKwargs with the managed weakref offset -32.
  • Add test_weakref_with_callback_object_type_support and test_weakref_builtin_types_with_weaklist to tests/test_weakref.py.

Testing

mx python-jvm on darwin-aarch64. tests/test_weakref.py passes (13 tests), and both new tests fail on the unpatched build. The tagged lib-python suites test_weakref, test_weakset, test_typing, test_deque, test_array, test_mmap, test_queue, test_struct, test_context, test_functools, test_re and test_threading_local pass. Over 79 builtin, stdlib and user-defined objects, weakref.ref(obj), weakref.ref(obj, cb) and weakref.proxy(obj, cb) now succeed or raise TypeError exactly as on CPython 3.13.14, apart from a __slots__ = () class and operator.attrgetter, which GraalPy already accepted without a callback.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
jseop-lim added 2 commits October 30, 2026 03:15
@jseop-lim
Reject weak references with a callback to non-weakrefable objects
13dc498
refTypeWithCallback skipped the weaklistoffset check that refType does,
so weakref.ref(obj, cb) and weakref.proxy(obj, cb) accepted dicts,
None and other builtin objects CPython cannot reference weakly.

Add the check, and give the builtin types that CPython does reference
weakly but that were missing from getBuiltinTypeWeaklistoffset their
CPython 3.13 offsets: deque, array, mmap, Context, SimpleQueue, Struct
and the TypeVar family. Without the entries the check would reject
them, and today they already fail without a callback.

Signed-off-by: Jeongseop Lim <[email protected]>
@jseop-lim
Spell out the weakref tests without loops
56676dc
Each object and constructor gets its own assertion, so a failure
names the case, and the mmap is closed after use.

Signed-off-by: Jeongseop Lim <[email protected]>
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Oct 31, 2026
msimacek
msimacek reviewed Nov 9, 2026
View reviewed changes
Comment thread ...python/src/com/oracle/graal/python/builtins/objects/referencetype/ReferenceTypeBuiltins.java
@Cached.Exclusive @Cached HiddenAttr.ReadNode readQueueNode,
@Bind PythonLanguage language,
@Shared @Cached TypeNodes.GetInstanceShape getInstanceShape) {
if (getClassNode.execute(inliningTarget, object) instanceof PythonBuiltinClassType type && type.getWeaklistoffset() == 0) {

@msimacek msimacek Nov 9, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to also handle PythonBuiltinClass

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@msimacek msimacek msimacek left review comments

At least 1 approving review is required to merge this pull request.

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

[Bug]: weakref.ref() and weakref.proxy() with a callback accept objects that do not support weak references

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@jseop-lim @msimacek
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.