Skip to content

Preserve ordered keyword expansions and dictionary boundaries - #22

Open
EiNSTeiN- wants to merge 2 commits into
ejfkdev:mainfrom
EiNSTeiN-:fix/ordered-keyword-expansions
Open

EiNSTeiN- wants to merge 2 commits into
ejfkdev:mainfrom
EiNSTeiN-:fix/ordered-keyword-expansions

Conversation

@EiNSTeiN-

Copy link
Copy Markdown

I am opening this PR to preserve duplicate-key checks and evaluation order across multiple keyword expansions. These two functions currently decompile to the same call even though their semantics differ:

def direct(fn, first, second):
    return fn(1, fixed=2, **first, **second)


def dictionary(fn, first, second):
    return fn(1, **{"fixed": 2, **first, **second})

The incorrect output for direct is:

def direct(fn, first, second):
    return fn(1, **{'fixed': 2, **first, **second})

Direct call expansions reject duplicate keywords. Dictionary displays overwrite duplicate keys before the final expansion. Flattening the first call into a single dictionary therefore removes its duplicate-key checks.

That distinction also controls side effects:

fn(1, fixed=2, **get_first(), **get_second())

If get_first() returns a mapping containing fixed, the source raises before evaluating get_second(). The dictionary-display reconstruction evaluates both producers and silently replaces the earlier value.

The decompiler now retains ordered expansion entries for DICT_MERGE calls, keeps DICT_UPDATE dictionary boundaries, and validates named keyword spellings and uniqueness before decomposition. The printer emits ** for unnamed keyword entries. This preserves interleaved forms such as fn(1, **first, fixed=2, **second) as well as intentionally constructed dictionaries with keys such as "my col", "class", or repeated literal keys.

Multiple unpacking begins in Python 3.5. The repaired DICT_MERGE/DICT_UPDATE instruction layout begins in Python 3.9; the older BUILD_MAP_UNPACK_WITH_CALL path is outside this repair.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant