[Checkins] SVN: zope.interface/branches/regebro-python3/ Fixed up the automatic 2to3 conversion for testing.

Lennart Regebro regebro at gmail.com
Mon Mar 30 18:56:33 EDT 2009


Log message for revision 98654:
  Fixed up the automatic 2to3 conversion for testing.
  

Changed:
  A   zope.interface/branches/regebro-python3/build_ext_2.py
  A   zope.interface/branches/regebro-python3/build_ext_3.py
  U   zope.interface/branches/regebro-python3/setup.py
  U   zope.interface/branches/regebro-python3/src/zope/interface/advice.py
  U   zope.interface/branches/regebro-python3/src/zope/interface/declarations.py
  U   zope.interface/branches/regebro-python3/src/zope/interface/interface.py
  U   zope.interface/branches/regebro-python3/src/zope/interface/tests/__init__.py

-=-
Added: zope.interface/branches/regebro-python3/build_ext_2.py
===================================================================
--- zope.interface/branches/regebro-python3/build_ext_2.py	                        (rev 0)
+++ zope.interface/branches/regebro-python3/build_ext_2.py	2009-03-30 22:56:33 UTC (rev 98654)
@@ -0,0 +1,38 @@
+import sys
+from distutils.errors import (CCompilerError, DistutilsExecError, 
+                              DistutilsPlatformError)
+try:
+    from setuptools.command.build_ext import build_ext
+except ImportError:
+    from distutils.command.build_ext import build_ext
+    
+
+class optional_build_ext(build_ext):
+    """This class subclasses build_ext and allows
+       the building of C extensions to fail.
+    """
+    def run(self):
+        try:
+            build_ext.run(self)
+        
+        except DistutilsPlatformError, e:
+            self._unavailable(e)
+
+    def build_extension(self, ext):
+        try:
+            build_ext.build_extension(self, ext)
+        
+        except (CCompilerError, DistutilsExecError), e:
+            self._unavailable(e)
+
+    def _unavailable(self, e):
+        print >> sys.stderr, '*' * 80
+        print >> sys.stderr, """WARNING:
+
+        An optional code optimization (C extension) could not be compiled.
+
+        Optimizations for this package will not be available!"""
+        print >> sys.stderr
+        print >> sys.stderr, e
+        print >> sys.stderr, '*' * 80
+        
\ No newline at end of file

