Nested Scopes in Idle/PythonWin

Greg Chapman glc at well.com
Sat Apr 21 15:24:17 EDT 2001


It appears that nested scopes are not turned on by default in the
interactive interpreters of Idle and PythonWin (using Python 2.1 under
Windows 2000).  Since this feature is to be mandatory in the next release of
Python, it seems to me that it ought to be on by default (or at least that
there should be some way to turn it on) in the interactive interpreters.
After much staring at the source code, the following patch appears to me to
be the best way to enable nested scopes in Idle, but I don't much like it.
I wonder if anyone else has a better idea.

--- C:\Python21\Tools\idle\PyShell.py.orig	Wed Mar 28 22:30:32 2001
+++ C:\Python21\Tools\idle\PyShell.py	Sat Apr 21 12:09:38 2001
@@ -150,8 +150,33 @@
         except TclError:
             pass
         UndoDelegator.delete(self, index1, index2)

+#nested scopes support -- begin
+import code
+compile_command = code.compile_command
+nested_scopes = "from __future__ import nested_scopes\n"
+
+# compile_command_nested wraps the compile_command function used by the
code module.
+# If compile_command raises a SyntaxError which contains the word
"shadows", it is
+# assumed that it is the error generated at the end of
symtable_check_shadow in compile.c
+# (the only use of "shadows" in the Python source hierarchy except for one
use in
+# python-mode.el).  If it gets this error, it retries the compile with
nested_scopes,
+# using "exec" mode.  I believe this error can only be raised when defining
a global
+# function or a class method, and I think compile behaves the same for
"single" and
+# "exec" when compiling a class or a def.
+
+def compile_command_nested(source, filename="<input>", symbol="single"):
+    try:
+        return compile_command(source, filename, symbol)
+    except SyntaxError, err:
+        if str(err).find("shadows") >= 0:
+            return compile_command(nested_scopes+source, filename, "exec")
+        else:
+            raise
+
+#nested scopes support -- end
+
 class ModifiedInterpreter(InteractiveInterpreter):

     def __init__(self, tkconsole):
         self.tkconsole = tkconsole
@@ -184,9 +209,13 @@
         self.more = 0
         self.save_warnings_filters = warnings.filters[:]
         warnings.filterwarnings(action="error", category=SyntaxWarning)
         try:
-            return InteractiveInterpreter.runsource(self, source, filename)
+            code.compile_command = compile_command_nested
+            try:
+                return InteractiveInterpreter.runsource(self, source,
filename)
+            finally:
+                code.compile_command = compile_command
         finally:
             if self.save_warnings_filters is not None:
                 warnings.filters[:] = self.save_warnings_filters
                 self.save_warnings_filters = None





More information about the Python-list mailing list