summaryrefslogtreecommitdiff
path: root/setuptools/command/easy_install.py
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools/command/easy_install.py')
-rwxr-xr-xsetuptools/command/easy_install.py427
1 files changed, 334 insertions, 93 deletions
diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py
index 71794865..146e1f47 100755
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -7,21 +7,42 @@ A tool for doing automatic download/extract/build of distutils-based Python
packages. For detailed documentation, see the accompanying EasyInstall.txt
file, or visit the `EasyInstall home page`__.
-__ http://peak.telecommunity.com/DevCenter/EasyInstall
+__ http://packages.python.org/setuptools/easy_install.html
+
"""
-import sys, os.path, zipimport, shutil, tempfile, zipfile, re, stat, random
+import sys
+import os
+import zipimport
+import shutil
+import tempfile
+import zipfile
+import re
+import stat
+import random
+import platform
from glob import glob
-from setuptools import Command
+import pkg_resources
+from setuptools import Command, _dont_write_bytecode
from setuptools.sandbox import run_setup
from distutils import log, dir_util
-from distutils.sysconfig import get_python_lib
+from distutils.util import get_platform
+from distutils.util import convert_path, subst_vars
+from distutils.sysconfig import get_python_lib, get_config_vars
from distutils.errors import DistutilsArgError, DistutilsOptionError, \
- DistutilsError
+ DistutilsError, DistutilsPlatformError
+from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS
+from setuptools.command import setopt
from setuptools.archive_util import unpack_archive
-from setuptools.package_index import PackageIndex, parse_bdist_wininst
+from setuptools.package_index import PackageIndex
from setuptools.package_index import URL_SCHEME
from setuptools.command import bdist_egg, egg_info
-from pkg_resources import *
+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.path.normpath(sys.executable)
__all__ = [
@@ -29,6 +50,13 @@ __all__ = [
'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)
@@ -39,6 +67,25 @@ def samefile(p1,p2):
os.path.normpath(os.path.normcase(p2))
)
+if sys.version_info <= (3,):
+ def _to_ascii(s):
+ return s
+ def isascii(s):
+ try:
+ unicode(s, 'ascii')
+ return True
+ except UnicodeError:
+ return False
+else:
+ def _to_ascii(s):
+ return s.encode('ascii')
+ def isascii(s):
+ try:
+ s.encode('ascii')
+ return True
+ except UnicodeError:
+ return False
+
class easy_install(Command):
"""Manage a download/build/install process"""
description = "Find/get/install Python packages"
@@ -71,16 +118,32 @@ class easy_install(Command):
('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"),
+ ('version', None, "print version information and exit"),
+ ('no-find-links', None,
+ "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',
- 'no-deps', 'local-snapshots-ok',
+ 'no-deps', 'local-snapshots-ok', 'version'
]
+
+ if HAS_USER_SITE:
+ user_options.append(('user', None,
+ "install in user site-package '%s'" % site.USER_SITE))
+ boolean_options.append('user')
+
+
negative_opt = {'always-unzip': 'zip-ok'}
create_index = PackageIndex
def initialize_options(self):
+ if HAS_USER_SITE:
+ whereami = os.path.abspath(__file__)
+ self.user = whereami.startswith(site.USER_SITE)
+ else:
+ self.user = 0
+
self.zip_ok = self.local_snapshots_ok = None
self.install_dir = self.script_dir = self.exclude_scripts = None
self.index_url = None
@@ -91,6 +154,22 @@ class easy_install(Command):
self.upgrade = self.always_copy = self.multi_version = None
self.editable = self.no_deps = self.allow_hosts = None
self.root = self.prefix = self.no_report = None
+ self.version = None
+ self.install_purelib = None # for pure module distributions
+ self.install_platlib = None # non-pure (dists w/ extensions)
+ self.install_headers = None # for C/C++ headers
+ self.install_lib = None # set to either purelib or platlib
+ self.install_scripts = None
+ self.install_data = None
+ self.install_base = None
+ self.install_platbase = None
+ if HAS_USER_SITE:
+ self.install_userbase = site.USER_BASE
+ self.install_usersite = site.USER_SITE
+ else:
+ self.install_userbase = None
+ self.install_usersite = None
+ self.no_find_links = None
# Options not specifiable via command line
self.package_index = None
@@ -122,12 +201,56 @@ class easy_install(Command):
os.unlink(filename)
def finalize_options(self):
+ if self.version:
+ print 'setuptools %s' % get_distribution('setuptools').version
+ sys.exit()
+
+ 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['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:
+ self.create_home_path()
+ if self.install_userbase is None:
+ raise DistutilsPlatformError(
+ "User base directory is not specified")
+ self.install_base = self.install_platbase = self.install_userbase
+ if os.name == 'posix':
+ self.select_scheme("unix_user")
+ else:
+ self.select_scheme(os.name + "_user")
+
+ self.expand_basedirs()
+ self.expand_dirs()
+
self._expand('install_dir','script_dir','build_directory','site_dirs')
# If a non-default installation directory was specified, default the
# script directory to match it.
if self.script_dir is None:
self.script_dir = self.install_dir
+ if self.no_find_links is None:
+ self.no_find_links = False
+
# Let install_dir get set by install_lib command, which in turn
# gets its info from the install command, and takes into account
# --prefix and --home and all that other crud.
@@ -138,6 +261,10 @@ class easy_install(Command):
self.set_undefined_options('install_scripts',
('install_dir', 'script_dir')
)
+
+ if self.user and self.install_purelib:
+ self.install_dir = self.install_purelib
+ self.script_dir = self.install_scripts
# default --record from the install command
self.set_undefined_options('install', ('record', 'record'))
normpath = map(normalize_path, sys.path)
@@ -179,7 +306,8 @@ class easy_install(Command):
self.find_links = []
if self.local_snapshots_ok:
self.package_index.scan_egg_links(self.shadow_path+sys.path)
- self.package_index.add_find_links(self.find_links)
+ if not self.no_find_links:
+ self.package_index.add_find_links(self.find_links)
self.set_undefined_options('install_lib', ('optimize','optimize'))
if not isinstance(self.optimize,int):
try:
@@ -203,8 +331,29 @@ class easy_install(Command):
self.outputs = []
+
+ def _expand_attrs(self, attrs):
+ for attr in attrs:
+ val = getattr(self, attr)
+ if val is not None:
+ if os.name == 'posix' or os.name == 'nt':
+ val = os.path.expanduser(val)
+ val = subst_vars(val, self.config_vars)
+ setattr(self, attr, val)
+
+ def expand_basedirs(self):
+ """Calls `os.path.expanduser` on install_base, install_platbase and
+ root."""
+ self._expand_attrs(['install_base', 'install_platbase', 'root'])
+
+ def expand_dirs(self):
+ """Calls `os.path.expanduser` on install dirs."""
+ self._expand_attrs(['install_purelib', 'install_platlib',
+ 'install_lib', 'install_headers',
+ 'install_scripts', 'install_data',])
+
def run(self):
- if self.verbose!=self.distribution.verbose:
+ if self.verbose != self.distribution.verbose:
log.set_verbosity(self.verbose)
try:
for spec in self.args:
@@ -246,6 +395,7 @@ class easy_install(Command):
def check_site_dir(self):
"""Verify that self.install_dir is .pth-capable dir, if needed"""
+
instdir = normalize_path(self.install_dir)
pth_file = os.path.join(instdir,'easy-install.pth')
@@ -317,7 +467,7 @@ variable.
For information on other options, you may wish to consult the
documentation at:
- http://peak.telecommunity.com/EasyInstall.html
+ http://packages.python.org/setuptools/easy_install.html
Please make the appropriate changes for your system and try again.
"""
@@ -335,12 +485,15 @@ Please make the appropriate changes for your system and try again.
ok_exists = os.path.exists(ok_file)
try:
if ok_exists: os.unlink(ok_file)
+ dirname = os.path.dirname(ok_file)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
f = open(pth_file,'w')
except (OSError,IOError):
self.cant_write_to_target()
else:
try:
- f.write("import os;open(%r,'w').write('OK')\n" % (ok_file,))
+ f.write("import os; f = open(%r, 'w'); f.write('OK'); f.close()\n" % (ok_file,))
f.close(); f=None
executable = sys.executable
if os.name=='nt':
@@ -371,6 +524,10 @@ Please make the appropriate changes for your system and try again.
"""Write all the scripts for `dist`, unless scripts are excluded"""
if not self.exclude_scripts and dist.metadata_isdir('scripts'):
for script_name in dist.metadata_listdir('scripts'):
+ if dist.metadata_isdir('scripts/' + script_name):
+ # The "script" is a directory, likely a Python 3
+ # __pycache__ directory, so skip it.
+ continue
self.install_script(
dist, script_name,
dist.get_metadata('scripts/'+script_name)
@@ -487,6 +644,15 @@ Please make the appropriate changes for your system and try again.
+ 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!
+ scheme = INSTALL_SCHEMES[name]
+ for key in SCHEME_KEYS:
+ attrname = 'install_' + key
+ if getattr(self, attrname) is None:
+ setattr(self, attrname, scheme[key])
+
@@ -497,7 +663,8 @@ Please make the appropriate changes for your system and try again.
self.install_egg_scripts(dist)
self.installed_projects[dist.key] = dist
log.info(self.installation_report(requirement, dist, *info))
- if dist.has_metadata('dependency_links.txt'):
+ if (dist.has_metadata('dependency_links.txt') and
+ not self.no_find_links):
self.package_index.add_find_links(
dist.get_metadata_lines('dependency_links.txt')
)
@@ -577,23 +744,27 @@ Please make the appropriate changes for your system and try again.
spec = str(dist.as_requirement())
is_script = is_python_script(script_text, script_name)
- if is_script and dev_path:
- script_text = get_script_header(script_text) + (
- "# EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r\n"
- "__requires__ = %(spec)r\n"
- "from pkg_resources import require; require(%(spec)r)\n"
- "del require\n"
- "__file__ = %(dev_path)r\n"
- "execfile(__file__)\n"
- ) % locals()
- elif is_script:
- script_text = get_script_header(script_text) + (
- "# EASY-INSTALL-SCRIPT: %(spec)r,%(script_name)r\n"
- "__requires__ = %(spec)r\n"
- "import pkg_resources\n"
- "pkg_resources.run_script(%(spec)r, %(script_name)r)\n"
- ) % locals()
- self.write_script(script_name, script_text, 'b')
+ def get_template(filename):
+ """
+ There are a couple of template scripts in the package. This
+ function loads one of them and prepares it for use.
+
+ These templates use triple-quotes to escape variable
+ substitutions so the scripts get the 2to3 treatment when build
+ on Python 3. The templates cannot use triple-quotes naturally.
+ """
+ raw_bytes = resource_string('setuptools', template_name)
+ template_str = raw_bytes.decode('utf-8')
+ clean_template = template_str.replace('"""', '')
+ return clean_template
+
+ if is_script:
+ template_name = 'script template.py'
+ if dev_path:
+ template_name = template_name.replace('.py', ' (dev).py')
+ script_text = (get_script_header(script_text) +
+ get_template(template_name) % locals())
+ self.write_script(script_name, _to_ascii(script_text), 'b')
def write_script(self, script_name, contents, mode="t", blockers=()):
"""Write an executable file to the scripts directory"""
@@ -603,12 +774,13 @@ Please make the appropriate changes for your system and try again.
target = os.path.join(self.script_dir, script_name)
self.add_output(target)
+ mask = current_umask()
if not self.dry_run:
ensure_directory(target)
f = open(target,"w"+mode)
f.write(contents)
f.close()
- chmod(target,0755)
+ chmod(target, 0777-mask)
@@ -705,7 +877,7 @@ Please make the appropriate changes for your system and try again.
# Create a dummy distribution object until we build the real distro
dist = Distribution(None,
project_name=cfg.get('metadata','name'),
- version=cfg.get('metadata','version'), platform="win32"
+ version=cfg.get('metadata','version'), platform=get_platform()
)
# Convert the .exe to an unpacked egg
@@ -781,7 +953,9 @@ Please make the appropriate changes for your system and try again.
if locals()[name]:
txt = os.path.join(egg_tmp, 'EGG-INFO', name+'.txt')
if not os.path.exists(txt):
- open(txt,'w').write('\n'.join(locals()[name])+'\n')
+ f = open(txt,'w')
+ f.write('\n'.join(locals()[name])+'\n')
+ f.close()
def check_conflicts(self, dist):
"""Verify that there are no conflicting "old-style" packages"""
@@ -922,11 +1096,14 @@ See the setuptools documentation for the "develop" command for more info.
def build_and_install(self, setup_script, setup_base):
args = ['bdist_egg', '--dist-dir']
+
dist_dir = tempfile.mkdtemp(
prefix='egg-dist-tmp-', dir=os.path.dirname(setup_script)
)
try:
+ self._set_fetcher_options(os.path.dirname(setup_script))
args.append(dist_dir)
+
self.run_setup(setup_script, setup_base, args)
all_eggs = Environment([dist_dir])
eggs = []
@@ -941,6 +1118,30 @@ See the setuptools documentation for the "develop" command for more info.
rmtree(dist_dir)
log.set_verbosity(self.verbose) # restore our log verbosity
+ def _set_fetcher_options(self, base):
+ """
+ When easy_install is about to run bdist_egg on a source dist, that
+ source dist might have 'setup_requires' directives, requiring
+ additional fetching. Ensure the fetcher options given to easy_install
+ are available to that command as well.
+ """
+ # find the fetch options from easy_install and write them out
+ # to the setup.cfg file.
+ ei_opts = self.distribution.get_option_dict('easy_install').copy()
+ fetch_directives = (
+ 'find_links', 'site_dirs', 'index_url', 'optimize',
+ 'site_dirs', 'allow_hosts',
+ )
+ fetch_options = {}
+ for key, val in ei_opts.iteritems():
+ if key not in fetch_directives: continue
+ fetch_options[key.replace('_', '-')] = val[1]
+ # create a settings dictionary suitable for `edit_config`
+ settings = dict(easy_install=fetch_options)
+ cfg_filename = os.path.join(base, 'setup.cfg')
+ setopt.edit_config(cfg_filename, settings)
+
+
def update_pth(self,dist):
if self.pth_file is None:
return
@@ -1001,6 +1202,10 @@ See the setuptools documentation for the "develop" command for more info.
chmod(f, mode)
def byte_compile(self, to_compile):
+ if _dont_write_bytecode:
+ self.warn('byte-compiling is disabled, skipping.')
+ return
+
from distutils.util import byte_compile
try:
# try to make the byte compile messages quieter
@@ -1049,7 +1254,7 @@ Here are some of your options for correcting the problem:
* You can set up the installation directory to support ".pth" files by
using one of the approaches described here:
- http://peak.telecommunity.com/EasyInstall.html#custom-installation-locations
+ http://packages.python.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','')
@@ -1076,7 +1281,13 @@ Please make the appropriate changes for your system and try again.""" % (
if os.path.exists(sitepy):
log.debug("Checking existing site.py in %s", self.install_dir)
- current = open(sitepy,'rb').read()
+ f = open(sitepy,'rb')
+ current = f.read()
+ # we want str, not bytes
+ if sys.version_info >= (3,):
+ current = current.decode()
+
+ f.close()
if not current.startswith('def __boot():'):
raise DistutilsError(
"%s is not a setuptools-generated site.py; please"
@@ -1097,7 +1308,15 @@ Please make the appropriate changes for your system and try again.""" % (
-
+ def create_home_path(self):
+ """Create directories under ~."""
+ if not self.user:
+ return
+ home = convert_path(os.path.expanduser("~"))
+ for name, path in self.config_vars.iteritems():
+ if path.startswith(home) and not os.path.isdir(path):
+ self.debug_print("os.makedirs('%s', 0700)" % path)
+ os.makedirs(path, 0700)
@@ -1183,7 +1402,11 @@ def get_site_dirs():
site_lib = get_python_lib(plat_specific)
if site_lib not in sitedirs: sitedirs.append(site_lib)
+ if HAS_USER_SITE:
+ sitedirs.append(site.USER_SITE)
+
sitedirs = map(normalize_path, sitedirs)
+
return sitedirs
@@ -1252,7 +1475,19 @@ def extract_wininst_cfg(dist_filename):
f.seek(prepended-(12+cfglen))
cfg = ConfigParser.RawConfigParser({'version':'','target_version':''})
try:
- cfg.readfp(StringIO.StringIO(f.read(cfglen).split(chr(0),1)[0]))
+ part = f.read(cfglen)
+ # part is in bytes, but we need to read up to the first null
+ # byte.
+ if sys.version_info >= (2,6):
+ null_byte = bytes([0])
+ 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')
+ cfg.readfp(StringIO.StringIO(config))
except ConfigParser.Error:
return None
if not cfg.has_section('metadata') or not cfg.has_section('Setup'):
@@ -1274,8 +1509,9 @@ def get_exe_prefixes(exe_filename):
prefixes = [
('PURELIB/', ''), ('PLATLIB/pywin32_system32', ''),
- ('PLATLIB/', ''), ('DATA/lib/site-packages/', ''),
- ('SCRIPTS/', 'EGG-INFO/scripts/')
+ ('PLATLIB/', ''),
+ ('SCRIPTS/', 'EGG-INFO/scripts/'),
+ ('DATA/lib/site-packages', ''),
]
z = zipfile.ZipFile(exe_filename)
try:
@@ -1291,7 +1527,10 @@ def get_exe_prefixes(exe_filename):
if name.endswith('-nspkg.pth'):
continue
if parts[0].upper() in ('PURELIB','PLATLIB'):
- for pth in yield_lines(z.read(name)):
+ contents = z.read(name)
+ if sys.version_info >= (3,):
+ contents = contents.decode()
+ for pth in yield_lines(contents):
pth = pth.strip().replace('\\','/')
if not pth.startswith('import'):
prefixes.append((('%s/%s/' % (parts[0],pth)), ''))
@@ -1327,7 +1566,8 @@ class PthDistributions(Environment):
saw_import = False
seen = dict.fromkeys(self.sitedirs)
if os.path.isfile(self.filename):
- for line in open(self.filename,'rt'):
+ f = open(self.filename,'rt')
+ for line in f:
if line.startswith('import'):
saw_import = True
continue
@@ -1345,6 +1585,7 @@ class PthDistributions(Environment):
self.dirty = True # we cleaned up, so we're dirty now :)
continue
seen[path] = 1
+ f.close()
if self.paths and not saw_import:
self.dirty = True # ensure anything we touch has import wrappers
@@ -1370,7 +1611,7 @@ class PthDistributions(Environment):
if os.path.islink(self.filename):
os.unlink(self.filename)
- f = open(self.filename,'wb')
+ f = open(self.filename,'wt')
f.write(data); f.close()
elif os.path.exists(self.filename):
@@ -1381,8 +1622,12 @@ class PthDistributions(Environment):
def add(self,dist):
"""Add `dist` to the distribution map"""
- if dist.location not in self.paths and dist.location not in self.sitedirs:
- self.paths.append(dist.location); self.dirty = True
+ if (dist.location not in self.paths and (
+ dist.location not in self.sitedirs or
+ dist.location == os.getcwd() #account for '.' being in PYTHONPATH
+ )):
+ self.paths.append(dist.location)
+ self.dirty = True
Environment.add(self,dist)
def remove(self,dist):
@@ -1410,6 +1655,11 @@ class PthDistributions(Environment):
def get_script_header(script_text, executable=sys_executable, wininst=False):
"""Create a #! line, getting options (if any) from script_text"""
from distutils.command.build_scripts import first_line_re
+
+ # first_line_re in Python >=3.1.4 and >=3.2.1 is a bytes pattern.
+ if not isinstance(first_line_re.pattern, str):
+ first_line_re = re.compile(first_line_re.pattern.decode())
+
first = (script_text+'\n').splitlines()[0]
match = first_line_re.match(first)
options = ''
@@ -1421,7 +1671,7 @@ def get_script_header(script_text, executable=sys_executable, wininst=False):
else:
executable = nt_quote_arg(executable)
hdr = "#!%(executable)s%(options)s\n" % locals()
- if unicode(hdr,'ascii','ignore').encode('ascii') != hdr:
+ if not isascii(hdr):
# Non-ascii path to sys.executable, use -x to prevent warnings
if options:
if options.strip().startswith('-'):
@@ -1543,6 +1793,11 @@ def chmod(path, mode):
def fix_jython_executable(executable, options):
if sys.platform.startswith('java') and is_sh(executable):
+ # Workaround for Jython is not needed on Linux systems.
+ import java
+ if java.lang.System.getProperty("os.name") == "Linux":
+ return executable
+
# Workaround Jython's sys.executable being a .sh (an invalid
# shebang line interpreter)
if options:
@@ -1561,16 +1816,18 @@ def get_script_args(dist, executable=sys_executable, wininst=False):
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():
+ 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"
- "sys.exit(\n"
- " load_entry_point(%(spec)r, %(group)r, %(name)r)()\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
@@ -1582,7 +1839,12 @@ def get_script_args(dist, executable=sys_executable, wininst=False):
ext, launcher = '-script.py', 'cli.exe'
old = ['.py','.pyc','.pyo']
new_header = re.sub('(?i)pythonw.exe','python.exe',header)
-
+ if platform.machine().lower()=='arm':
+ launcher = launcher.replace(".", "-arm.")
+ if is_64bit():
+ launcher = launcher.replace(".", "-64.")
+ else:
+ launcher = launcher.replace(".", "-32.")
if os.path.exists(new_header[2:-1].strip('"')) or sys.platform!='win32':
hdr = new_header
else:
@@ -1590,53 +1852,27 @@ def get_script_args(dist, executable=sys_executable, wininst=False):
yield (name+ext, hdr+script_text, 't', [name+x for x in old])
yield (
name+'.exe', resource_string('setuptools', launcher),
- 'b') # write in binary mode
- yield (name+'.exe.manifest', _launcher_manifest % (name,), 't')
+ '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)
-_launcher_manifest = """
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
- <assemblyIdentity version="1.0.0.0"
- processorArchitecture="X86"
- name="%s.exe"
- type="win32"/>
-
- <!-- Identify the application security requirements. -->
- <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
- <security>
- <requestedPrivileges>
- <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
- </requestedPrivileges>
- </security>
- </trustInfo>
-</assembly>"""
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+def load_launcher_manifest(name):
+ manifest = pkg_resources.resource_string(__name__, 'launcher manifest.xml')
+ if sys.version_info[0] < 3:
+ return manifest % vars()
+ else:
+ return manifest.decode('utf-8') % vars()
def rmtree(path, ignore_errors=False, onerror=auto_chmod):
"""Recursively delete a directory tree.
@@ -1673,12 +1909,16 @@ def rmtree(path, ignore_errors=False, onerror=auto_chmod):
except os.error:
onerror(os.rmdir, path, sys.exc_info())
+def current_umask():
+ tmp = os.umask(022)
+ os.umask(tmp)
+ return tmp
+
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()
-
def main(argv=None, **kw):
from setuptools import setup
from setuptools.dist import Distribution
@@ -1703,6 +1943,7 @@ usage: %(script)s [options] requirement_or_url ...
class DistributionWithoutHelpCommands(Distribution):
common_usage = ""
+
def _show_help(self,*args,**kw):
with_ei_usage(lambda: Distribution._show_help(self,*args,**kw))