Added: zope.interface/branches/regebro-python3/build_ext_3.py
===================================================================
--- zope.interface/branches/regebro-python3/build_ext_3.py	                        (rev 0)
+++ zope.interface/branches/regebro-python3/build_ext_3.py	2009-03-30 22:56:33 UTC (rev 98654)
@@ -0,0 +1,167 @@
+import os
+import sys
+from distutils.errors import (CCompilerError, DistutilsExecError, 
+                              DistutilsPlatformError)
+try:
+    from setuptools.command.build_ext import build_ext
+    from pkg_resources import (normalize_path, working_set, 
+                               add_activation_listener, require)
+except ImportError:
+    from distutils.command.build_ext import build_ext
+    
+
+class optional_build_ext(build_ext):
+    """This class subclasses build_ext and allows
+       the building of C extensions to fail.
+    """
+    def run(self):
+        try:
+            build_ext.run(self)
+        
+        except DistutilsPlatformError as e:
+            self._unavailable(e)
+
+    def build_extension(self, ext):
+        try:
+            build_ext.build_extension(self, ext)
+        
+        except (CCompilerError, DistutilsExecError) as e:
+            self._unavailable(e)
+
+    def _unavailable(self, e):
+        print('*' * 80, file=sys.stderr)
+        print("""WARNING:
+
+        An optional code optimization (C extension) could not be compiled.
+
+        Optimizations for this package will not be available!""", file=sys.stderr)
+        print(file=sys.stderr)
+        print(e, file=sys.stderr)
+        print('*' * 80, file=sys.stderr)
+        
+        
+try:
+    from distutils import log
+    # These should be a part of the Python 3 setuptools port
+    def run_2to3(files, fixer_names=None, options=None, explicit=None, doctests_only=False):
+        """Invoke 2to3 on a list of Python files.
+        The files should all come from the build area, as the
+        modification is done in-place. To reduce the build time,
+        only files modified since the last invocation of this
+        function should be passed in the files argument."""
+    
+        if not files:
+            return
+    
+        # Make this class local, to delay import of 2to3
+        from lib2to3.refactor import RefactoringTool, get_fixers_from_package
+        class DistutilsRefactoringTool(RefactoringTool):
+            def log_error(self, msg, *args, **kw):
+                log.error(msg, *args)
+    
+            def log_message(self, msg, *args):
+                log.info(msg, *args)
+    
+            def log_debug(self, msg, *args):
+                log.debug(msg, *args)
+    
+        if fixer_names is None:
+            fixer_names = get_fixers_from_package('lib2to3.fixes')
+        r = DistutilsRefactoringTool(fixer_names, options=options)
+        r.refactor(files, write=True, doctests_only=doctests_only)
+        
+    class Mixin2to3:
+        '''Mixin class for commands that run 2to3.
+        To configure 2to3, setup scripts may either change
+        the class variables, or inherit from individual commands
+        to override how 2to3 is invoked.'''
+    
+        # provide list of fixers to run;
+        # defaults to all from lib2to3.fixers
+        fixer_names = None
+    
+        # options dictionary
+        options = None
+    
+        # list of fixers to invoke even though they are marked as explicit
+        explicit = None
+    
+        def run_2to3(self, files, doctests_only=False):
+            return run_2to3(files, self.fixer_names, self.options, 
+                            self.explicit, doctests_only=doctests_only)
+
+    from setuptools.command.test import test
+    class test_2to3(test):
+        def with_project_on_sys_path(self, func):
+            # Ensure metadata is up-to-date
+            self.reinitialize_command('build_py', inplace=0)
+            self.run_command('build_py')
+            bpy_cmd = self.get_finalized_command("build_py")
+            build_path = normalize_path(bpy_cmd.build_lib)
+            
+            self.reinitialize_command('egg_info', egg_base=build_path)
+            self.run_command('egg_info')
+            
+            self.reinitialize_command('build_ext', inplace=0)
+            self.run_command('build_ext')
+    
+            ei_cmd = self.get_finalized_command("egg_info")
+    
+            old_path = sys.path[:]
+            old_modules = sys.modules.copy()
+    
+            try:
+                sys.path.insert(0, build_path)
+                working_set.__init__()
+                add_activation_listener(lambda dist: dist.activate())
+                require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version))
+                func()
+            finally:
+                sys.path[:] = old_path
+                sys.modules.clear()
+                sys.modules.update(old_modules)
+                working_set.__init__()
+        
+    from setuptools.command.build_py import build_py
+    
+    class build_py_2to3(build_py, Mixin2to3):
+        def run(self):
+            self.updated_files = []
+            self.possible_doctests = []
+    
+            # Base class code
+            if self.py_modules:
+                self.build_modules()
+            if self.packages:
+                self.build_packages()
+                self.build_package_data()
+    
+            # 2to3
+            self.run_2to3(self.updated_files)
+            self.run_2to3(self.possible_doctests, doctests_only=True)
+    
+            # Remaining base class code
+            self.byte_compile(self.get_outputs(include_bytecode=0))
+    
+        def build_module(self, module, module_file, package):
+            res = build_py.build_module(self, module, module_file, package)
+            if res[1]:
+                # file was copied
+                self.updated_files.append(res[0])
+            return res
+        
+        def build_package_data(self):
+            """Copy data files into build directory"""
+            lastdir = None
+            for package, src_dir, build_dir, filenames in self.data_files:
+                for filename in filenames:
+                    target = os.path.join(build_dir, filename)
+                    self.mkpath(os.path.dirname(target))
+                    res = self.copy_file(os.path.join(src_dir, filename), target,
+                                         preserve_mode=False)
+                    if res[1]:
+                        # file was copied
+                        self.possible_doctests.append(res[0])
+    
+except ImportError:
+    pass
\ No newline at end of file

Modified: zope.interface/branches/regebro-python3/setup.py
===================================================================
--- zope.interface/branches/regebro-python3/setup.py	2009-03-30 22:42:27 UTC (rev 98653)
+++ zope.interface/branches/regebro-python3/setup.py	2009-03-30 22:56:33 UTC (rev 98654)
@@ -18,17 +18,12 @@
 
 import os, sys
 
-from distutils.errors import (CCompilerError, DistutilsExecError, 
-                              DistutilsPlatformError)
-
 try:
     from setuptools import setup, Extension, Feature
-    from setuptools.command.build_ext import build_ext
-except ImportError, e:
+except ImportError:
     # do we need to support plain distutils for building when even
     # the package itself requires setuptools for installing?
     from distutils.core import setup, Extension
-    from distutils.command.build_ext import build_ext
 
     if sys.version_info[:2] >= (2, 4):
         extra = dict(
@@ -82,37 +77,22 @@
         '********\n'
         )
 
-
-class optional_build_ext(build_ext):
-    """This class subclasses build_ext and allows
-       the building of C extensions to fail.
-    """
-    def run(self):
-        try:
-            build_ext.run(self)
-        
-        except DistutilsPlatformError, e:
-            self._unavailable(e)
-
-    def build_extension(self, ext):
-       try:
-           build_ext.build_extension(self, ext)
-        
-       except (CCompilerError, DistutilsExecError), e:
-           self._unavailable(e)
-
-    def _unavailable(self, e):
-        print >> sys.stderr, '*' * 80
-        print >> sys.stderr, """WARNING:
-
-        An optional code optimization (C extension) could not be compiled.
-
-        Optimizations for this package will not be available!"""
-        print >> sys.stderr
-        print >> sys.stderr, e
-        print >> sys.stderr, '*' * 80
+try: # Zope 3 setuptools versions
+    from build_ext_3 import build_py_2to3 as build_py
+    from build_ext_3 import optional_build_ext
+    from build_ext_3 import test_2to3 as test
+except (ImportError, SyntaxError):
+    try: # Zope 2 setuptools versions
+        from setuptools.command.build_py import build_py
+        from setuptools.command.test import test
+        from build_ext_2 import optional_build_ext
+    except ImportError:
+        # Zope 2 distutils
+        from distutils.command.build_py import build_py
+        from distutils.command.test import test
+        from build_ext_2 import optional_build_ext
     
-
+        
 setup(name='zope.interface',
       version = '3.5.2dev',
       url='http://pypi.python.org/pypi/zope.interface',
@@ -122,8 +102,11 @@
       author_email='zope-dev at zope.org',
       long_description=long_description,
 
-      packages = ['zope', 'zope.interface'],
+      packages = ['zope', 'zope.interface', 'zope.interface.tests'],
       package_dir = {'': 'src'},
-      cmdclass = {'build_ext': optional_build_ext},
+      cmdclass = {'build_ext': optional_build_ext,
+                  'build_py': build_py,
+                  'test': test,
+                  },
       test_suite = 'zope.interface.tests',
       **extra)

