Commits

Mathieu Le Marec - Pasquet committed b48795f

1.3.4.4 distribute 0.6.6

Comments (0)

Files changed (5)

 
 Changes & News
 --------------
+1.3.4.4
+~~~~~~~~
+* upgrade distribute to 0.6.6 (kiorky <kiorky@cryptelium.net>) 
 
 1.3.4.3
 ~~~~~~~~
     print 'Note: without Setuptools installed you will have to use "python -m virtualenv ENV"'
 import sys, os
 
-version = '1.3.4.3'
+version = '1.3.4.4'
 
 f = open(os.path.join(os.path.dirname(__file__), 'docs', 'index.txt'))
 long_description = f.read().strip()

support-files/distribute_setup.py

             args = [quote(arg) for arg in args]
         return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
 
-DEFAULT_VERSION = "0.6.5"
+DEFAULT_VERSION = "0.6.6"
 DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
 SETUPTOOLS_PKG_INFO = """\
 Metadata-Version: 1.0
         try:
             pkg_resources.require("distribute>="+version)
             return
-        except pkg_resources.VersionConflict, e:
+        except pkg_resources.VersionConflict:
+            e = sys.exc_info()[1]
             if was_imported:
-                print >>sys.stderr, (
+                sys.stderr.write(
                 "The required version of distribute (>=%s) is not available,\n"
                 "and can't be installed while this script is running. Please\n"
                 "install a more recent version first, using\n"
                 "'easy_install -U distribute'."
-                "\n\n(Currently using %r)") % (version, e.args[0])
+                "\n\n(Currently using %r)\n" % (version, e.args[0]))
                 sys.exit(2)
             else:
                 del pkg_resources, sys.modules['pkg_resources']    # reload ok
     """
     # making sure we use the absolute path
     to_dir = os.path.abspath(to_dir)
-    import urllib2
+    try:
+        from urllib.request import urlopen
+    except ImportError:
+        from urllib2 import urlopen
     tgz_name = "distribute-%s.tar.gz" % version
     url = download_base + tgz_name
     saveto = os.path.join(to_dir, tgz_name)
     if not os.path.exists(saveto):  # Avoid repeated downloads
         try:
             log.warn("Downloading %s", url)
-            src = urllib2.urlopen(url)
+            src = urlopen(url)
             # Read/write all in one block, so we don't create a corrupt file
             # if the download is interrupted.
             data = src.read()
         log.warn('Setuptools or Distribute does not seem to be installed.')
         return
     ws = pkg_resources.working_set
-    setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
-                              replacement=False))
+    try:
+        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
+                                  replacement=False))
+    except TypeError:
+        # old distribute API
+        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
+
     if setuptools_dist is None:
         log.warn('No setuptools distribution found')
         return
             # Extract directories with a safe mode.
             directories.append(tarinfo)
             tarinfo = copy.copy(tarinfo)
-            tarinfo.mode = 0700
+            tarinfo.mode = 448 # decimal for oct 0700
         self.extract(tarinfo, path)
 
     # Reverse sort directories.
             self.chown(tarinfo, dirpath)
             self.utime(tarinfo, dirpath)
             self.chmod(tarinfo, dirpath)
-        except ExtractError, e:
+        except ExtractError:
+            e = sys.exc_info()[1]
             if self.errorlevel > 1:
                 raise
             else:

support-files/distribute_setup_3k.py

