ipython: Global variables undefined in interactive use of embedded ipython shell
Original Launchpad bug 399627: https://bugs.launchpad.net/ipython/+bug/399627 Reported by: h-fangohr (Hans Fangohr).
The error can be reproduced as follows:
- Start Python, and start embedded ipython session. Following ipython’s manual, we do
fangohr@eta:~$ python
Python 2.4.3 (#1, Jun 8 2009, 14:09:06)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from IPython.Shell import IPShellEmbed
>>> ipshell=IPShellEmbed()
>>> ipshell()
Within the just started ipython session, global variables are sometimes not visible. Two examples are:
Example 1:
In [1]: a=1
In [2]: def f(x):
...: return a*x
...:
In [3]: f(2)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/home/fangohr/<ipython console>
/home/fangohr/<ipython console> in f(x)
NameError: global name 'a' is not defined
Example 2:
In [4]: b=1
In [5]: (lambda :b)()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/home/fangohr/<ipython console>
/home/fangohr/<ipython console> in <lambda>()
NameError: global name 'b' is not defined
There is no error if “b=1; (lambda :b)()” is put in a script, and this script is executed using ipython’s “run” command.
There is no error if “b=1; (lambda :b)()” is executed interactively after having started ipython.
The only way the error seems comes up is if an embedded IPython shell is started from a Python prompt AND the commands are executed interactively at the prompt.
I find the same error when trying ipython-0.9.1 (with python2.4).
The bug was reported by Olivier Klein to the nmag team (http://nmag.soton.ac.uk).
About this issue
- Original URL
- State: open
- Created 14 years ago
- Reactions: 6
- Comments: 39 (17 by maintainers)
Commits related to this issue
- Back-port of fix for globals in shell. Direct back-port of a fix released in Django 1.6: https://github.com/django/django/commit/3570ff734e93f493e023b912c9a97101f605f7f5 An official discussion and d... — committed to theatlantic/django by OaklandPeters 9 years ago
- Switch from 'embedding' to 'starting' IPython Embedding IPython results in issues where import statements and other globals changes in the shell environment don't work as expected.[1] As an example, ... — committed to kemitche/baseplate.py by kemitche 4 years ago
- Switch from 'embedding' to 'starting' IPython Embedding IPython results in issues where import statements and other globals changes in the shell environment don't work as expected.[1] As an example, ... — committed to kemitche/baseplate.py by kemitche 4 years ago
- Switch from 'embedding' to 'starting' IPython Embedding IPython results in issues where import statements and other globals changes in the shell environment don't work as expected.[1] As an example, ... — committed to kemitche/baseplate.py by kemitche 4 years ago
- Switch from 'embedding' to 'starting' IPython (#507) Embedding IPython results in issues where import statements and other globals changes in the shell environment don't work as expected.[1] As an ... — committed to reddit/baseplate.py by kemitche 4 years ago
- debugshell: make globals() match locals() in interactive shell Summary: This fixes issues like https://github.com/ipython/ipython/issues/62. Reviewed By: zzl0 Differential Revision: D44759311 fbsh... — committed to facebook/sapling by quark-zju a year ago
As noted at https://github.com/inducer/pudb/issues/103, a temporary workaround while using an embedded shell is:
globals().update(locals())
(after defining the locally global variables, only).I don’t understand, and it makes me angry.
Yup, I think it was fixed for Django 1.6. If you really can’t upgrade, you might want to apply the fix manually. It looks like this was it: https://github.com/django/django/commit/3570ff734e93f493e023b912c9a97101f605f7f5
AFAIK, my comments from a few years ago stand:
I believe we are limited by the way Python itself works. Closures and dynamic evaluation don’t play well together, and IPython can’t fix it. People have found workarounds to move local variables to a global namespace, but those are hacks which can cause other problems, because they’re modifying the global namespace. I don’t plan on putting such workarounds into IPython; I’d rather leave an issue with something we’re not doing than introduce one by trying to be too clever.
Many places where people thought they wanted
embed()
, they should actually usestart_ipython()
instead and avoid this kind of issue.If I recall correctly, this was fixed for a little while, and seems to be reintroduced (reproduced using IPython 5.1.0 on macOS here: https://git.io/vPDrJ).
(edit: I may be mis-remembering the fix. It’s possible I just threw everything I needed into a startup file instead of using embed)