Modified: zope.interface/branches/regebro-python3/src/zope/interface/advice.py
===================================================================
--- zope.interface/branches/regebro-python3/src/zope/interface/advice.py	2009-03-30 22:42:27 UTC (rev 98653)
+++ zope.interface/branches/regebro-python3/src/zope/interface/advice.py	2009-03-30 22:56:33 UTC (rev 98654)
@@ -27,7 +27,13 @@
 $Id$
 """
 
-from types import ClassType, FunctionType
+from types import FunctionType
+try:
+    from types import ClassType
+    __python3 = False
+except ImportError:
+    __python3 = True
+    
 import sys
 
 def getFrameInfo(frame):
@@ -102,7 +108,10 @@
     #    )
 
     previousMetaclass = caller_locals.get('__metaclass__')
-    defaultMetaclass  = caller_globals.get('__metaclass__', ClassType)
+    if __python3:
+        defaultMetaclass  = caller_globals.get('__metaclass__', type)
+    else:
+        defaultMetaclass  = caller_globals.get('__metaclass__', ClassType)
 
 
     def advise(name, bases, cdict):
@@ -111,11 +120,11 @@
             del cdict['__metaclass__']
 
         if previousMetaclass is None:
-             if bases:
-                 # find best metaclass or use global __metaclass__ if no bases
-                 meta = determineMetaclass(bases)
-             else:
-                 meta = defaultMetaclass
+            if bases:
+                # find best metaclass or use global __metaclass__ if no bases
+                meta = determineMetaclass(bases)
+            else:
+                meta = defaultMetaclass
 
         elif isClassAdvisor(previousMetaclass):
             # special case: we can't compute the "true" metaclass here,
@@ -162,6 +171,7 @@
 
     if not candidates:
         # they're all "classic" classes
+        assert(not __python3) # This should not happen under Python 3
         return ClassType
 
     elif len(candidates)>1:
@@ -175,7 +185,8 @@
 def minimalBases(classes):
     """Reduce a list of base classes to its ordered minimum equivalent"""
 
-    classes = [c for c in classes if c is not ClassType]
+    if not __python3:
+        classes = [c for c in classes if c is not ClassType]
     candidates = []
 
     for m in classes:

Modified: zope.interface/branches/regebro-python3/src/zope/interface/declarations.py
===================================================================
--- zope.interface/branches/regebro-python3/src/zope/interface/declarations.py	2009-03-30 22:42:27 UTC (rev 98653)
+++ zope.interface/branches/regebro-python3/src/zope/interface/declarations.py	2009-03-30 22:56:33 UTC (rev 98654)
@@ -33,7 +33,7 @@
 from zope.interface.interface import InterfaceClass, Specification
 from ro import mergeOrderings, ro
 import exceptions
-from types import ClassType, ModuleType
+from types import ModuleType
 from zope.interface.advice import addClassAdvisor
 
 # Registry of class-implementation specifications
@@ -755,8 +755,12 @@
     return spec
 Provides.__safe_for_unpickling__ = True
 
-
-DescriptorAwareMetaClasses = ClassType, type
+try:
+    from types import ClassType
+    DescriptorAwareMetaClasses = ClassType, type
+except ImportError: # Python 3
+    DescriptorAwareMetaClasses = (type,)
+    
 def directlyProvides(object, *interfaces):
     """Declare interfaces declared directly for an object
 

Modified: zope.interface/branches/regebro-python3/src/zope/interface/interface.py
===================================================================
--- zope.interface/branches/regebro-python3/src/zope/interface/interface.py	2009-03-30 22:42:27 UTC (rev 98653)
+++ zope.interface/branches/regebro-python3/src/zope/interface/interface.py	2009-03-30 22:56:33 UTC (rev 98654)
@@ -603,6 +603,7 @@
 
         for k, v in self.__attrs.items():
             if isinstance(v, Method) and not (k in dict):
+                import pdb;pdb.set_trace()
                 dict[k]=v
 
         for b in self.__bases__:

Modified: zope.interface/branches/regebro-python3/src/zope/interface/tests/__init__.py
===================================================================
--- zope.interface/branches/regebro-python3/src/zope/interface/tests/__init__.py	2009-03-30 22:42:27 UTC (rev 98653)
+++ zope.interface/branches/regebro-python3/src/zope/interface/tests/__init__.py	2009-03-30 22:56:33 UTC (rev 98654)
@@ -1,10 +1,8 @@
 #
 # This file is necessary to make this directory a package.
-
 import os
 import unittest
 
-
 def additional_tests():
     suites = unittest.TestSuite()
     for file in os.listdir(os.path.dirname(__file__)):



More information about the Checkins mailing list