From d9a1617d0067f31ae8c20afcf0a52570a6a3c0fe Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Tue, 16 Apr 2019 16:17:57 -0700 Subject: [PATCH] scripts: Fix exec invocation for in-process virtualenv activation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit activate_this.py has always documented that it should be exec()ed with locals = globals, and in virtualenv 16.0.0 it raises a NameError otherwise. As a simplified demonstration of the weird things that can go wrong when locals ≠ globals: >>> exec('a = 1; print([a])', {}, {}) [1] >>> exec('a = 1; print([a for b in [1]])', {}, {}) Traceback (most recent call last): File "", line 1, in File "", line 1, in File "", line 1, in NameError: name 'a' is not defined >>> exec('a = 1; print([a for b in [1]])', {}) [1] Top-level assignments go into locals, but from inside a new scope like a list comprehension, they’re read out of globals, which doesn’t work. Fixes #12030. Signed-off-by: Anders Kaseorg --- scripts/lib/setup_path_on_import.py | 2 +- tools/lib/provision.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/lib/setup_path_on_import.py b/scripts/lib/setup_path_on_import.py index 3cd8a65d7e..f38d44e5e1 100644 --- a/scripts/lib/setup_path_on_import.py +++ b/scripts/lib/setup_path_on_import.py @@ -13,6 +13,6 @@ if sys.prefix != venv: # this file will exist in production if os.path.exists(activate_this): activate_locals = dict(__file__=activate_this) - exec(open(activate_this).read(), {}, activate_locals) + exec(open(activate_this).read(), activate_locals) if not os.path.exists(activate_locals["site_packages"]): raise RuntimeError(venv + " was not set up for this Python version") diff --git a/tools/lib/provision.py b/tools/lib/provision.py index a9e2822ff3..03c6b83a63 100755 --- a/tools/lib/provision.py +++ b/tools/lib/provision.py @@ -393,7 +393,7 @@ def main(options): setup_venvs.main() activate_this = "/srv/zulip-py3-venv/bin/activate_this.py" - exec(open(activate_this).read(), {}, dict(__file__=activate_this)) + exec(open(activate_this).read(), dict(__file__=activate_this)) setup_shell_profile('~/.bash_profile') setup_shell_profile('~/.zprofile')