From a953d91d7229deb2af3b1609772fccb915c50e4d 2008-09-14 21:27:44
From: Fernando Perez <Fernando.Perez@berkeley.edu>
Date: 2008-09-14 21:27:44
Subject: [PATCH] Partial fixes for 2.4 compatibility.  Unfinished.

We just discovered that 0.9 breaks with python 2.4.  This is an
attempt at fixing the problem, but I'm not finished yet.  Pushing so
others can work off my branch.

---

diff --git a/IPython/Release.py b/IPython/Release.py
index 3cc40eb..06783bf 100644
--- a/IPython/Release.py
+++ b/IPython/Release.py
@@ -21,7 +21,7 @@ name = 'ipython'
 # bdist_deb does not accept underscores (a Debian convention).
 
 development = False    # change this to False to do a release
-version_base = '0.9'
+version_base = '0.9.1'
 branch = 'ipython'
 revision = '1143'
 
diff --git a/IPython/frontend/frontendbase.py b/IPython/frontend/frontendbase.py
index 9f98dcf..8821fa8 100644
--- a/IPython/frontend/frontendbase.py
+++ b/IPython/frontend/frontendbase.py
@@ -21,8 +21,77 @@ __docformat__ = "restructuredtext en"
 # Imports
 #-------------------------------------------------------------------------------
 import string
-import uuid
-import _ast
+
+try:
+    import _ast
+except ImportError:
+    # Python 2.4 hackish workaround.
+    class bunch: pass
+    _ast = bunch()
+    _ast.PyCF_ONLY_AST = 1024
+    
+
+
+try:
+    import uuid
+except ImportError:
+    # Python 2.4 hackish workaround.
+    class UUID:
+        def __init__(self,bytes):
+            version = 4
+            int = long(('%02x'*16) % tuple(map(ord, bytes)), 16)
+            # Set the variant to RFC 4122.
+            int &= ~(0xc000 << 48L)
+            int |= 0x8000 << 48L
+            # Set the version number.
+            int &= ~(0xf000 << 64L)
+            int |= version << 76L
+            self.__dict__['int'] = int
+
+        def __cmp__(self, other):
+            if isinstance(other, UUID):
+                return cmp(self.int, other.int)
+            return NotImplemented
+
+        def __hash__(self):
+            return hash(self.int)
+
+        def __int__(self):
+            return self.int
+
+        def __repr__(self):
+            return 'UUID(%r)' % str(self)
+
+        def __setattr__(self, name, value):
+            raise TypeError('UUID objects are immutable')
+
+        def __str__(self):
+            hex = '%032x' % self.int
+            return '%s-%s-%s-%s-%s' % (
+                hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:])
+
+        def get_bytes(self):
+            bytes = ''
+            for shift in range(0, 128, 8):
+                bytes = chr((self.int >> shift) & 0xff) + bytes
+            return bytes
+
+        bytes = property(get_bytes)
+ 
+    
+    def _u4():
+        "Fake random uuid"
+        
+        import random
+        bytes = [chr(random.randrange(256)) for i in range(16)]
+        return UUID(bytes)
+
+    class bunch: pass
+    uuid = bunch()
+    uuid.uuid4 = _u4
+    del _u4
+
+
 
 from IPython.frontend.zopeinterface import (
     Interface, 
diff --git a/IPython/frontend/linefrontendbase.py b/IPython/frontend/linefrontendbase.py
index 494fc71..a154e13 100644
--- a/IPython/frontend/linefrontendbase.py
+++ b/IPython/frontend/linefrontendbase.py
@@ -182,16 +182,29 @@ class LineFrontEndBase(FrontEndBase):
             raw_string = python_string
         # Create a false result, in case there is an exception
         self.last_result = dict(number=self.prompt_number)
+
+        ## try:
+        ##     self.history.input_cache[-1] = raw_string.rstrip()
+        ##     result = self.shell.execute(python_string)
+        ##     self.last_result = result
+        ##     self.render_result(result)
+        ## except:
+        ##     self.show_traceback()
+        ## finally:
+        ##     self.after_execute()
+
         try:
-            self.history.input_cache[-1] = raw_string.rstrip()
-            result = self.shell.execute(python_string)
-            self.last_result = result
-            self.render_result(result)
-        except:
-            self.show_traceback()
+            try:
+                self.history.input_cache[-1] = raw_string.rstrip()
+                result = self.shell.execute(python_string)
+                self.last_result = result
+                self.render_result(result)
+            except:
+                self.show_traceback()
         finally:
             self.after_execute()
 
+
     #--------------------------------------------------------------------------
     # LineFrontEndBase interface
     #--------------------------------------------------------------------------
diff --git a/IPython/frontend/prefilterfrontend.py b/IPython/frontend/prefilterfrontend.py
index ad6ce13..440d3e2 100644
--- a/IPython/frontend/prefilterfrontend.py
+++ b/IPython/frontend/prefilterfrontend.py
@@ -196,17 +196,33 @@ This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""
         # capture it.
         self.capture_output()
         self.last_result = dict(number=self.prompt_number)
+        
+        ## try:
+        ##     for line in input_string.split('\n'):
+        ##         filtered_lines.append(
+        ##                 self.ipython0.prefilter(line, False).rstrip())
+        ## except:
+        ##     # XXX: probably not the right thing to do.
+        ##     self.ipython0.showsyntaxerror()
+        ##     self.after_execute()
+        ## finally:
+        ##     self.release_output()
+
+
         try:
-            for line in input_string.split('\n'):
-                filtered_lines.append(
-                        self.ipython0.prefilter(line, False).rstrip())
-        except:
-            # XXX: probably not the right thing to do.
-            self.ipython0.showsyntaxerror()
-            self.after_execute()
+            try:
+                for line in input_string.split('\n'):
+                    filtered_lines.append(
+                            self.ipython0.prefilter(line, False).rstrip())
+            except:
+                # XXX: probably not the right thing to do.
+                self.ipython0.showsyntaxerror()
+                self.after_execute()
         finally:
             self.release_output()
 
+
+
         # Clean up the trailing whitespace, to avoid indentation errors
         filtered_string = '\n'.join(filtered_lines)
         return filtered_string
diff --git a/IPython/frontend/zopeinterface.py b/IPython/frontend/zopeinterface.py
index fd37101..9bb726a 100644
--- a/IPython/frontend/zopeinterface.py
+++ b/IPython/frontend/zopeinterface.py
@@ -19,10 +19,6 @@ __docformat__ = "restructuredtext en"
 #-------------------------------------------------------------------------------
 # Imports
 #-------------------------------------------------------------------------------
-import string
-import uuid
-import _ast
-
 try:
     from zope.interface import Interface, Attribute, implements, classProvides
 except ImportError:
diff --git a/IPython/kernel/contexts.py b/IPython/kernel/contexts.py
index 553f140..949688e 100644
--- a/IPython/kernel/contexts.py
+++ b/IPython/kernel/contexts.py
@@ -8,8 +8,6 @@ which can also be useful as templates for writing new, application-specific
 managers.
 """
 
-from __future__ import with_statement
-
 __docformat__ = "restructuredtext en"
 
 #-------------------------------------------------------------------------------
diff --git a/IPython/kernel/tests/test_contexts.py b/IPython/kernel/tests/test_contexts.py
index 22590d0..2ef2dec 100644
--- a/IPython/kernel/tests/test_contexts.py
+++ b/IPython/kernel/tests/test_contexts.py
@@ -1,4 +1,6 @@
-from __future__ import with_statement
+#from __future__ import with_statement
+
+# XXX This file is currently disabled to preserve 2.4 compatibility.
 
 #def test_simple():
 if 0:
@@ -25,17 +27,17 @@ if 0:
 
     mec.pushAll()
 
-    with parallel as pr:
-        # A comment
-        remote()  # this means the code below only runs remotely
-        print 'Hello remote world'
-        x = range(10)
-        # Comments are OK
-        # Even misindented.
-        y = x+1
+    ## with parallel as pr:
+    ##     # A comment
+    ##     remote()  # this means the code below only runs remotely
+    ##     print 'Hello remote world'
+    ##     x = range(10)
+    ##     # Comments are OK
+    ##     # Even misindented.
+    ##     y = x+1
 
 
-    with pfor('i',sequence) as pr:
-        print x[i]
+    ## with pfor('i',sequence) as pr:
+    ##     print x[i]
 
     print pr.x + pr.y
diff --git a/docs/examples/kernel/nwmerge.py b/docs/examples/kernel/nwmerge.py
index 32447a2..4723501 100644
--- a/docs/examples/kernel/nwmerge.py
+++ b/docs/examples/kernel/nwmerge.py
@@ -45,7 +45,10 @@ def mergesort(list_of_lists, key=None):
     for i, itr in enumerate(iter(pl) for pl in list_of_lists):
         try:
             item = itr.next()
-            toadd = (key(item), i, item, itr) if key else (item, i, itr)
+            if key:
+                toadd = (key(item), i, item, itr)
+            else:
+                toadd = (item, i, itr)
             heap.append(toadd)
         except StopIteration:
             pass
diff --git a/tools/testrel b/tools/testrel
index 3ead49f..b6901e2 100755
--- a/tools/testrel
+++ b/tools/testrel
@@ -15,8 +15,8 @@ cd $ipdir
 ./setup.py sdist --formats=gztar
 
 # Build rpms
-#python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4
-#python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5
+python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4
+python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5
 
 # Build eggs
 python2.4 ./setup_bdist_egg.py