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

missing __builtins__ in the scope with py::exec #1654

Closed
martinRenou opened this issue Jan 4, 2019 · 1 comment · Fixed by #2616
Closed

missing __builtins__ in the scope with py::exec #1654

martinRenou opened this issue Jan 4, 2019 · 1 comment · Fixed by #2616

Comments

@martinRenou
Copy link
Contributor

Issue description

When creating a module using the constructor directly instead of using a macro from pybind11, and when defining multiple functions in it using py::exec, there seem to be an issue. I'm not sure yet if the issue comes from py::exec, but the following code works fine when py::exec is replaced by py::module::import("builtins").attr("exec").

Reproducible example code

py::module my_module("my_module");
std::string my_code = "\n"
       "def foo():\n"
       "    return 4\n"
       "\n"
       "def bar():\n"
       "    return foo()\n";
py::exec(my_code, py::globals(), my_module.attr("__dict__"));

py::print(my_module.attr("foo")()); // Prints "4" as expected
py::print(my_module.attr("bar")()); // Oops, "NameError: global name 'foo' is not defined"
@martinRenou martinRenou changed the title Defining multiple functions in a module created with py::module constructor missing __builtins__ in the scope with py::exec Jan 7, 2019
@martinRenou
Copy link
Contributor Author

According to the Python documentation

Remember that at module level, globals and locals are the same dictionary.

This means that in my case, the code should be:

py::module my_module("my_module");
std::string my_code = "\n"
       "def foo():\n"
       "    return 4\n"
       "\n"
       "def bar():\n"
       "    return foo()\n";
py::exec(my_code, my_module.attr("__dict__"), my_module.attr("__dict__"));

The problem is that it won't be possible to use builtins functions, or even the import keyword. Because the __builtins__ key is not in the my_module.attr("__dict__") dictionary. Which means that this part of the documentation is not implemented in py::exec:

If the globals dictionary does not contain a value for the key builtins, a reference to the dictionary of the built-in module builtins is inserted under that key.

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 a pull request may close this issue.

1 participant