Skip to content

[Bug]: dict.update() updates lazily from a generator #1007

Description

@scoder

Describe the bug

I have the following code:

exception_subtypes = {
    'BaseException' : [
        'BaseExceptionGroup',
        'Exception',
        'GeneratorExit',
        'KeyboardInterrupt',
        'SystemExit',
    ],
    'BaseExceptionGroup' : [
        'ExceptionGroup',
    ],
    # ...
}

exception_supertypes = {'BaseException': ['BaseException']}
exception_supertypes.update(
    # Rebuild the exception type MRO, knowing that the 'exception_subtypes' dict
    # was built breadth-first, listing all parents before their children.
    (child, [child] + exception_supertypes[parent])
    for parent, children in exception_subtypes.items()
    for child in children
)

In CPython, this allows for an efficient linear-time supertypes dict creation, by inserting one item from the generator expression at a time before requesting the next item. It fails in GraalPy, apparently because the first items have not yet been inserted into the supertypes dict (or can at least not be looked up there) when it reaches the BaseExceptionGroup entry in the subtypes dict that the generator iterates over.

The error is:

    (child, [child] + exception_supertypes[parent])
                      ~~~~~~~~~~~~~~~~~~~~^^^^^^^^
KeyError: 'BaseExceptionGroup'

Operating system

Linux

CPU architecture

x86_64

GraalPy version

25.1.3

JDK version

No response

Context configuration

No response

Steps to reproduce

Run the above code, see the error.

Expected behavior

It can certainly be argued whether there should be a guarantee regarding the time of insertions, but I don't think it's wrong to assume that once an item has been retrieved from the generator (and iteration continues), it should have been stored in the dict being updated – because where else should it be stored? The usage of a generator (expression), as opposed to passing a prepared list of items into .update(), is to apply the updates as they are being generated, and at least not using intermediate storage for them.

Stack trace

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions