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

Persistence of variables when executing separate exec calls #9

Open
carlosuc3m opened this issue Nov 20, 2023 · 1 comment
Open

Persistence of variables when executing separate exec calls #9

carlosuc3m opened this issue Nov 20, 2023 · 1 comment
Milestone

Comments

@carlosuc3m
Copy link

carlosuc3m commented Nov 20, 2023

Currently Appose is not able to access the variables that where created in the same Python Service on previous Tasks.
This means that if we do:

Environment env = new Environment() {
			@Override public String base() { return envPath; }
			@Override public boolean useSystemPath() { return false; }
			};
Service python = env.python();

Task task1 = python.task("a=5")
task1.waitFor()
Task task2 = python.task("a + a")
task2.waitFor()

I will get an error saying that the variable a is not defined

  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'a' is not defined

The error is caused by the following line:
https://github.com/apposed/appose-python/blob/ed37c651084601d201e7dc7c8e8bb5b5f72e0d70/src/appose/python_worker.py#L108

This line is setting the globals to be empty, that is that there are no global variables defined for the Python code that is going to be executed. That line should be:

_globals = None

Which instead is interpreted as that we are not setting any global variables in the scope.

To test the behaviour try the following:

exec("a=5", None, None)
exec("print(a)", None, None)

Output:

5

and compare to:

exec("a=5", {}, {})
exec("print(a)", {}, {})

Output:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>

However, weirdly, in Appose in order to get this to work, the variables created in one task need to be set explicitly as a global variable to be accessible in other tasks.

globals()['np'] = np
@carlosuc3m
Copy link
Author

Hello, I deleted my previous comment because it was completely wrong, I had not understood anything.

After reading the docs (probaly I should have done it way earlier) I realised that setting both globals and locals is equivalent to inserting the piece of code in the script. It basically makes the code in the script share locals and globals with the program the exec is embedded in.
This is why if we do:

exec("a=5", None, None)
exec("print(a)", None, None)

It works.

However, whenever we set globals or locals, it will not work anymore, because now the exec has its own variables.
In addition if we do the following:

>>> _globals = {}
>>> _locals = {}
>>> exec("a=5", _globals, _locals)
>>> exec("print(a)", _globals, _locals)
5
>>> _locals
{'a': 5}

It seems that the new variables created in the scope of exec are added to the globals locals dictionary and not the globals. We still can add the to the globals by doing globals()["a"] = a.

With this in mind I think it might make sense to keep track of the globals and locals as attributes of the python service to guarantee variable consistency among tasks.

What do you think?

@ctrueden ctrueden added this to the 0.1.1 milestone Aug 10, 2024
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

No branches or pull requests

2 participants