=== modified file 'setup.py'
--- setup.py	2011-07-04 23:21:42 +0000
+++ setup.py	2012-01-11 21:50:11 +0000
@@ -20,6 +20,8 @@
     """
     Get all extensions from core and all subprojects.
     """
+    from twisted.python.compat import execfile
+
     extensions = []
 
     if not sys.platform.startswith('java'):

=== modified file 'twisted/lore/htmlbook.py'
--- twisted/lore/htmlbook.py	2011-02-14 04:45:15 +0000
+++ twisted/lore/htmlbook.py	2012-01-11 21:50:11 +0000
@@ -1,6 +1,8 @@
 # Copyright (c) Twisted Matrix Laboratories.
 # See LICENSE for details.
 
+from twisted.python.compat import execfile
+
 
 def getNumber(filename):
     return None
@@ -24,7 +26,7 @@
         Index = self.Index
 
         if filename:
-            execfile(filename)
+            execfile(filename, globals())
 
     def getFiles(self):
         return [c[0] for c in self.chapters]

=== modified file 'twisted/names/authority.py'
--- twisted/names/authority.py	2011-02-14 04:45:15 +0000
+++ twisted/names/authority.py	2012-01-11 21:50:11 +0000
@@ -12,6 +12,7 @@
 from twisted.names import dns
 from twisted.internet import defer
 from twisted.python import failure
+from twisted.python.compat import execfile
 
 import common
 

=== modified file 'twisted/python/_release.py'
--- twisted/python/_release.py	2011-11-20 15:23:17 +0000
+++ twisted/python/_release.py	2012-01-11 21:50:11 +0000
@@ -25,6 +25,7 @@
 from twisted.python.versions import Version
 from twisted.python.filepath import FilePath
 from twisted.python.dist import twisted_subprojects
+from twisted.python.compat import execfile
 
 # This import is an example of why you shouldn't use this module unless you're
 # radix

=== modified file 'twisted/python/compat.py'
--- twisted/python/compat.py	2011-06-03 21:55:35 +0000
+++ twisted/python/compat.py	2012-01-11 21:49:26 +0000
@@ -139,12 +139,12 @@
                   'set_connect_state', 'set_accept_state',
                   'connect_ex', 'sendall'):
 
-            exec """def %s(self, *args):
+            exec("""def %s(self, *args):
                 self._lock.acquire()
                 try:
                     return apply(self._ssl_conn.%s, args)
                 finally:
-                    self._lock.release()\n""" % (f, f)
+                    self._lock.release()\n""" % (f, f))
 sys.modules['OpenSSL.tsafe'] = tsafe
 
 import operator
@@ -175,3 +175,40 @@
     from functools import reduce
 except ImportError:
     reduce = reduce
+
+
+try:
+    _execfile = execfile
+except NameError:
+    _execfile = None
+
+
+def execfile(filename, globals, locals=None):
+    """Execute a Python script in the given namespaces.
+
+    Similar to the execfile builtin, but a namespace is mandatory, partly
+    because that's a sensible thing to require, and because otherwise we'd
+    have to do some frame hacking.
+
+    This is a compatibility wrapper for Python 3 porting.
+    """
+    if locals is None:
+        locals = globals
+    if _execfile is None:
+        fin = open(filename, "rb")
+        try:
+            source = fin.read()
+        finally:
+            fin.close()
+        code = compile(source, filename, "exec")
+        exec(code, globals, locals)
+    else:
+        _execfile(filename, globals, locals)
+
+
+__all__ = [
+    "execfile",
+    "frozenset",
+    "reduce",
+    "set",
+    ]

=== modified file 'twisted/python/dist.py'
--- twisted/python/dist.py	2011-11-20 15:19:42 +0000
+++ twisted/python/dist.py	2012-01-11 21:50:11 +0000
@@ -15,6 +15,8 @@
 import platform
 import sys
 
+from twisted.python.compat import execfile
+
 
 twisted_subprojects = ["conch", "lore", "mail", "names",
                        "news", "pair", "runner", "web",

=== modified file 'twisted/python/test/test_release.py'
--- twisted/python/test/test_release.py	2011-07-14 18:05:14 +0000
+++ twisted/python/test/test_release.py	2012-01-11 21:51:37 +0000
@@ -20,7 +20,7 @@
 
 from twisted.trial.unittest import TestCase
 
-from twisted.python.compat import set
+from twisted.python.compat import execfile, set
 from twisted.python.procutils import which
 from twisted.python import release
 from twisted.python.filepath import FilePath

=== modified file 'twisted/test/test_compat.py'
--- twisted/test/test_compat.py	2011-07-14 18:05:14 +0000
+++ twisted/test/test_compat.py	2012-01-11 22:44:32 +0000
@@ -6,11 +6,11 @@
 Tests for L{twisted.python.compat}.
 """
 
-import types, socket
+import os, tempfile, types, socket
 
 from twisted.trial import unittest
 
-from twisted.python.compat import set, frozenset, reduce
+from twisted.python.compat import set, frozenset, reduce, execfile
 
 
 
@@ -197,3 +197,38 @@
         """
         self.assertEqual(15, reduce(lambda x, y: x + y, [1, 2, 3, 4, 5]))
         self.assertEqual(16, reduce(lambda x, y: x + y, [1, 2, 3, 4, 5], 1))
+
+
+class ExecfileCompatTestCase(unittest.TestCase):
+    """Tests for the L{execfile} compatibility wrapper."""
+
+    def setUp(self):
+        super(ExecfileCompatTestCase, self).setUp()
+        fd, self.script = tempfile.mkstemp(".py")
+        fout = os.fdopen(fd, "wb")
+        try:
+            fout.write("foo += 1\n".encode("ascii"))
+        finally:
+            fout.close()
+
+    def tearDown(self):
+        super(ExecfileCompatTestCase, self).tearDown()
+        os.unlink(self.script)
+
+    def test_execfileGlobals(self):
+        """
+        L{execfile} executes the specified file in the given global namespace.
+        """
+        ns_global = {"foo": 1}
+        execfile(self.script, ns_global)
+        self.assertEqual(2, ns_global["foo"])
+
+    def test_execfileGlobalsAndLocals(self):
+        """
+        L{execfile} executes the specified file in the given global and local
+        namespaces.
+        """
+        ns_global, ns_local = {"foo": 10}, {"foo": 20}
+        execfile(self.script, ns_global, ns_local)
+        self.assertEqual(10, ns_global["foo"])
+        self.assertEqual(21, ns_local["foo"])

=== added file 'twisted/topfiles/5129.misc'
--- twisted/topfiles/5129.misc	1970-01-01 00:00:00 +0000
+++ twisted/topfiles/5129.misc	2012-01-11 21:50:34 +0000
@@ -0,0 +1,3 @@
+Replace usage of execfile() with t.p.compat.execfile(), a new function
+that wraps execfile() on Python 2.x and provides equivalent
+functionality on Python 3.x.

=== modified file 'twisted/web/script.py'
--- twisted/web/script.py	2011-02-14 04:45:15 +0000
+++ twisted/web/script.py	2012-01-11 21:50:11 +0000
@@ -14,6 +14,7 @@
     import StringIO
 
 from twisted import copyright
+from twisted.python.compat import execfile
 from twisted.web import http, server, static, resource, html
 
 

