Hi,

I want to port pyobjc to python 3.1 and need a py3k port of setuptools for that. I'm slowy moving forward with the latter, partly based on earlier discussions on this list. I don't have anything useful to share at the moment, beyond a setup3.py file (see below).

But first a question: some of the tests use docutils and I'm having a hard time getting those to run with both python3 and python2. The bit that's particularly annoying is this bit of api_tests.txt:

Note that asking for a conflicting version of a distribution already in a
   working set triggers a ``pkg_resources.VersionConflict`` error:

>>> ws.find(Requirement.parse("Bar==1.0")) # doctest: +NORMALIZE_WHITESPACE
       Traceback (most recent call last):
         ...
       VersionConflict: (Bar 0.9 (http://example.com/something),
                      Requirement.parse('Bar==1.0'))

This passes with 2.6, but fails in 3.1 because it expects 'pkg_resources.VersionConflict' rather than just 'VersionConflict'. What's the best way to work around this issue?


The attached file "setup3.py" is a script that incrementally copies the setuptools source-tree to a temporary directory, runs 2to3 on that copy and exec-s the contents of the translated 'setup.py' file. This seems to be good enough to be able to install setuptools for python2 and python3 using the same code-base. That said, this is just the first step of a python3 port there need to be changes to the setuptools sources to be able to actually use the translated sources.

Ronald

"""
Setup.py file for use with python3.x

This file will run 2to3 on the setuptools sources and
than executes the real setup.

NOTE: It is not possible to use the import trick 
described in the distutils documentation because 
setup.py depends on the (on yet translated) copy
of setuptools.

NOTE2: The actual 'build' and 'dist' directories will 
be hidden in the generated subdirectory.
"""
import os, sys, shutil
import subprocess

def newer(file1, file2):
    return os.stat(file1).st_mtime > os.stat(file2).st_mtime

def make_2to3_tree():
    """ 
    Creates build/setuptools3 containing a 2to3-ed
    copy of setuptools.

    This function takes care to translate only files
    that are changed in the input tree, for convenience
    during edit/test cycles.
    """
    topdir='build/setuptools3'
    tofix = []

    if not os.path.exists(topdir):
        os.makedirs(topdir)

    for elem in os.listdir('.'):
        if elem.startswith('.') or elem in ('build', 'dist'): continue

        if os.path.isfile(elem):
            inpath = elem
            outpath = os.path.join(topdir, elem)
            if not os.path.exists(outpath) or newer(inpath, outpath):
                shutil.copy(inpath, outpath)
                if inpath.endswith('.py') or inpath.endswith('.pyw'):
                    tofix.append(outpath)

        elif os.path.isdir(elem):
            if not os.path.exists(os.path.join(topdir, elem)):
                os.mkdir(os.path.join(topdir, elem))
            for dirpath, dnames, fnames in os.walk(elem):
                for fn in dnames:
                    outpath = os.path.join(topdir, dirpath, fn)
                    if not os.path.exists(outpath):
                        os.mkdir(outpath)

                for fn in fnames:
                    if fn.endswith('.pyc') or fn.endswith('.pyo'):
                        # Ignore compiled files
                        continue
                    inpath = os.path.join(dirpath, fn)
                    outpath = os.path.join(topdir, dirpath, fn)
                    if not os.path.exists(outpath) or newer(inpath, outpath):
                        shutil.copy(inpath, outpath)
                        if inpath.endswith('.py') or inpath.endswith('.pyw'):
                            tofix.append(outpath)

        else:
            raise RuntimeError("Unhandled file type for %s"%(elem,))

    # Explicitly specify the 2to3 command to use
    cmd = os.path.join(sys.prefix, 'bin', '2to3')
    for fn in tofix:
        print("Converting %s ... "%(fn,))
        subprocess.Popen([cmd, '--write', '--nobackups', '--', fn]).wait()


def run_setup_py():
    """
    Execute the translated setup.py file in the __main__
    module
    """

    # Fix the __file__ variable.
    global __file__
    __file__ = os.path.abspath('build/setuptools3/setup.py')

    with open('build/setuptools3/setup.py', 'r') as fp:
        source = fp.read()

    # Distutils assumes that the setup.py file is run from
    # the current directory.
    os.chdir('build/setuptools3')

    sys.path[0] = os.path.abspath('.')

    # Actually run the setup.py file
    exec(compile(source, 'build/setuptools3/setup.py', 'exec'), globals())

def main():
    make_2to3_tree()
    run_setup_py()

if __name__ == "__main__":
    main()

_______________________________________________
Distutils-SIG maillist  -  Distutils-SIG@python.org
http://mail.python.org/mailman/listinfo/distutils-sig

Reply via email to