Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dictionary order influences parseability #5183

Open
apexys opened this issue Feb 29, 2024 · 3 comments
Open

Dictionary order influences parseability #5183

apexys opened this issue Feb 29, 2024 · 3 comments
Labels
C-compat A discrepancy between RustPython and CPython

Comments

@apexys
Copy link

apexys commented Feb 29, 2024

Hello everyone,
I'm currently using rustpython to embed an existing python library into a piece of software and I think I might have found a bug.
The goal is to create a dictionary with String keys and Callable entries somewhat like this:

new_dict = {
    **{x: lambda y: y + 2 for x in ["a", "b", "c"]}, 
    "d": lambda x: x +1,
}

If I try to run this code through the rustpython executable, I get the error message:

thread 'main' panicked at /home/valentinbuck/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rustpython-codegen-0.3.0/src/compile.rs:311:9:
assertion failed: table.sub_tables.is_empty()
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

This differs from the error I get when I run this code through a VM I constructed myself:

thread 'main' panicked at /home/valentinbuck/.cargo/git/checkouts/rustpython-f8ef4d934ac33cd8/e6c6f96/compiler/codegen/src/compile.rs:481:57:
The symbol must be present in the symbol table, even when it is undefined in python.

However, when I swap the two lines in the dict, it compiles and runs fine:

new_dict = {
    "d": lambda x: x +1,
    **{x: lambda y: y + 2 for x in ["a", "b", "c"]}, 
}

I tried looking through the parser to find the place where this happens but had no luck.
Do you have an idea where I could start or what is going wrong?

Thanks a lot for your project!

@apexys apexys added the C-compat A discrepancy between RustPython and CPython label Feb 29, 2024
@apexys
Copy link
Author

apexys commented Feb 29, 2024

Almost forgot: Both variants compile fine through CPython.

@youknowone
Copy link
Member

Thank you for the report!
Somehow, x in "d": lambda x: x +1, doesn't exist in symbol table. How about starting comparing how the symbol put in or not put in by the order?

@apexys
Copy link
Author

apexys commented Feb 29, 2024

I think its a different problem. On the current main branch, if I run the working version (dict-comp-last), and log the symbol table stack before the code object gets popped in compile_expression->Expr::Lambda after the emit! of the return value , I get

ST stack [SymbolTable(2 symbols, 1 sub scopes), SymbolTable(1 symbols, 0 sub scopes)]
Sub Table Symbols None
ST stack [SymbolTable(2 symbols, 0 sub scopes), SymbolTable(2 symbols, 0 sub scopes), SymbolTable(1 symbols, 0 sub scopes)]

But if I run the non-working version (dict-comp-first), I get

ST stack [SymbolTable(2 symbols, 1 sub scopes), SymbolTable(2 symbols, 1 sub scopes)]

It almost looks like the entry gets put into the symbol table twice.
But why and where does that happen?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-compat A discrepancy between RustPython and CPython
Projects
None yet
Development

No branches or pull requests

2 participants