-#!python
-"""Bootstrap distribute installation
-
-If you want to use setuptools in your package's setup.py, just include this
-file in the same directory with it, and add this to the top of your setup.py::
-
-    from distribute_setup import use_setuptools
-    use_setuptools()
-
-If you want to require a specific version of setuptools, set a download
-mirror, or use an alternate download directory, you can do so by supplying
-the appropriate options to ``use_setuptools()``.
-
-This file can also be run as a script to install or upgrade setuptools.
-"""
-import os
-import sys
-import time
-import fnmatch
-import tempfile
-import tarfile
-from distutils import log
-
-try:
-    from site import USER_SITE
-except ImportError:
-    USER_SITE = None
-
-try:
-    import subprocess
-
-    def _python_cmd(*args):
-        args = (sys.executable,) + args
-        return subprocess.call(args) == 0
-
-except ImportError:
-    # will be used for python 2.3
-    def _python_cmd(*args):
-        args = (sys.executable,) + args
-        # quoting arguments if windows
-        if sys.platform == 'win32':
-            def quote(arg):
-                if ' ' in arg:
-                    return '"%s"' % arg
-                return arg
-            args = [quote(arg) for arg in args]
-        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
-
-DEFAULT_VERSION = "0.6.5"
-DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
-SETUPTOOLS_PKG_INFO = """\
-Metadata-Version: 1.0
-Name: setuptools
-Version: 0.6c9
-Summary: xxxx
-Home-page: xxx
-Author: xxx
-Author-email: xxx
-License: xxx
-Description: xxx
-"""
-
-
-def _install(tarball):
-    # extracting the tarball
-    tmpdir = tempfile.mkdtemp()
-    log.warn('Extracting in %s', tmpdir)
-    old_wd = os.getcwd()
-    try:
-        os.chdir(tmpdir)
-        tar = tarfile.open(tarball)
-        _extractall(tar)
-        tar.close()
-
-        # going in the directory
-        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
-        os.chdir(subdir)
-        log.warn('Now working in %s', subdir)
-
-        # installing
-        log.warn('Installing Distribute')
-        assert _python_cmd('setup.py', 'install')
-    finally:
-        os.chdir(old_wd)
-
-
-def _build_egg(tarball, to_dir):
-    # extracting the tarball
-    tmpdir = tempfile.mkdtemp()
-    log.warn('Extracting in %s', tmpdir)
-    old_wd = os.getcwd()
-    try:
-        os.chdir(tmpdir)
-        tar = tarfile.open(tarball)
-        _extractall(tar)
-        tar.close()
-
-        # going in the directory
-        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
-        os.chdir(subdir)
-        log.warn('Now working in %s', subdir)
-
-        # building an egg
-        log.warn('Building a Distribute egg in %s', to_dir)
-        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
-
-        # returning the result
-        for file in os.listdir(to_dir):
-            if fnmatch.fnmatch(file, 'distribute-%s*.egg' % DEFAULT_VERSION):
-                return os.path.join(to_dir, file)
-
-        raise IOError('Could not build the egg.')
-    finally:
-        os.chdir(old_wd)
-
-
-def _do_download(version, download_base, to_dir, download_delay):
-    tarball = download_setuptools(version, download_base,
-                                  to_dir, download_delay)
-    egg = _build_egg(tarball, to_dir)
-    sys.path.insert(0, egg)
-    import setuptools
-    setuptools.bootstrap_install_from = egg
-
-
-def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
-                   to_dir=os.curdir, download_delay=15, no_fake=False):
-    # making sure we use the absolute path
-    to_dir = os.path.abspath(to_dir)
-    was_imported = 'pkg_resources' in sys.modules or \
-        'setuptools' in sys.modules
-    try:
-        try:
-            import pkg_resources
-            if not hasattr(pkg_resources, '_distribute'):
-                if not no_fake:
-                    fake_setuptools()
-                raise ImportError
-        except ImportError:
-            return _do_download(version, download_base, to_dir, download_delay)
-        try:
-            pkg_resources.require("distribute>="+version)
-            return
-        except pkg_resources.VersionConflict as e:
-            if was_imported:
-                print((
-                "The required version of distribute (>=%s) is not available,\n"
-                "and can't be installed while this script is running. Please\n"
-                "install a more recent version first, using\n"
-                "'easy_install -U distribute'."
-                "\n\n(Currently using %r)") % (version, e.args[0]), file=sys.stderr)
-                sys.exit(2)
-            else:
-                del pkg_resources, sys.modules['pkg_resources']    # reload ok
-                return _do_download(version, download_base, to_dir,
-                                    download_delay)
-        except pkg_resources.DistributionNotFound:
-            return _do_download(version, download_base, to_dir,
-                                download_delay)
-    finally:
-        _create_fake_setuptools_pkg_info(to_dir)
-
-def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
-                        to_dir=os.curdir, delay=15):
-    """Download distribute from a specified location and return its filename
-
-    `version` should be a valid distribute version number that is available
-    as an egg for download under the `download_base` URL (which should end
-    with a '/'). `to_dir` is the directory where the egg will be downloaded.
-    `delay` is the number of seconds to pause before an actual download
-    attempt.
-    """
-    # making sure we use the absolute path
-    to_dir = os.path.abspath(to_dir)
-    import urllib.request, urllib.error, urllib.parse
-    tgz_name = "distribute-%s.tar.gz" % version
-    url = download_base + tgz_name
-    saveto = os.path.join(to_dir, tgz_name)
-    src = dst = None
-    if not os.path.exists(saveto):  # Avoid repeated downloads
-        try:
-            log.warn("Downloading %s", url)
-            src = urllib.request.urlopen(url)
-            # Read/write all in one block, so we don't create a corrupt file
-            # if the download is interrupted.
-            data = src.read()
-            dst = open(saveto, "wb")
-            dst.write(data)
-        finally:
-            if src:
-                src.close()
-            if dst:
-                dst.close()
-    return os.path.realpath(saveto)
-
-
-def _patch_file(path, content):
-    """Will backup the file then patch it"""
-    existing_content = open(path).read()
-    if existing_content == content:
-        # already patched
-        log.warn('Already patched.')
-        return False
-    log.warn('Patching...')
-    _rename_path(path)
-    f = open(path, 'w')
-    try:
-        f.write(content)
-    finally:
-        f.close()
-    return True
-
-
-def _same_content(path, content):
-    return open(path).read() == content
-
-
-def _rename_path(path):
-    new_name = path + '.OLD.%s' % time.time()
-    log.warn('Renaming %s into %s', path, new_name)
-    try:
-        from setuptools.sandbox import DirectorySandbox
-        def _violation(*args):
-            pass
-        DirectorySandbox._violation = _violation
-    except ImportError:
-        pass
-
-    os.rename(path, new_name)
-    return new_name
-
-
-def _remove_flat_installation(placeholder):
-    if not os.path.isdir(placeholder):
-        log.warn('Unkown installation at %s', placeholder)
-        return False
-    found = False
-    for file in os.listdir(placeholder):
-        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
-            found = True
-            break
-    if not found:
-        log.warn('Could not locate setuptools*.egg-info')
-        return
-
-    log.warn('Removing elements out of the way...')
-    pkg_info = os.path.join(placeholder, file)
-    if os.path.isdir(pkg_info):
-        patched = _patch_egg_dir(pkg_info)
-    else:
-        patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
-
-    if not patched:
-        log.warn('%s already patched.', pkg_info)
-        return False
-    # now let's move the files out of the way
-    for element in ('setuptools', 'pkg_resources.py', 'site.py'):
-        element = os.path.join(placeholder, element)
-        if os.path.exists(element):
-            _rename_path(element)
-        else:
-            log.warn('Could not find the %s element of the '
-                     'Setuptools distribution', element)
-    return True
-
-
-def _after_install(dist):
-    log.warn('After install bootstrap.')
-    placeholder = dist.get_command_obj('install').install_purelib
-    _create_fake_setuptools_pkg_info(placeholder)
-
-def _create_fake_setuptools_pkg_info(placeholder):
-    if not placeholder or not os.path.exists(placeholder):
-        log.warn('Could not find the install location')
-        return
-    pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
-    setuptools_file = 'setuptools-0.6c9-py%s.egg-info' % pyver
-    pkg_info = os.path.join(placeholder, setuptools_file)
-    if os.path.exists(pkg_info):
-        log.warn('%s already exists', pkg_info)
-        return
-    log.warn('Creating %s', pkg_info)
-    f = open(pkg_info, 'w')
-    try:
-        f.write(SETUPTOOLS_PKG_INFO)
-    finally:
-        f.close()
-    pth_file = os.path.join(placeholder, 'setuptools.pth')
-    log.warn('Creating %s', pth_file)
-    f = open(pth_file, 'w')
-    try:
-        f.write(os.path.join(os.curdir, setuptools_file))
-    finally:
-        f.close()
-
-
-def _patch_egg_dir(path):
-    # let's check if it's already patched
-    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
-    if os.path.exists(pkg_info):
-        if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
-            log.warn('%s already patched.', pkg_info)
-            return False
-    _rename_path(path)
-    os.mkdir(path)
-    os.mkdir(os.path.join(path, 'EGG-INFO'))
-    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
-    f = open(pkg_info, 'w')
-    try:
-        f.write(SETUPTOOLS_PKG_INFO)
-    finally:
-        f.close()
-    return True
-
-
-def _before_install():
-    log.warn('Before install bootstrap.')
-    fake_setuptools()
-
-
-def _under_prefix(location):
-    if 'install' not in sys.argv:
-        return True
-    args = sys.argv[sys.argv.index('install')+1:]
-    for index, arg in enumerate(args):
-        for option in ('--root', '--prefix'):
-            if arg.startswith('%s=' % option):
-                top_dir = arg.split('root=')[-1]
-                return location.startswith(top_dir)
-            elif arg == option:
-                if len(args) > index:
-                    top_dir = args[index+1]
-                    return location.startswith(top_dir)
-            elif option == '--user' and USER_SITE is not None:
-                return location.startswith(USER_SITE)
-    return True
-
-
-def fake_setuptools():
-    log.warn('Scanning installed packages')
-    try:
-        import pkg_resources
-    except ImportError:
-        # we're cool
-        log.warn('Setuptools or Distribute does not seem to be installed.')
-        return
-    ws = pkg_resources.working_set
-    setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
-                              replacement=False))
-    if setuptools_dist is None:
-        log.warn('No setuptools distribution found')
-        return
-    # detecting if it was already faked
-    setuptools_location = setuptools_dist.location
-    log.warn('Setuptools installation detected at %s', setuptools_location)
-
-    # if --root or --preix was provided, and if
-    # setuptools is not located in them, we don't patch it
-    if not _under_prefix(setuptools_location):
-        log.warn('Not patching, --root or --prefix is installing Distribute'
-                 ' in another location')
-        return
-
-    # let's see if its an egg
-    if not setuptools_location.endswith('.egg'):
-        log.warn('Non-egg installation')
-        res = _remove_flat_installation(setuptools_location)
-        if not res:
-            return
-    else:
-        log.warn('Egg installation')
-        pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
-        if (os.path.exists(pkg_info) and
-            _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
-            log.warn('Already patched.')
-            return
-        log.warn('Patching...')
-        # let's create a fake egg replacing setuptools one
-        res = _patch_egg_dir(setuptools_location)
-        if not res:
-            return
-    log.warn('Patched done.')
-    _relaunch()
-
-
-def _relaunch():
-    log.warn('Relaunching...')
-    # we have to relaunch the process
-    args = [sys.executable] + sys.argv
-    sys.exit(subprocess.call(args))
-
-
-def _extractall(self, path=".", members=None):
-    """Extract all members from the archive to the current working
-       directory and set owner, modification time and permissions on
-       directories afterwards. `path' specifies a different directory
-       to extract to. `members' is optional and must be a subset of the
-       list returned by getmembers().
-    """
-    import copy
-    import operator
-    from tarfile import ExtractError
-    directories = []
-
-    if members is None:
-        members = self
-
-    for tarinfo in members:
-        if tarinfo.isdir():
-            # Extract directories with a safe mode.
-            directories.append(tarinfo)
-            tarinfo = copy.copy(tarinfo)
-            tarinfo.mode = 0o700
-        self.extract(tarinfo, path)
-
-    # Reverse sort directories.
-    if sys.version_info < (2, 4):
-        def sorter(dir1, dir2):
-            return cmp(dir1.name, dir2.name)
-        directories.sort(sorter)
-        directories.reverse()
-    else:
-        directories.sort(key=operator.attrgetter('name'), reverse=True)
-
-    # Set correct owner, mtime and filemode on directories.
-    for tarinfo in directories:
-        dirpath = os.path.join(path, tarinfo.name)
-        try:
-            self.chown(tarinfo, dirpath)
-            self.utime(tarinfo, dirpath)
-            self.chmod(tarinfo, dirpath)
-        except ExtractError as e:
-            if self.errorlevel > 1:
-                raise
-            else:
-                self._dbg(1, "tarfile: %s" % e)
-
-
-def main(argv, version=DEFAULT_VERSION):
-    """Install or upgrade setuptools and EasyInstall"""
-    tarball = download_setuptools()
-    _install(tarball)
-
-
-if __name__ == '__main__':
-    main(sys.argv[1:])
         cmd = [py_executable, distribute_setup]
     else:
         if PYTHON3:
-            cmd = [py_executable, '-c', DISTRIBUTE_SETUP_3K_PY.decode('ascii')]
+            cmd = [py_executable, '-c', DISTRIBUTE_SETUP_PY.decode('ascii')]
         else:
             cmd = [py_executable, '-c', DISTRIBUTE_SETUP_PY]
     if unzip:
 
 ##file distribute_setup.py
 DISTRIBUTE_SETUP_PY = _decode("""
-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
-""")
-
-##file distribute_setup_3k.py
-DISTRIBUTE_SETUP_3K_PY = _decode("""
-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
-nCUhiw==
+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
 """)
 
 ##file activate.sh