summaryrefslogtreecommitdiff
path: root/setuptools/command
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools/command')
-rw-r--r--setuptools/command/__init__.py6
-rw-r--r--setuptools/command/build_py.py101
-rwxr-xr-xsetuptools/command/easy_install.py599
-rwxr-xr-xsetuptools/command/egg_info.py118
-rw-r--r--setuptools/command/install.py29
-rwxr-xr-xsetuptools/command/sdist.py48
-rwxr-xr-xsetuptools/command/upload.py184
-rw-r--r--setuptools/command/upload_docs.py24
8 files changed, 330 insertions, 779 deletions
diff --git a/setuptools/command/__init__.py b/setuptools/command/__init__.py
index b063fa19..29c9d75a 100644
--- a/setuptools/command/__init__.py
+++ b/setuptools/command/__init__.py
@@ -1,17 +1,13 @@
__all__ = [
'alias', 'bdist_egg', 'bdist_rpm', 'build_ext', 'build_py', 'develop',
'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts',
- 'sdist', 'setopt', 'test', 'upload', 'install_egg_info', 'install_scripts',
+ 'sdist', 'setopt', 'test', 'install_egg_info', 'install_scripts',
'register', 'bdist_wininst', 'upload_docs',
]
from setuptools.command import install_scripts
import sys
-if sys.version>='2.5':
- # In Python 2.5 and above, distutils includes its own upload command
- __all__.remove('upload')
-
from distutils.command.bdist import bdist
if 'egg' not in bdist.format_commands:
diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py
index 8751acd4..090b44d2 100644
--- a/setuptools/command/build_py.py
+++ b/setuptools/command/build_py.py
@@ -1,64 +1,17 @@
-import os.path, sys, fnmatch
+import os
+import sys
+import fnmatch
+import textwrap
from distutils.command.build_py import build_py as _build_py
from distutils.util import convert_path
from glob import glob
try:
- from distutils.util import Mixin2to3 as _Mixin2to3
- # add support for converting doctests that is missing in 3.1 distutils
- from distutils import log
- from lib2to3.refactor import RefactoringTool, get_fixers_from_package
- import setuptools
- 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)
-
- class Mixin2to3(_Mixin2to3):
- def run_2to3(self, files, doctests = False):
- # See of the distribution option has been set, otherwise check the
- # setuptools default.
- if self.distribution.use_2to3 is not True:
- return
- if not files:
- return
- log.info("Fixing "+" ".join(files))
- self.__build_fixer_names()
- self.__exclude_fixers()
- if doctests:
- if setuptools.run_2to3_on_doctests:
- r = DistutilsRefactoringTool(self.fixer_names)
- r.refactor(files, write=True, doctests_only=True)
- else:
- _Mixin2to3.run_2to3(self, files)
-
- def __build_fixer_names(self):
- if self.fixer_names: return
- self.fixer_names = []
- for p in setuptools.lib2to3_fixer_packages:
- self.fixer_names.extend(get_fixers_from_package(p))
- if self.distribution.use_2to3_fixers is not None:
- for p in self.distribution.use_2to3_fixers:
- self.fixer_names.extend(get_fixers_from_package(p))
-
- def __exclude_fixers(self):
- excluded_fixers = getattr(self, 'exclude_fixers', [])
- if self.distribution.use_2to3_exclude_fixers is not None:
- excluded_fixers.extend(self.distribution.use_2to3_exclude_fixers)
- for fixer_name in excluded_fixers:
- if fixer_name in self.fixer_names:
- self.fixer_names.remove(fixer_name)
-
+ from setuptools.lib2to3_ex import Mixin2to3
except ImportError:
class Mixin2to3:
def run_2to3(self, files, doctests=True):
- # Nothing done in 2.x
- pass
+ "do nothing"
class build_py(_build_py, Mixin2to3):
"""Enhanced 'build_py' command that includes data files with packages
@@ -97,9 +50,10 @@ class build_py(_build_py, Mixin2to3):
# output files are.
self.byte_compile(_build_py.get_outputs(self, include_bytecode=0))
- def __getattr__(self,attr):
+ def __getattr__(self, attr):
if attr=='data_files': # lazily compute data files
- self.data_files = files = self._get_data_files(); return files
+ self.data_files = files = self._get_data_files()
+ return files
return _build_py.__getattr__(self,attr)
def build_module(self, module, module_file, package):
@@ -126,7 +80,7 @@ class build_py(_build_py, Mixin2to3):
filenames = [
file[plen:] for file in self.find_data_files(package, src_dir)
]
- data.append( (package, src_dir, build_dir, filenames) )
+ data.append((package, src_dir, build_dir, filenames))
return data
def find_data_files(self, package, src_dir):
@@ -141,7 +95,6 @@ class build_py(_build_py, Mixin2to3):
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)
@@ -152,7 +105,6 @@ class build_py(_build_py, Mixin2to3):
if copied and srcfile in self.distribution.convert_2to3_doctests:
self.__doctests_2to3.append(outf)
-
def analyze_manifest(self):
self.manifest_files = mf = {}
if not self.distribution.include_package_data:
@@ -217,10 +169,10 @@ class build_py(_build_py, Mixin2to3):
if 'declare_namespace'.encode() not in f.read():
from distutils import log
log.warn(
- "WARNING: %s is a namespace package, but its __init__.py does\n"
- "not declare_namespace(); setuptools 0.7 will REQUIRE this!\n"
- '(See the setuptools manual under "Namespace Packages" for '
- "details.)\n", package
+ "WARNING: %s is a namespace package, but its __init__.py does\n"
+ "not declare_namespace(); setuptools 0.7 will REQUIRE this!\n"
+ '(See the setuptools manual under "Namespace Packages" for '
+ "details.)\n", package
)
f.close()
return init_py
@@ -229,14 +181,12 @@ class build_py(_build_py, Mixin2to3):
self.packages_checked={}
_build_py.initialize_options(self)
-
def get_package_dir(self, package):
res = _build_py.get_package_dir(self, package)
if self.distribution.src_root is not None:
return os.path.join(self.distribution.src_root, res)
return res
-
def exclude_data_files(self, package, src_dir, files):
"""Filter filenames for package's data files in 'src_dir'"""
globs = (self.exclude_package_data.get('', [])
@@ -260,21 +210,12 @@ def assert_relative(path):
if not os.path.isabs(path):
return path
from distutils.errors import DistutilsSetupError
- raise DistutilsSetupError(
-"""Error: setup script specifies an absolute path:
-
- %s
-
-setup() arguments must *always* be /-separated paths relative to the
-setup.py directory, *never* absolute paths.
-""" % path
- )
-
-
-
-
-
-
-
+ msg = textwrap.dedent("""
+ Error: setup script specifies an absolute path:
+ %s
+ setup() arguments must *always* be /-separated paths relative to the
+ setup.py directory, *never* absolute paths.
+ """).lstrip() % path
+ raise DistutilsSetupError(msg)
diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py
index 3194644e..08ebf3e5 100755
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -1,5 +1,6 @@
-#!python
-"""\
+#!/usr/bin/env python
+
+"""
Easy Install
------------
@@ -10,6 +11,7 @@ file, or visit the `EasyInstall home page`__.
__ https://pythonhosted.org/setuptools/easy_install.html
"""
+
import sys
import os
import zipimport
@@ -20,24 +22,17 @@ import re
import stat
import random
import platform
+import textwrap
+import warnings
+import site
+import struct
from glob import glob
+from distutils import log, dir_util
+
import pkg_resources
from setuptools import Command, _dont_write_bytecode
from setuptools.sandbox import run_setup
-from distutils import log, dir_util
-try:
- # Python 2.7 or >=3.2
- from sysconfig import get_config_vars, get_path
- def _get_platlib():
- return get_path("platlib")
- def _get_purelib():
- return get_path("purelib")
-except ImportError:
- from distutils.sysconfig import get_config_vars, get_python_lib
- def _get_platlib():
- return get_python_lib(True)
- def _get_purelib():
- return get_python_lib(False)
+from setuptools.py31compat import get_path, get_config_vars
from distutils.util import get_platform
from distutils.util import convert_path, subst_vars
@@ -49,41 +44,34 @@ from setuptools.archive_util import unpack_archive
from setuptools.package_index import PackageIndex
from setuptools.package_index import URL_SCHEME
from setuptools.command import bdist_egg, egg_info
-from setuptools.compat import (iteritems, maxsize, xrange, basestring, unicode,
+from setuptools.compat import (iteritems, maxsize, basestring, unicode,
reraise)
-from pkg_resources import yield_lines, normalize_path, resource_string, \
- ensure_directory, get_distribution, find_distributions, \
- Environment, Requirement, Distribution, \
- PathMetadata, EggMetadata, WorkingSet, \
- DistributionNotFound, VersionConflict, \
- DEVELOP_DIST
-
-if '__VENV_LAUNCHER__' in os.environ:
- sys_executable = os.environ['__VENV_LAUNCHER__']
-else:
- sys_executable = os.path.normpath(sys.executable)
+from pkg_resources import (
+ yield_lines, normalize_path, resource_string, ensure_directory,
+ get_distribution, find_distributions, Environment, Requirement,
+ Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound,
+ VersionConflict, DEVELOP_DIST,
+)
+
+sys_executable = os.environ.get('__VENV_LAUNCHER__',
+ os.path.normpath(sys.executable))
__all__ = [
'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg',
'main', 'get_exe_prefixes',
]
-import site
-HAS_USER_SITE = not sys.version < "2.6" and site.ENABLE_USER_SITE
-
-import struct
def is_64bit():
return struct.calcsize("P") == 8
-def samefile(p1,p2):
- if hasattr(os.path,'samefile') and (
- os.path.exists(p1) and os.path.exists(p2)
- ):
- return os.path.samefile(p1,p2)
- return (
- os.path.normpath(os.path.normcase(p1)) ==
- os.path.normpath(os.path.normcase(p2))
- )
+def samefile(p1, p2):
+ both_exist = os.path.exists(p1) and os.path.exists(p2)
+ use_samefile = hasattr(os.path, 'samefile') and both_exist
+ if use_samefile:
+ return os.path.samefile(p1, p2)
+ norm_p1 = os.path.normpath(os.path.normcase(p1))
+ norm_p2 = os.path.normpath(os.path.normcase(p2))
+ return norm_p1 == norm_p2
if sys.version_info <= (3,):
def _to_ascii(s):
@@ -120,43 +108,40 @@ class easy_install(Command):
("always-copy", "a", "Copy all needed packages to install dir"),
("index-url=", "i", "base URL of Python Package Index"),
("find-links=", "f", "additional URL(s) to search for packages"),
- ("delete-conflicting", "D", "no longer needed; don't use this"),
- ("ignore-conflicts-at-my-risk", None,
- "no longer needed; don't use this"),
("build-directory=", "b",
"download/extract/build in DIR; keep the results"),
('optimize=', 'O',
- "also compile with optimization: -O1 for \"python -O\", "
- "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
+ "also compile with optimization: -O1 for \"python -O\", "
+ "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
('record=', None,
- "filename in which to record list of installed files"),
+ "filename in which to record list of installed files"),
('always-unzip', 'Z', "don't install as a zipfile, no matter what"),
('site-dirs=','S',"list of directories where .pth files work"),
('editable', 'e', "Install specified packages in editable form"),
('no-deps', 'N', "don't install dependencies"),
('allow-hosts=', 'H', "pattern(s) that hostnames must match"),
- ('local-snapshots-ok', 'l', "allow building eggs from local checkouts"),
+ ('local-snapshots-ok', 'l',
+ "allow building eggs from local checkouts"),
('version', None, "print version information and exit"),
('no-find-links', None,
- "Don't load find-links defined in packages being installed")
+ "Don't load find-links defined in packages being installed")
]
boolean_options = [
'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy',
- 'delete-conflicting', 'ignore-conflicts-at-my-risk', 'editable',
+ 'editable',
'no-deps', 'local-snapshots-ok', 'version'
]
- if HAS_USER_SITE:
- user_options.append(('user', None,
- "install in user site-package '%s'" % site.USER_SITE))
+ if site.ENABLE_USER_SITE:
+ help_msg = "install in user site-package '%s'" % site.USER_SITE
+ user_options.append(('user', None, help_msg))
boolean_options.append('user')
-
negative_opt = {'always-unzip': 'zip-ok'}
create_index = PackageIndex
def initialize_options(self):
- if HAS_USER_SITE:
+ if site.ENABLE_USER_SITE:
whereami = os.path.abspath(__file__)
self.user = whereami.startswith(site.USER_SITE)
else:
@@ -181,7 +166,7 @@ class easy_install(Command):
self.install_data = None
self.install_base = None
self.install_platbase = None
- if HAS_USER_SITE:
+ if site.ENABLE_USER_SITE:
self.install_userbase = site.USER_BASE
self.install_usersite = site.USER_SITE
else:
@@ -192,8 +177,6 @@ class easy_install(Command):
# Options not specifiable via command line
self.package_index = None
self.pth_file = self.always_copy_from = None
- self.delete_conflicting = None
- self.ignore_conflicts_at_my_risk = None
self.site_dirs = None
self.installed_projects = {}
self.sitepy_installed = False
@@ -226,27 +209,28 @@ class easy_install(Command):
py_version = sys.version.split()[0]
prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix')
- self.config_vars = {'dist_name': self.distribution.get_name(),
- 'dist_version': self.distribution.get_version(),
- 'dist_fullname': self.distribution.get_fullname(),
- 'py_version': py_version,
- 'py_version_short': py_version[0:3],
- 'py_version_nodot': py_version[0] + py_version[2],
- 'sys_prefix': prefix,
- 'prefix': prefix,
- 'sys_exec_prefix': exec_prefix,
- 'exec_prefix': exec_prefix,
- # Only python 3.2+ has abiflags
- 'abiflags': getattr(sys, 'abiflags', ''),
- }
-
- if HAS_USER_SITE:
+ self.config_vars = {
+ 'dist_name': self.distribution.get_name(),
+ 'dist_version': self.distribution.get_version(),
+ 'dist_fullname': self.distribution.get_fullname(),
+ 'py_version': py_version,
+ 'py_version_short': py_version[0:3],
+ 'py_version_nodot': py_version[0] + py_version[2],
+ 'sys_prefix': prefix,
+ 'prefix': prefix,
+ 'sys_exec_prefix': exec_prefix,
+ 'exec_prefix': exec_prefix,
+ # Only python 3.2+ has abiflags
+ 'abiflags': getattr(sys, 'abiflags', ''),
+ }
+
+ if site.ENABLE_USER_SITE:
self.config_vars['userbase'] = self.install_userbase
self.config_vars['usersite'] = self.install_usersite
# fix the install_dir if "--user" was used
#XXX: duplicate of the code in the setup command
- if self.user and HAS_USER_SITE:
+ if self.user and site.ENABLE_USER_SITE:
self.create_home_path()
if self.install_userbase is None:
raise DistutilsPlatformError(
@@ -336,11 +320,6 @@ class easy_install(Command):
except ValueError:
raise DistutilsOptionError("--optimize must be 0, 1, or 2")
- if self.delete_conflicting and self.ignore_conflicts_at_my_risk:
- raise DistutilsOptionError(
- "Can't use both --delete-conflicting and "
- "--ignore-conflicts-at-my-risk at the same time"
- )
if self.editable and not self.build_directory:
raise DistutilsArgError(
"Must specify a build directory (-b) when using --editable"
@@ -351,7 +330,6 @@ class easy_install(Command):
self.outputs = []
-
def _expand_attrs(self, attrs):
for attr in attrs:
val = getattr(self, attr)
@@ -382,7 +360,7 @@ class easy_install(Command):
outputs = self.outputs
if self.root: # strip any package prefix
root_len = len(self.root)
- for counter in xrange(len(outputs)):
+ for counter in range(len(outputs)):
outputs[counter] = outputs[counter][root_len:]
from distutils import file_util
self.execute(
@@ -406,12 +384,7 @@ class easy_install(Command):
return os.path.join(self.install_dir, "test-easy-install-%s" % pid)
def warn_deprecated_options(self):
- if self.delete_conflicting or self.ignore_conflicts_at_my_risk:
- log.warn(
- "Note: The -D, --delete-conflicting and"
- " --ignore-conflicts-at-my-risk no longer have any purpose"
- " and should not be used."
- )
+ pass
def check_site_dir(self):
"""Verify that self.install_dir is .pth-capable dir, if needed"""
@@ -456,7 +429,7 @@ class easy_install(Command):
self.install_dir = instdir
def cant_write_to_target(self):
- msg = """can't create or remove files in install directory
+ template = """can't create or remove files in install directory
The following error occurred while trying to add or remove files in the
installation directory:
@@ -467,7 +440,8 @@ The installation directory you specified (via --install-dir, --prefix, or
the distutils default setting) was:
%s
-""" % (sys.exc_info()[1], self.install_dir,)
+"""
+ msg = template % (sys.exc_info()[1], self.install_dir,)
if not os.path.exists(self.install_dir):
msg += """
@@ -493,9 +467,6 @@ Please make the appropriate changes for your system and try again.
"""
raise DistutilsError(msg)
-
-
-
def check_pth_processing(self):
"""Empirically verify whether .pth files are supported in inst. dir"""
instdir = self.install_dir
@@ -514,7 +485,8 @@ Please make the appropriate changes for your system and try again.
else:
try:
f.write("import os; f = open(%r, 'w'); f.write('OK'); f.close()\n" % (ok_file,))
- f.close(); f=None
+ f.close()
+ f=None
executable = sys.executable
if os.name=='nt':
dirname,basename = os.path.split(executable)
@@ -533,9 +505,12 @@ Please make the appropriate changes for your system and try again.
)
return True
finally:
- if f: f.close()
- if os.path.exists(ok_file): os.unlink(ok_file)
- if os.path.exists(pth_file): os.unlink(pth_file)
+ if f:
+ f.close()
+ if os.path.exists(ok_file):
+ os.unlink(ok_file)
+ if os.path.exists(pth_file):
+ os.unlink(pth_file)
if not self.multi_version:
log.warn("TEST FAILED: %s does NOT support .pth files", instdir)
return False
@@ -580,11 +555,6 @@ Please make the appropriate changes for your system and try again.
(spec.key, self.build_directory)
)
-
-
-
-
-
def easy_install(self, spec, deps=False):
tmpdir = tempfile.mkdtemp(prefix="easy_install-")
download = None
@@ -654,7 +624,7 @@ Please make the appropriate changes for your system and try again.
for dist in dists:
self.process_distribution(spec, dist, deps)
else:
- dists = [self.check_conflicts(self.egg_distribution(download))]
+ dists = [self.egg_distribution(download)]
self.process_distribution(spec, dists[0], deps, "Using")
if spec is not None:
@@ -662,8 +632,6 @@ Please make the appropriate changes for your system and try again.
if dist in spec:
return dist
-
-
def select_scheme(self, name):
"""Sets the install directories by applying the install schemes."""
# it's the caller's problem if they supply a bad name!
@@ -673,9 +641,6 @@ Please make the appropriate changes for your system and try again.
if getattr(self, attrname) is None:
setattr(self, attrname, scheme[key])
-
-
-
def process_distribution(self, requirement, dist, deps=True, *info):
self.update_pth(dist)
self.package_index.add(dist)
@@ -684,7 +649,7 @@ Please make the appropriate changes for your system and try again.
self.installed_projects[dist.key] = dist
log.info(self.installation_report(requirement, dist, *info))
if (dist.has_metadata('dependency_links.txt') and
- not self.no_find_links):
+ not self.no_find_links):
self.package_index.add_find_links(
dist.get_metadata_lines('dependency_links.txt')
)
@@ -735,10 +700,8 @@ Please make the appropriate changes for your system and try again.
def maybe_move(self, spec, dist_filename, setup_base):
dst = os.path.join(self.build_directory, spec.key)
if os.path.exists(dst):
- log.warn(
- "%r already exists in %s; build directory %s will not be kept",
- spec.key, self.build_directory, setup_base
- )
+ msg = "%r already exists in %s; build directory %s will not be kept"
+ log.warn(msg, spec.key, self.build_directory, setup_base)
return setup_base
if os.path.isdir(dist_filename):
setup_base = dist_filename
@@ -751,7 +714,8 @@ Please make the appropriate changes for your system and try again.
if os.path.isdir(dist_filename):
# if the only thing there is a directory, move it instead
setup_base = dist_filename
- ensure_directory(dst); shutil.move(setup_base, dst)
+ ensure_directory(dst)
+ shutil.move(setup_base, dst)
return dst
def install_wrapper_scripts(self, dist):
@@ -759,8 +723,6 @@ Please make the appropriate changes for your system and try again.
for args in get_script_args(dist):
self.write_script(*args)
-
-
def install_script(self, dist, script_name, script_text, dev_path=None):
"""Generate a legacy script wrapper and install it"""
spec = str(dist.as_requirement())
@@ -799,14 +761,13 @@ Please make the appropriate changes for your system and try again.
mask = current_umask()
if not self.dry_run:
ensure_directory(target)
+ if os.path.exists(target):
+ os.unlink(target)
f = open(target,"w"+mode)
f.write(contents)
f.close()
chmod(target, 0x1FF-mask) # 0777
-
-
-
def install_eggs(self, spec, dist_filename, tmpdir):
# .egg dirs or files are already built, so just return them
if dist_filename.lower().endswith('.egg'):
@@ -822,8 +783,7 @@ Please make the appropriate changes for your system and try again.
setup_base = os.path.abspath(dist_filename)
if (setup_base.startswith(tmpdir) # something we downloaded
- and self.build_directory and spec is not None
- ):
+ and self.build_directory and spec is not None):
setup_base = self.maybe_move(spec, dist_filename, setup_base)
# Find the setup.py file
@@ -862,7 +822,6 @@ Please make the appropriate changes for your system and try again.
ensure_directory(destination)
dist = self.egg_distribution(egg_path)
- self.check_conflicts(dist)
if not samefile(egg_path, destination):
if os.path.isdir(destination) and not os.path.islink(destination):
dir_util.remove_tree(destination, dry_run=self.dry_run)
@@ -897,18 +856,19 @@ Please make the appropriate changes for your system and try again.
"%s is not a valid distutils Windows .exe" % dist_filename
)
# Create a dummy distribution object until we build the real distro
- dist = Distribution(None,
+ dist = Distribution(
+ None,
project_name=cfg.get('metadata','name'),
- version=cfg.get('metadata','version'), platform=get_platform()
+ version=cfg.get('metadata','version'), platform=get_platform(),
)
# Convert the .exe to an unpacked egg
egg_path = dist.location = os.path.join(tmpdir, dist.egg_name()+'.egg')
- egg_tmp = egg_path+'.tmp'
- egg_info = os.path.join(egg_tmp, 'EGG-INFO')
- pkg_inf = os.path.join(egg_info, 'PKG-INFO')
+ egg_tmp = egg_path + '.tmp'
+ _egg_info = os.path.join(egg_tmp, 'EGG-INFO')
+ pkg_inf = os.path.join(_egg_info, 'PKG-INFO')
ensure_directory(pkg_inf) # make sure EGG-INFO dir exists
- dist._provider = PathMetadata(egg_tmp, egg_info) # XXX
+ dist._provider = PathMetadata(egg_tmp, _egg_info) # XXX
self.exe_to_egg(dist_filename, egg_tmp)
# Write EGG-INFO/PKG-INFO
@@ -919,7 +879,7 @@ Please make the appropriate changes for your system and try again.
if k != 'target_version':
f.write('%s: %s\n' % (k.replace('_','-').title(), v))
f.close()
- script_dir = os.path.join(egg_info,'scripts')
+ script_dir = os.path.join(_egg_info,'scripts')
self.delete_blockers( # delete entry-point scripts to avoid duping
[os.path.join(script_dir,args[0]) for args in get_script_args(dist)]
)
@@ -965,7 +925,8 @@ Please make the appropriate changes for your system and try again.
resource = parts[-1]
parts[-1] = bdist_egg.strip_module(parts[-1])+'.py'
pyfile = os.path.join(egg_tmp, *parts)
- to_compile.append(pyfile); stubs.append(pyfile)
+ to_compile.append(pyfile)
+ stubs.append(pyfile)
bdist_egg.write_stub(resource, pyfile)
self.byte_compile(to_compile) # compile .py's
bdist_egg.write_safety_flag(os.path.join(egg_tmp,'EGG-INFO'),
@@ -979,82 +940,6 @@ Please make the appropriate changes for your system and try again.
f.write('\n'.join(locals()[name])+'\n')
f.close()
- def check_conflicts(self, dist):
- """Verify that there are no conflicting "old-style" packages"""
-
- return dist # XXX temporarily disable until new strategy is stable
- from imp import find_module, get_suffixes
- from glob import glob
-
- blockers = []
- names = dict.fromkeys(dist._get_metadata('top_level.txt')) # XXX private attr
-
- exts = {'.pyc':1, '.pyo':1} # get_suffixes() might leave one out
- for ext,mode,typ in get_suffixes():
- exts[ext] = 1
-
- for path,files in expand_paths([self.install_dir]+self.all_site_dirs):
- for filename in files:
- base,ext = os.path.splitext(filename)
- if base in names:
- if not ext:
- # no extension, check for package
- try:
- f, filename, descr = find_module(base, [path])
- except ImportError:
- continue
- else:
- if f: f.close()
- if filename not in blockers:
- blockers.append(filename)
- elif ext in exts and base!='site': # XXX ugh
- blockers.append(os.path.join(path,filename))
- if blockers:
- self.found_conflicts(dist, blockers)
-
- return dist
-
- def found_conflicts(self, dist, blockers):
- if self.delete_conflicting:
- log.warn("Attempting to delete conflicting packages:")
- return self.delete_blockers(blockers)
-
- msg = """\
--------------------------------------------------------------------------
-CONFLICT WARNING:
-
-The following modules or packages have the same names as modules or
-packages being installed, and will be *before* the installed packages in
-Python's search path. You MUST remove all of the relevant files and
-directories before you will be able to use the package(s) you are
-installing:
-
- %s
-
-""" % '\n '.join(blockers)
-
- if self.ignore_conflicts_at_my_risk:
- msg += """\
-(Note: you can run EasyInstall on '%s' with the
---delete-conflicting option to attempt deletion of the above files
-and/or directories.)
-""" % dist.project_name
- else:
- msg += """\
-Note: you can attempt this installation again with EasyInstall, and use
-either the --delete-conflicting (-D) option or the
---ignore-conflicts-at-my-risk option, to either delete the above files
-and directories, or to ignore the conflicts, respectively. Note that if
-you ignore the conflicts, the installed package(s) may not work.
-"""
- msg += """\
--------------------------------------------------------------------------
-"""
- sys.stderr.write(msg)
- sys.stderr.flush()
- if not self.ignore_conflicts_at_my_risk:
- raise DistutilsError("Installation aborted due to conflicts")
-
def installation_report(self, req, dist, what="Installed"):
"""Helpful installation message for display to package users"""
msg = "\n%(what)s %(eggloc)s%(extras)s"
@@ -1164,8 +1049,7 @@ See the setuptools documentation for the "develop" command for more info.
cfg_filename = os.path.join(base, 'setup.cfg')
setopt.edit_config(cfg_filename, settings)
-
- def update_pth(self,dist):
+ def update_pth(self, dist):
if self.pth_file is None:
return
@@ -1207,9 +1091,10 @@ See the setuptools documentation for the "develop" command for more info.
return dst # only unpack-and-compile skips files for dry run
def unpack_and_compile(self, egg_path, destination):
- to_compile = []; to_chmod = []
+ to_compile = []
+ to_chmod = []
- def pf(src,dst):
+ def pf(src, dst):
if dst.endswith('.py') and not src.startswith('EGG-INFO/'):
to_compile.append(dst)
elif dst.endswith('.dll') or dst.endswith('.so'):
@@ -1243,16 +1128,8 @@ See the setuptools documentation for the "develop" command for more info.
finally:
log.set_verbosity(self.verbose) # restore original verbosity
-
-
-
-
-
-
-
-
def no_default_version_msg(self):
- return """bad install directory or PYTHONPATH
+ template = """bad install directory or PYTHONPATH
You are attempting to install a package to a directory that is not
on PYTHONPATH and which Python does not read ".pth" files from. The
@@ -1279,18 +1156,8 @@ Here are some of your options for correcting the problem:
https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations
-Please make the appropriate changes for your system and try again.""" % (
- self.install_dir, os.environ.get('PYTHONPATH','')
- )
-
-
-
-
-
-
-
-
-
+Please make the appropriate changes for your system and try again."""
+ return template % (self.install_dir, os.environ.get('PYTHONPATH',''))
def install_site_py(self):
"""Make sure there's a site.py in the target dir, if needed"""
@@ -1328,9 +1195,6 @@ Please make the appropriate changes for your system and try again.""" % (
self.sitepy_installed = True
-
-
-
def create_home_path(self):
"""Create directories under ~."""
if not self.user:
@@ -1341,22 +1205,16 @@ Please make the appropriate changes for your system and try again.""" % (
self.debug_print("os.makedirs('%s', 0700)" % path)
os.makedirs(path, 0x1C0) # 0700
-
-
-
-
-
-
INSTALL_SCHEMES = dict(
posix = dict(
install_dir = '$base/lib/python$py_version_short/site-packages',
- script_dir = '$base/bin',
+ script_dir = '$base/bin',
),
)
DEFAULT_SCHEME = dict(
install_dir = '$base/Lib/site-packages',
- script_dir = '$base/Scripts',
+ script_dir = '$base/Scripts',
)
def _expand(self, *attrs):
@@ -1380,14 +1238,6 @@ Please make the appropriate changes for your system and try again.""" % (
val = os.path.expanduser(val)
setattr(self, attr, val)
-
-
-
-
-
-
-
-
def get_site_dirs():
# return a list of 'site' dirs
sitedirs = [_f for _f in os.environ.get('PYTHONPATH',
@@ -1422,10 +1272,11 @@ def get_site_dirs():
'Python',
sys.version[:3],
'site-packages'))
- for site_lib in (_get_purelib(), _get_platlib()):
+ lib_paths = get_path('purelib'), get_path('platlib')
+ for site_lib in lib_paths:
if site_lib not in sitedirs: sitedirs.append(site_lib)
- if HAS_USER_SITE:
+ if site.ENABLE_USER_SITE:
sitedirs.append(site.USER_SITE)
sitedirs = list(map(normalize_path, sitedirs))
@@ -1507,10 +1358,9 @@ def extract_wininst_cfg(dist_filename):
else:
null_byte = chr(0)
config = part.split(null_byte, 1)[0]
- # Now the config is in bytes, but on Python 3, it must be
- # unicode for the RawConfigParser, so decode it. Is this the
- # right encoding?
- config = config.decode('ascii')
+ # Now the config is in bytes, but for RawConfigParser, it should
+ # be text, so decode it.
+ config = config.decode(sys.getfilesystemencoding())
cfg.readfp(StringIO(config))
except ConfigParser.Error:
return None
@@ -1522,12 +1372,6 @@ def extract_wininst_cfg(dist_filename):
f.close()
-
-
-
-
-
-
def get_exe_prefixes(exe_filename):
"""Get exe->egg path translations for a given .exe file"""
@@ -1561,7 +1405,8 @@ def get_exe_prefixes(exe_filename):
finally:
z.close()
prefixes = [(x.lower(),y) for x, y in prefixes]
- prefixes.sort(); prefixes.reverse()
+ prefixes.sort()
+ prefixes.reverse()
return prefixes
@@ -1582,7 +1427,8 @@ class PthDistributions(Environment):
self.filename = filename
self.sitedirs = list(map(normalize_path, sitedirs))
self.basedir = normalize_path(os.path.dirname(self.filename))
- self._load(); Environment.__init__(self, [], None, None)
+ self._load()
+ Environment.__init__(self, [], None, None)
for path in yield_lines(self.paths):
list(map(self.add, find_distributions(path, True)))
@@ -1637,7 +1483,8 @@ class PthDistributions(Environment):
if os.path.islink(self.filename):
os.unlink(self.filename)
f = open(self.filename,'wt')
- f.write(data); f.close()
+ f.write(data)
+ f.close()
elif os.path.exists(self.filename):
log.debug("Deleting empty %s", self.filename)
@@ -1645,22 +1492,22 @@ class PthDistributions(Environment):
self.dirty = False
- def add(self,dist):
+ def add(self, dist):
"""Add `dist` to the distribution map"""
if (dist.location not in self.paths and (
dist.location not in self.sitedirs or
- dist.location == os.getcwd() #account for '.' being in PYTHONPATH
+ dist.location == os.getcwd() # account for '.' being in PYTHONPATH
)):
self.paths.append(dist.location)
self.dirty = True
- Environment.add(self,dist)
+ Environment.add(self, dist)
- def remove(self,dist):
+ def remove(self, dist):
"""Remove `dist` from the distribution map"""
while dist.location in self.paths:
- self.paths.remove(dist.location); self.dirty = True
- Environment.remove(self,dist)
-
+ self.paths.remove(dist.location)
+ self.dirty = True
+ Environment.remove(self, dist)
def make_relative(self,path):
npath, last = os.path.split(normalize_path(path))
@@ -1782,14 +1629,6 @@ def nt_quote_arg(arg):
return ''.join(result)
-
-
-
-
-
-
-
-
def is_python_script(script_text, filename):
"""Is this text, as a whole, a Python script? (as opposed to shell/bat/etc.
"""
@@ -1828,66 +1667,140 @@ def fix_jython_executable(executable, options):
# shebang line interpreter)
if options:
# Can't apply the workaround, leave it broken
- log.warn("WARNING: Unable to adapt shebang line for Jython,"
- " the following script is NOT executable\n"
- " see http://bugs.jython.org/issue1112 for"
- " more information.")
+ log.warn(
+ "WARNING: Unable to adapt shebang line for Jython,"
+ " the following script is NOT executable\n"
+ " see http://bugs.jython.org/issue1112 for"
+ " more information.")
else:
return '/usr/bin/env %s' % executable
return executable
-def get_script_args(dist, executable=sys_executable, wininst=False):
- """Yield write_script() argument tuples for a distribution's entrypoints"""
- spec = str(dist.as_requirement())
- header = get_script_header("", executable, wininst)
- for group in 'console_scripts', 'gui_scripts':
- for name, ep in dist.get_entry_map(group).items():
- script_text = (
- "# EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r\n"
- "__requires__ = %(spec)r\n"
- "import sys\n"
- "from pkg_resources import load_entry_point\n"
- "\n"
- "if __name__ == '__main__':"
- "\n"
- " sys.exit(\n"
- " load_entry_point(%(spec)r, %(group)r, %(name)r)()\n"
- " )\n"
- ) % locals()
- if sys.platform=='win32' or wininst:
- # On Windows/wininst, add a .py extension and an .exe launcher
- if group=='gui_scripts':
- launcher_type = 'gui'
- ext = '-script.pyw'
- old = ['.pyw']
- new_header = re.sub('(?i)python.exe','pythonw.exe',header)
- else:
- launcher_type = 'cli'
- ext = '-script.py'
- old = ['.py','.pyc','.pyo']
- new_header = re.sub('(?i)pythonw.exe','python.exe',header)
- if os.path.exists(new_header[2:-1].strip('"')) or sys.platform!='win32':
- hdr = new_header
- else:
- hdr = header
- yield (name+ext, hdr+script_text, 't', [name+x for x in old])
- yield (
- name+'.exe', get_win_launcher(launcher_type),
- 'b' # write in binary mode
- )
- if not is_64bit():
- # install a manifest for the launcher to prevent Windows
- # from detecting it as an installer (which it will for
- # launchers like easy_install.exe). Consider only
- # adding a manifest for launchers detected as installers.
- # See Distribute #143 for details.
- m_name = name + '.exe.manifest'
- yield (m_name, load_launcher_manifest(name), 't')
- else:
- # On other platforms, we assume the right thing to do is to
- # just write the stub with no extension.
- yield (name, header+script_text)
+class ScriptWriter(object):
+ """
+ Encapsulates behavior around writing entry point scripts for console and
+ gui apps.
+ """
+
+ template = textwrap.dedent("""
+ # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r
+ __requires__ = %(spec)r
+ import sys
+ from pkg_resources import load_entry_point
+
+ if __name__ == '__main__':
+ sys.exit(
+ load_entry_point(%(spec)r, %(group)r, %(name)r)()
+ )
+ """).lstrip()
+
+ @classmethod
+ def get_script_args(cls, dist, executable=sys_executable, wininst=False):
+ """
+ Yield write_script() argument tuples for a distribution's entrypoints
+ """
+ gen_class = cls.get_writer(wininst)
+ spec = str(dist.as_requirement())
+ header = get_script_header("", executable, wininst)
+ for type_ in 'console', 'gui':
+ group = type_ + '_scripts'
+ for name, ep in dist.get_entry_map(group).items():
+ script_text = gen_class.template % locals()
+ for res in gen_class._get_script_args(type_, name, header,
+ script_text):
+ yield res
+
+ @classmethod
+ def get_writer(cls, force_windows):
+ if force_windows or sys.platform=='win32':
+ return WindowsScriptWriter.get_writer()
+ return cls
+
+ @classmethod
+ def _get_script_args(cls, type_, name, header, script_text):
+ # Simply write the stub with no extension.
+ yield (name, header+script_text)
+
+
+class WindowsScriptWriter(ScriptWriter):
+ @classmethod
+ def get_writer(cls):
+ """
+ Get a script writer suitable for Windows
+ """
+ writer_lookup = dict(
+ executable=WindowsExecutableLauncherWriter,
+ natural=cls,
+ )
+ # for compatibility, use the executable launcher by default
+ launcher = os.environ.get('SETUPTOOLS_LAUNCHER', 'executable')
+ return writer_lookup[launcher]
+
+ @classmethod
+ def _get_script_args(cls, type_, name, header, script_text):
+ "For Windows, add a .py extension"
+ ext = dict(console='.pya', gui='.pyw')[type_]
+ if ext not in os.environ['PATHEXT'].lower().split(';'):
+ warnings.warn("%s not listed in PATHEXT; scripts will not be "
+ "recognized as executables." % ext, UserWarning)
+ old = ['.pya', '.py', '-script.py', '.pyc', '.pyo', '.pyw', '.exe']
+ old.remove(ext)
+ header = cls._adjust_header(type_, header)
+ blockers = [name+x for x in old]
+ yield name+ext, header+script_text, 't', blockers
+
+ @staticmethod
+ def _adjust_header(type_, orig_header):
+ """
+ Make sure 'pythonw' is used for gui and and 'python' is used for
+ console (regardless of what sys.executable is).
+ """
+ pattern = 'pythonw.exe'
+ repl = 'python.exe'
+ if type_ == 'gui':
+ pattern, repl = repl, pattern
+ pattern_ob = re.compile(re.escape(pattern), re.IGNORECASE)
+ new_header = pattern_ob.sub(string=orig_header, repl=repl)
+ clean_header = new_header[2:-1].strip('"')
+ if sys.platform == 'win32' and not os.path.exists(clean_header):
+ # the adjusted version doesn't exist, so return the original
+ return orig_header
+ return new_header
+
+
+class WindowsExecutableLauncherWriter(WindowsScriptWriter):
+ @classmethod
+ def _get_script_args(cls, type_, name, header, script_text):
+ """
+ For Windows, add a .py extension and an .exe launcher
+ """
+ if type_=='gui':
+ launcher_type = 'gui'
+ ext = '-script.pyw'
+ old = ['.pyw']
+ else:
+ launcher_type = 'cli'
+ ext = '-script.py'
+ old = ['.py','.pyc','.pyo']
+ hdr = cls._adjust_header(type_, header)
+ blockers = [name+x for x in old]
+ yield (name+ext, hdr+script_text, 't', blockers)
+ yield (
+ name+'.exe', get_win_launcher(launcher_type),
+ 'b' # write in binary mode
+ )
+ if not is_64bit():
+ # install a manifest for the launcher to prevent Windows
+ # from detecting it as an installer (which it will for
+ # launchers like easy_install.exe). Consider only
+ # adding a manifest for launchers detected as installers.
+ # See Distribute #143 for details.
+ m_name = name + '.exe.manifest'
+ yield (m_name, load_launcher_manifest(name), 't')
+
+# for backward-compatibility
+get_script_args = ScriptWriter.get_script_args
def get_win_launcher(type):
"""
@@ -1955,8 +1868,11 @@ def current_umask():
def bootstrap():
# This function is called when setuptools*.egg is run using /bin/sh
- import setuptools; argv0 = os.path.dirname(setuptools.__path__[0])
- sys.argv[0] = argv0; sys.argv.append(argv0); main()
+ import setuptools
+ argv0 = os.path.dirname(setuptools.__path__[0])
+ sys.argv[0] = argv0
+ sys.argv.append(argv0)
+ main()
def main(argv=None, **kw):
from setuptools import setup
@@ -1968,9 +1884,10 @@ usage: %(script)s [options] requirement_or_url ...
or: %(script)s --help
"""
- def gen_usage (script_name):
- script = os.path.basename(script_name)
- return USAGE % vars()
+ def gen_usage(script_name):
+ return USAGE % dict(
+ script=os.path.basename(script_name),
+ )
def with_ei_usage(f):
old_gen_usage = distutils.core.gen_usage
@@ -1996,7 +1913,3 @@ usage: %(script)s [options] requirement_or_url ...
distclass=DistributionWithoutHelpCommands, **kw
)
)
-
-
-
-
diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py
index 31700648..5953aad4 100755
--- a/setuptools/command/egg_info.py
+++ b/setuptools/command/egg_info.py
@@ -2,22 +2,22 @@
Create a distribution's .egg-info directory and contents"""
-# This module should be kept compatible with Python 2.3
-import os, re, sys
+import os
+import re
+import sys
+
from setuptools import Command
-from distutils.errors import *
+import distutils.errors
from distutils import log
from setuptools.command.sdist import sdist
from setuptools.compat import basestring
from setuptools import svn_utils
from distutils.util import convert_path
from distutils.filelist import FileList as _FileList
-from pkg_resources import parse_requirements, safe_name, parse_version, \
- safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename
+from pkg_resources import (parse_requirements, safe_name, parse_version,
+ safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename)
from setuptools.command.sdist import walk_revctrl
-#requires python >= 2.4
-from subprocess import Popen as _Popen, PIPE as _PIPE
class egg_info(Command):
description = "create a distribution's .egg-info directory"
@@ -38,12 +38,6 @@ class egg_info(Command):
negative_opt = {'no-svn-revision': 'tag-svn-revision',
'no-date': 'tag-date'}
-
-
-
-
-
-
def initialize_options(self):
self.egg_name = None
self.egg_version = None
@@ -57,35 +51,16 @@ class egg_info(Command):
def save_version_info(self, filename):
from setuptools.command.setopt import edit_config
- edit_config(
- filename,
- {'egg_info':
- {'tag_svn_revision':0, 'tag_date': 0, 'tag_build': self.tags()}
- }
+ values = dict(
+ egg_info=dict(
+ tag_svn_revision=0,
+ tag_date=0,
+ tag_build=self.tags(),
+ )
)
+ edit_config(filename, values)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- def finalize_options (self):
+ def finalize_options(self):
self.egg_name = safe_name(self.distribution.get_name())
self.vtags = self.tags()
self.egg_version = self.tagged_version()
@@ -95,7 +70,7 @@ class egg_info(Command):
parse_requirements('%s==%s' % (self.egg_name,self.egg_version))
)
except ValueError:
- raise DistutilsOptionError(
+ raise distutils.errors.DistutilsOptionError(
"Invalid distribution name or version syntax: %s-%s" %
(self.egg_name,self.egg_version)
)
@@ -125,7 +100,6 @@ class egg_info(Command):
pd._parsed_version = parse_version(self.egg_version)
self.distribution._patched_dist = None
-
def write_or_delete_file(self, what, filename, data, force=False):
"""Write `data` to `filename` or delete if empty
@@ -196,34 +170,14 @@ class egg_info(Command):
os.path.exists('.svn') or os.path.exists('PKG-INFO')
): version += '-r%s' % self.get_svn_revision()
if self.tag_date:
- import time; version += time.strftime("-%Y%m%d")
+ import time
+ version += time.strftime("-%Y%m%d")
return version
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@staticmethod
def get_svn_revision():
return str(svn_utils.SvnInfo.load(os.curdir).get_revision())
-
-
-
-
-
def find_sources(self):
"""Generate SOURCES.txt manifest file"""
manifest_filename = os.path.join(self.egg_info,"SOURCES.txt")
@@ -271,17 +225,11 @@ class FileList(_FileList):
self.files.append(path)
-
-
-
-
-
-
class manifest_maker(sdist):
template = "MANIFEST.in"
- def initialize_options (self):
+ def initialize_options(self):
self.use_defaults = 1
self.prune = 1
self.manifest_only = 1
@@ -303,7 +251,7 @@ class manifest_maker(sdist):
self.filelist.remove_duplicates()
self.write_manifest()
- def write_manifest (self):
+ def write_manifest(self):
"""Write the file list in 'self.filelist' (presumably as filled in
by 'add_defaults()' and 'read_template()') to the manifest file
named by 'self.manifest'.
@@ -342,7 +290,7 @@ class manifest_maker(sdist):
ei_cmd = self.get_finalized_command('egg_info')
self.filelist.include_pattern("*", prefix=ei_cmd.egg_info)
- def prune_file_list (self):
+ def prune_file_list(self):
build = self.get_finalized_command('build')
base_dir = self.distribution.get_fullname()
self.filelist.exclude_pattern(None, prefix=build.build_base)
@@ -351,7 +299,7 @@ class manifest_maker(sdist):
self.filelist.exclude_pattern(sep+r'(RCS|CVS|\.svn)'+sep, is_regex=1)
-def write_file (filename, contents):
+def write_file(filename, contents):
"""Create a file with the specified name and write 'contents' (a
sequence of strings without line terminators) to it.
"""
@@ -362,24 +310,12 @@ def write_file (filename, contents):
f.write(contents)
f.close()
-
-
-
-
-
-
-
-
-
-
-
-
def write_pkg_info(cmd, basename, filename):
log.info("writing %s", filename)
if not cmd.dry_run:
metadata = cmd.distribution.metadata
metadata.version, oldver = cmd.egg_version, metadata.version
- metadata.name, oldname = cmd.egg_name, metadata.name
+ metadata.name, oldname = cmd.egg_name, metadata.name
try:
# write unescaped data to PKG-INFO, so older pkg_resources
# can still parse it
@@ -408,14 +344,14 @@ def write_requirements(cmd, basename, filename):
def write_toplevel_names(cmd, basename, filename):
pkgs = dict.fromkeys(
- [k.split('.',1)[0]
+ [
+ k.split('.',1)[0]
for k in cmd.distribution.iter_distribution_names()
]
)
cmd.write_file("top-level names", filename, '\n'.join(pkgs)+'\n')
-
def overwrite_arg(cmd, basename, filename):
write_arg(cmd, basename, filename, True)
@@ -454,7 +390,3 @@ def get_pkg_info_revision():
return int(match.group(1))
f.close()
return 0
-
-
-
-#
diff --git a/setuptools/command/install.py b/setuptools/command/install.py
index 247c4f25..459cd3cd 100644
--- a/setuptools/command/install.py
+++ b/setuptools/command/install.py
@@ -1,4 +1,6 @@
-import setuptools, sys, glob
+import setuptools
+import sys
+import glob
from distutils.command.install import install as _install
from distutils.errors import DistutilsArgError
@@ -15,7 +17,7 @@ class install(_install):
]
new_commands = [
('install_egg_info', lambda self: True),
- ('install_scripts', lambda self: True),
+ ('install_scripts', lambda self: True),
]
_nc = dict(new_commands)
@@ -46,7 +48,6 @@ class install(_install):
self.path_file = None
self.extra_dirs = ''
-
def run(self):
# Explicit request for old-style install? Just do it
if self.old_and_unmanageable or self.single_version_externally_managed:
@@ -72,11 +73,6 @@ class install(_install):
else:
self.do_egg_install()
-
-
-
-
-
def do_egg_install(self):
easy_install = self.distribution.get_command_class('easy_install')
@@ -105,20 +101,3 @@ class install(_install):
install.sub_commands = [
cmd for cmd in _install.sub_commands if cmd[0] not in install._nc
] + install.new_commands
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#
diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py
index 1bd07e65..04cbccdf 100755
--- a/setuptools/command/sdist.py
+++ b/setuptools/command/sdist.py
@@ -1,9 +1,12 @@
+import os
+import re
+import sys
+from glob import glob
+
+import pkg_resources
from distutils.command.sdist import sdist as _sdist
from distutils.util import convert_path
from distutils import log
-from glob import glob
-import os, re, sys, pkg_resources
-from glob import glob
from setuptools import svn_utils
READMES = ('README', 'README.rst', 'README.txt')
@@ -19,7 +22,7 @@ def walk_revctrl(dirname=''):
#TODO will need test case
class re_finder(object):
- def __init__(self, path, pattern, postproc=None):
+ def __init__(self, path, pattern, postproc=lambda x: x):
self.pattern = pattern
self.postproc = postproc
self.path = convert_path(path)
@@ -32,10 +35,9 @@ class re_finder(object):
f.close()
for match in self.pattern.finditer(data):
path = match.group(1)
- if postproc:
- #postproc used to be used when the svn finder
- #was an re_finder for calling unescape
- path = postproc(path)
+ # postproc was formerly used when the svn finder
+ # was an re_finder for calling unescape
+ path = self.postproc(path)
yield svn_utils.joinpath(dirname,path)
def find(self, dirname=''):
@@ -64,17 +66,6 @@ finders = [
]
-
-
-
-
-
-
-
-
-
-
-
class sdist(_sdist):
"""Smart sdist that finds anything supported by revision control"""
@@ -129,11 +120,12 @@ class sdist(_sdist):
# Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle
# has been fixed, so only override the method if we're using an earlier
# Python.
- if (
- sys.version_info < (2,7,2)
- or (3,0) <= sys.version_info < (3,1,4)
- or (3,2) <= sys.version_info < (3,2,1)
- ):
+ has_leaky_handle = (
+ sys.version_info < (2,7,2)
+ or (3,0) <= sys.version_info < (3,1,4)
+ or (3,2) <= sys.version_info < (3,2,1)
+ )
+ if has_leaky_handle:
read_template = __read_template_hack
def add_defaults(self):
@@ -198,7 +190,6 @@ class sdist(_sdist):
"standard file not found: should have one of " +', '.join(READMES)
)
-
def make_release_tree(self, base_dir, files):
_sdist.make_release_tree(self, base_dir, files)
@@ -245,10 +236,3 @@ class sdist(_sdist):
continue
self.filelist.append(line)
manifest.close()
-
-
-
-
-
-
-#
diff --git a/setuptools/command/upload.py b/setuptools/command/upload.py
deleted file mode 100755
index 02d955ed..00000000
--- a/setuptools/command/upload.py
+++ /dev/null
@@ -1,184 +0,0 @@
-"""distutils.command.upload
-
-Implements the Distutils 'upload' subcommand (upload package to PyPI)."""
-
-from distutils.errors import *
-from distutils.core import Command
-from distutils.spawn import spawn
-from distutils import log
-try:
- from hashlib import md5
-except ImportError:
- from md5 import md5
-import os
-import sys
-import socket
-import platform
-import base64
-
-from setuptools.compat import urlparse, StringIO, httplib, ConfigParser
-
-class upload(Command):
-
- description = "upload binary package to PyPI"
-
- DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi'
-
- user_options = [
- ('repository=', 'r',
- "url of repository [default: %s]" % DEFAULT_REPOSITORY),
- ('show-response', None,
- 'display full response text from server'),
- ('sign', 's',
- 'sign files to upload using gpg'),
- ('identity=', 'i', 'GPG identity used to sign files'),
- ]
- boolean_options = ['show-response', 'sign']
-
- def initialize_options(self):
- self.username = ''
- self.password = ''
- self.repository = ''
- self.show_response = 0
- self.sign = False
- self.identity = None
-
- def finalize_options(self):
- if self.identity and not self.sign:
- raise DistutilsOptionError(
- "Must use --sign for --identity to have meaning"
- )
- if 'HOME' in os.environ:
- rc = os.path.join(os.environ['HOME'], '.pypirc')
- if os.path.exists(rc):
- self.announce('Using PyPI login from %s' % rc)
- config = ConfigParser.ConfigParser({
- 'username':'',
- 'password':'',
- 'repository':''})
- config.read(rc)
- if not self.repository:
- self.repository = config.get('server-login', 'repository')
- if not self.username:
- self.username = config.get('server-login', 'username')
- if not self.password:
- self.password = config.get('server-login', 'password')
- if not self.repository:
- self.repository = self.DEFAULT_REPOSITORY
-
- def run(self):
- if not self.distribution.dist_files:
- raise DistutilsOptionError("No dist file created in earlier command")
- for command, pyversion, filename in self.distribution.dist_files:
- self.upload_file(command, pyversion, filename)
-
- def upload_file(self, command, pyversion, filename):
- # Sign if requested
- if self.sign:
- gpg_args = ["gpg", "--detach-sign", "-a", filename]
- if self.identity:
- gpg_args[2:2] = ["--local-user", self.identity]
- spawn(gpg_args,
- dry_run=self.dry_run)
-
- # Fill in the data
- f = open(filename,'rb')
- content = f.read()
- f.close()
- basename = os.path.basename(filename)
- comment = ''
- if command=='bdist_egg' and self.distribution.has_ext_modules():
- comment = "built on %s" % platform.platform(terse=1)
- data = {
- ':action':'file_upload',
- 'protocol_version':'1',
- 'name':self.distribution.get_name(),
- 'version':self.distribution.get_version(),
- 'content':(basename,content),
- 'filetype':command,
- 'pyversion':pyversion,
- 'md5_digest':md5(content).hexdigest(),
- }
- if command == 'bdist_rpm':
- dist, version, id = platform.dist()
- if dist:
- comment = 'built for %s %s' % (dist, version)
- elif command == 'bdist_dumb':
- comment = 'built for %s' % platform.platform(terse=1)
- data['comment'] = comment
-
- if self.sign:
- asc_file = open(filename + ".asc")
- data['gpg_signature'] = (os.path.basename(filename) + ".asc", asc_file.read())
- asc_file.close()
-
- # set up the authentication
- auth = "Basic " + base64.encodestring(self.username + ":" + self.password).strip()
-
- # Build up the MIME payload for the POST data
- boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
- sep_boundary = '\n--' + boundary
- end_boundary = sep_boundary + '--'
- body = StringIO.StringIO()
- for key, value in data.items():
- # handle multiple entries for the same name
- if type(value) != type([]):
- value = [value]
- for value in value:
- if type(value) is tuple:
- fn = ';filename="%s"' % value[0]
- value = value[1]
- else:
- fn = ""
- value = str(value)
- body.write(sep_boundary)
- body.write('\nContent-Disposition: form-data; name="%s"'%key)
- body.write(fn)
- body.write("\n\n")
- body.write(value)
- if value and value[-1] == '\r':
- body.write('\n') # write an extra newline (lurve Macs)
- body.write(end_boundary)
- body.write("\n")
- body = body.getvalue()
-
- self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO)
-
- # build the Request
- # We can't use urllib2 since we need to send the Basic
- # auth right with the first request
- schema, netloc, url, params, query, fragments = \
- urlparse(self.repository)
- assert not params and not query and not fragments
- if schema == 'http':
- http = httplib.HTTPConnection(netloc)
- elif schema == 'https':
- http = httplib.HTTPSConnection(netloc)
- else:
- raise AssertionError("unsupported schema " + schema)
-
- data = ''
- loglevel = log.INFO
- try:
- http.connect()
- http.putrequest("POST", url)
- http.putheader('Content-type',
- 'multipart/form-data; boundary=%s'%boundary)
- http.putheader('Content-length', str(len(body)))
- http.putheader('Authorization', auth)
- http.endheaders()
- http.send(body)
- except socket.error:
- e = sys.exc_info()[1]
- self.announce(str(e), log.ERROR)
- return
-
- r = http.getresponse()
- if r.status == 200:
- self.announce('Server response (%s): %s' % (r.status, r.reason),
- log.INFO)
- else:
- self.announce('Upload failed (%s): %s' % (r.status, r.reason),
- log.ERROR)
- if self.show_response:
- print('-'*75, r.read(), '-'*75)
diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py
index 12bc916b..cad7a52d 100644
--- a/setuptools/command/upload_docs.py
+++ b/setuptools/command/upload_docs.py
@@ -17,20 +17,11 @@ from pkg_resources import iter_entry_points
from distutils import log
from distutils.errors import DistutilsOptionError
+from distutils.command.upload import upload
-try:
- from distutils.command.upload import upload
-except ImportError:
- from setuptools.command.upload import upload
+from setuptools.compat import httplib, urlparse, unicode, iteritems, PY3
-from setuptools.compat import httplib, urlparse, unicode, iteritems
-
-_IS_PYTHON3 = sys.version > '3'
-
-if _IS_PYTHON3:
- errors = 'surrogateescape'
-else:
- errors = 'strict'
+errors = 'surrogateescape' if PY3 else 'strict'
# This is not just a replacement for byte literals
@@ -124,7 +115,7 @@ class upload_docs(upload):
# set up the authentication
credentials = b(self.username + ':' + self.password)
credentials = standard_b64encode(credentials)
- if sys.version_info >= (3,):
+ if PY3:
credentials = credentials.decode('ascii')
auth = "Basic " + credentials
@@ -136,7 +127,7 @@ class upload_docs(upload):
for key, values in iteritems(data):
title = '\nContent-Disposition: form-data; name="%s"' % key
# handle multiple entries for the same name
- if type(values) != type([]):
+ if not isinstance(values, list):
values = [values]
for value in values:
if type(value) is tuple:
@@ -171,12 +162,11 @@ class upload_docs(upload):
raise AssertionError("unsupported schema "+schema)
data = ''
- loglevel = log.INFO
try:
conn.connect()
conn.putrequest("POST", url)
- conn.putheader('Content-type',
- 'multipart/form-data; boundary=%s'%boundary)
+ content_type = 'multipart/form-data; boundary=%s' % boundary
+ conn.putheader('Content-type', content_type)
conn.putheader('Content-length', str(len(body)))
conn.putheader('Authorization', auth)
conn.endheaders()