aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2013-05-13 07:07:03 -0400
committerJason R. Coombs <jaraco@jaraco.com>2013-05-13 07:07:03 -0400
commit8f05565451ef38cc10074582ad826941f8f8c899 (patch)
tree3b13af466ad891a3481fd420c63f612a7621b44e
parenta0d19667eaa92bd95f2bebfcb50a68d0921282eb (diff)
parent068ab0e3a6e5146137ee9f913e3b1fbc5b337c22 (diff)
downloadexternal_python_setuptools-8f05565451ef38cc10074582ad826941f8f8c899.tar.gz
external_python_setuptools-8f05565451ef38cc10074582ad826941f8f8c899.tar.bz2
external_python_setuptools-8f05565451ef38cc10074582ad826941f8f8c899.zip
Merge with Distribute 0.6.39
--HG-- rename : distribute_setup.py => ez_setup.py
-rw-r--r--.hgignore1
-rw-r--r--.hgtags5
-rw-r--r--CHANGES.txt39
-rw-r--r--CONTRIBUTORS.txt1
-rw-r--r--MANIFEST.in2
-rw-r--r--docs/conf.py4
-rw-r--r--ez_setup.py2
-rwxr-xr-xlauncher.c8
-rw-r--r--msvc-build-launcher.cmd52
-rw-r--r--pkg_resources.py56
-rw-r--r--release.py75
-rwxr-xr-xsetup.py32
-rw-r--r--setuptools/cli-32.exebin69632 -> 65536 bytes
-rw-r--r--setuptools/cli-64.exebin75264 -> 74752 bytes
-rw-r--r--setuptools/cli-arm-32.exebin0 -> 69120 bytes
-rw-r--r--setuptools/cli.exebin69632 -> 0 bytes
-rwxr-xr-xsetuptools/command/easy_install.py23
-rw-r--r--setuptools/command/launcher manifest.xml15
-rw-r--r--setuptools/gui-32.exebin65536 -> 65536 bytes
-rw-r--r--setuptools/gui-64.exebin75264 -> 75264 bytes
-rw-r--r--setuptools/gui-arm-32.exebin0 -> 69120 bytes
-rw-r--r--setuptools/gui.exebin65536 -> 0 bytes
-rw-r--r--setuptools/tests/win_script_wrapper.txt6
-rw-r--r--tests/test_pkg_resources.py61
24 files changed, 319 insertions, 63 deletions
diff --git a/.hgignore b/.hgignore
index 21ec620a..4e5d0bcf 100644
--- a/.hgignore
+++ b/.hgignore
@@ -11,3 +11,4 @@ bin
include
\.Python
*.swp
+CHANGES (links).txt
diff --git a/.hgtags b/.hgtags
index 5f3ee48d..b433c91f 100644
--- a/.hgtags
+++ b/.hgtags
@@ -44,3 +44,8 @@ b1a7f86b315a1f8c20036d718d6dc641bb84cac6 0.6.32
6acac3919ae9a7dba2cbecbe3d4b31ece25d5f09 0.6.33
23c310bf4ae8e4616e37027f08891702f5a33bc9 0.6.34
2abe1117543be0edbafb10c7c159d1bcb1cb1b87 0.6.35
+c813a29e831f266d427d4a4bce3da97f475a8eee 0.6.36
+be6f65eea9c10ce78b6698d8c220b6e5de577292 0.6.37
+2b26ec8909bff210f47c5f8fc620bc505e1610b5 0.6.37
+f0d502a83f6c83ba38ad21c15a849c2daf389ec7 0.6.38
+d737b2039c5f92af8000f78bbc80b6a5183caa97 0.6.39
diff --git a/CHANGES.txt b/CHANGES.txt
index cae946e0..6053c703 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -3,6 +3,45 @@ CHANGES
=======
------
+0.6.39
+------
+
+* Add support for console launchers on ARM platforms.
+* Fix possible issue in GUI launchers where the subsystem was not supplied to
+ the linker.
+* Launcher build script now refactored for robustness.
+* Issue #375: Resources extracted from a zip egg to the file system now also
+ check the contents of the file against the zip contents during each
+ invocation of get_resource_filename.
+
+------
+0.6.38
+------
+
+* Issue #371: The launcher manifest file is now installed properly.
+
+------
+0.6.37
+------
+
+* Issue #143: Launcher scripts, including easy_install itself, are now
+ accompanied by a manifest on 32-bit Windows environments to avoid the
+ Installer Detection Technology and thus undesirable UAC elevation described
+ in `this Microsoft article
+ <http://technet.microsoft.com/en-us/library/cc709628%28WS.10%29.aspx>`_.
+
+------
+0.6.36
+------
+
+* Pull Request #35: In `Buildout issue 64
+ <https://github.com/buildout/buildout/issues/64>`_, it was reported that
+ under Python 3, installation of distutils scripts could attempt to copy
+ the ``__pycache__`` directory as a file, causing an error, apparently only
+ under Windows. Easy_install now skips all directories when processing
+ metadata scripts.
+
+------
0.6.35
------
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index a5f050cd..d35d9e11 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -8,6 +8,7 @@ Contributors
* Christophe Combelles
* Daniel Stutzbach
* Daniel Holth
+* Grigory Petrov
* Hanno Schlichting
* Jannis Leidel
* Jason R. Coombs
diff --git a/MANIFEST.in b/MANIFEST.in
index 9837747a..68337800 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,4 @@
-recursive-include setuptools *.py *.txt *.exe
+recursive-include setuptools *.py *.txt *.exe *.xml
recursive-include tests *.py *.c *.pyx *.txt
recursive-include setuptools/tests *.html
recursive-include docs *.py *.txt *.conf *.css *.css_t Makefile indexsidebar.html
diff --git a/docs/conf.py b/docs/conf.py
index 4f878f64..9a60cfe1 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -48,9 +48,9 @@ copyright = u'2009-2013, The fellowship of the packaging'
# built documents.
#
# The short X.Y version.
-version = '0.6.36'
+version = '0.6.40'
# The full version, including alpha/beta/rc tags.
-release = '0.6.36'
+release = '0.6.40'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/ez_setup.py b/ez_setup.py
index d311a0b9..57f019b1 100644
--- a/ez_setup.py
+++ b/ez_setup.py
@@ -47,7 +47,7 @@ except ImportError:
args = [quote(arg) for arg in args]
return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
-DEFAULT_VERSION = "0.6.36"
+DEFAULT_VERSION = "0.6.40"
DEFAULT_URL = "http://pypi.python.org/packages/source/s/setuptools/"
diff --git a/launcher.c b/launcher.c
index ea4c80b5..be69f0c6 100755
--- a/launcher.c
+++ b/launcher.c
@@ -14,6 +14,14 @@
gcc -DGUI=0 -mno-cygwin -O -s -o setuptools/cli.exe launcher.c
gcc -DGUI=1 -mwindows -mno-cygwin -O -s -o setuptools/gui.exe launcher.c
+ To build for Windows RT, install both Visual Studio Express for Windows 8
+ and for Windows Desktop (both freeware), create "win32" application using
+ "Windows Desktop" version, create new "ARM" target via
+ "Configuration Manager" menu and modify ".vcxproj" file by adding
+ "<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>" tag
+ as child of "PropertyGroup" tags that has "Debug|ARM" and "Release|ARM"
+ properties.
+
It links to msvcrt.dll, but this shouldn't be a problem since it doesn't
actually run Python in the same process. Note that using 'exec' instead
of 'spawn' doesn't work, because on Windows this leads to the Python
diff --git a/msvc-build-launcher.cmd b/msvc-build-launcher.cmd
index 3666d723..07c474d4 100644
--- a/msvc-build-launcher.cmd
+++ b/msvc-build-launcher.cmd
@@ -1,15 +1,49 @@
@echo off
-REM VCVARSALL may be in Program Files or Program Files (x86)
-PATH=C:\Program Files\Microsoft Visual Studio 9.0\VC;%PATH%
-PATH=C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC;%PATH%
+REM Use old Windows SDK 6.1 so created .exe will be compatible with
+REM old Windows versions.
+REM Windows SDK 6.1 may be downloaded at:
+REM http://www.microsoft.com/en-us/download/details.aspx?id=11310
+set PATH_OLD=%PATH%
+
+REM The SDK creates a false install of Visual Studio at one of these locations
+set PATH=C:\Program Files\Microsoft Visual Studio 9.0\VC\bin;%PATH%
+set PATH=C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin;%PATH%
REM set up the environment to compile to x86
-call VCVARSALL x86
-cl /D "GUI=0" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x86 /out:setuptools/cli-32.exe
-cl /D "GUI=1" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x86 /out:setuptools/gui-32.exe
+call VCVARS32
+if "%ERRORLEVEL%"=="0" (
+ cl /D "GUI=0" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x86 /SUBSYSTEM:CONSOLE /out:setuptools/cli-32.exe
+ cl /D "GUI=1" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x86 /SUBSYSTEM:WINDOWS /out:setuptools/gui-32.exe
+) else (
+ echo Windows SDK 6.1 not found to build Windows 32-bit version
+)
REM now for 64-bit
-call VCVARSALL x86_amd64
-cl /D "GUI=0" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x64 /out:setuptools/cli-64.exe
-cl /D "GUI=1" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x64 /out:setuptools/gui-64.exe \ No newline at end of file
+REM Use the x86_amd64 profile, which is the 32-bit cross compiler for amd64
+call VCVARSx86_amd64
+if "%ERRORLEVEL%"=="0" (
+ cl /D "GUI=0" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x64 /SUBSYSTEM:CONSOLE /out:setuptools/cli-64.exe
+ cl /D "GUI=1" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x64 /SUBSYSTEM:WINDOWS /out:setuptools/gui-64.exe
+) else (
+ echo Windows SDK 6.1 not found to build Windows 64-bit version
+)
+
+REM Windows RT ARM build requires both freeware
+REM "Visual Studio Express 2012 for Windows 8" and
+REM "Visual Studio Express 2012 for Windows Desktop" to be installed from
+REM http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products
+set PATH=%PATH_OLD%
+set PATH=C:\Program Files\Microsoft Visual Studio 11.0\VC;%PATH%
+set PATH=C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC;%PATH%
+call VCVARSALL x86_arm >nul 2>&1
+if "%ERRORLEVEL%"=="0" (
+ echo Building Windows RT Version ...
+ cl /D "GUI=0" /D "WIN32_LEAN_AND_MEAN" /D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE launcher.c /O2 /link /MACHINE:ARM /SUBSYSTEM:CONSOLE /out:setuptools/cli-arm-32.exe
+ cl /D "GUI=1" /D "WIN32_LEAN_AND_MEAN" /D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE launcher.c /O2 /link /MACHINE:ARM /SUBSYSTEM:WINDOWS /out:setuptools/gui-arm-32.exe
+) else (
+ echo Visual Studio ^(Express^) 2012 not found to build Windows RT Version
+)
+
+set PATH=%PATH_OLD%
+
diff --git a/pkg_resources.py b/pkg_resources.py
index 2ba0febf..03f750d7 100644
--- a/pkg_resources.py
+++ b/pkg_resources.py
@@ -1384,6 +1384,16 @@ class ZipProvider(EggProvider):
self._extract_resource(manager, self._eager_to_zip(name))
return self._extract_resource(manager, zip_path)
+ @staticmethod
+ def _get_date_and_size(zip_stat):
+ t,d,size = zip_stat[5], zip_stat[6], zip_stat[3]
+ date_time = (
+ (d>>9)+1980, (d>>5)&0xF, d&0x1F, # ymd
+ (t&0xFFFF)>>11, (t>>5)&0x3F, (t&0x1F) * 2, 0, 0, -1 # hms, etc.
+ )
+ timestamp = time.mktime(date_time)
+ return timestamp, size
+
def _extract_resource(self, manager, zip_path):
if zip_path in self._index():
@@ -1393,28 +1403,19 @@ class ZipProvider(EggProvider):
)
return os.path.dirname(last) # return the extracted directory name
- zip_stat = self.zipinfo[zip_path]
- t,d,size = zip_stat[5], zip_stat[6], zip_stat[3]
- date_time = (
- (d>>9)+1980, (d>>5)&0xF, d&0x1F, # ymd
- (t&0xFFFF)>>11, (t>>5)&0x3F, (t&0x1F) * 2, 0, 0, -1 # hms, etc.
- )
- timestamp = time.mktime(date_time)
+ timestamp, size = self._get_date_and_size(self.zipinfo[zip_path])
+ if not WRITE_SUPPORT:
+ raise IOError('"os.rename" and "os.unlink" are not supported '
+ 'on this platform')
try:
- if not WRITE_SUPPORT:
- raise IOError('"os.rename" and "os.unlink" are not supported '
- 'on this platform')
real_path = manager.get_cache_path(
self.egg_name, self._parts(zip_path)
)
- if os.path.isfile(real_path):
- stat = os.stat(real_path)
- if stat.st_size==size and stat.st_mtime==timestamp:
- # size and stamp match, don't bother extracting
- return real_path
+ if self._is_current(real_path, zip_path):
+ return real_path
outf, tmpnam = _mkstemp(".$extract", dir=os.path.dirname(real_path))
os.write(outf, self.loader.get_data(zip_path))
@@ -1427,11 +1428,9 @@ class ZipProvider(EggProvider):
except os.error:
if os.path.isfile(real_path):
- stat = os.stat(real_path)
-
- if stat.st_size==size and stat.st_mtime==timestamp:
- # size and stamp match, somebody did it just ahead of
- # us, so we're done
+ if self._is_current(real_path, zip_path):
+ # the file became current since it was checked above,
+ # so proceed.
return real_path
elif os.name=='nt': # Windows, del old file and retry
unlink(real_path)
@@ -1444,6 +1443,23 @@ class ZipProvider(EggProvider):
return real_path
+ def _is_current(self, file_path, zip_path):
+ """
+ Return True if the file_path is current for this zip_path
+ """
+ timestamp, size = self._get_date_and_size(self.zipinfo[zip_path])
+ if not os.path.isfile(file_path):
+ return False
+ stat = os.stat(file_path)
+ if stat.st_size!=size or stat.st_mtime!=timestamp:
+ return False
+ # check that the contents match
+ zip_contents = self.loader.get_data(zip_path)
+ f = open(file_path, 'rb')
+ file_contents = f.read()
+ f.close()
+ return zip_contents == file_contents
+
def _get_eager_resources(self):
if self.eagers is None:
eagers = []
diff --git a/release.py b/release.py
index 46720a8e..2dc51ae8 100644
--- a/release.py
+++ b/release.py
@@ -14,13 +14,17 @@ import sys
import urllib2
import getpass
import collections
+import itertools
+import re
try:
import keyring
except Exception:
pass
-VERSION = '0.6.36'
+VERSION = '0.6.40'
+PACKAGE_INDEX = 'https://pypi.python.org/pypi'
+PACKAGE_INDEX = 'https://pypi.python.org/pypi'
def get_next_version():
digits = map(int, VERSION.split('.'))
@@ -50,7 +54,7 @@ def get_mercurial_creds(system='https://bitbucket.org', username=None):
# todo: consider getting this from .hgrc
username = username or getpass.getuser()
keyring_username = '@@'.join((username, system))
- system = '@'.join((keyring_username, 'Mercurial'))
+ system = 'Mercurial'
password = (
keyring.get_password(system, keyring_username)
if 'keyring' in globals()
@@ -110,13 +114,20 @@ def do_release():
subprocess.check_call(['hg', 'update', VERSION])
+ linkify('CHANGES.txt', 'CHANGES (links).txt')
+
has_docs = build_docs()
if os.path.isdir('./dist'):
shutil.rmtree('./dist')
- cmd = [sys.executable, 'setup.py', '-q', 'egg_info', '-RD', '-b', '',
- 'sdist', 'register', 'upload']
+ cmd = [
+ sys.executable, 'setup.py', '-q',
+ 'egg_info', '-RD', '-b', '',
+ 'sdist',
+ 'register', '-r', PACKAGE_INDEX,
+ 'upload', '-r', PACKAGE_INDEX,
+ ]
if has_docs:
- cmd.append('upload_docs')
+ cmd.extend(['upload_docs', '-r', PACKAGE_INDEX])
subprocess.check_call(cmd)
upload_bootstrap_script()
@@ -166,5 +177,59 @@ def upload_bootstrap_script():
except:
print("Unable to upload bootstrap script. Ask Tarek to do it.")
+def linkify(source, dest):
+ with open(source) as source:
+ out = _linkified_text(source.read())
+ with open(dest, 'w') as dest:
+ dest.write(out)
+
+def _linkified(rst_path):
+ "return contents of reStructureText file with linked issue references"
+ rst_file = open(rst_path)
+ rst_content = rst_file.read()
+ rst_file.close()
+
+ return _linkified_text(rst_content)
+
+def _linkified_text(rst_content):
+ # first identify any existing HREFs so they're not changed
+ HREF_pattern = re.compile('`.*?`_', re.MULTILINE | re.DOTALL)
+
+ # split on the HREF pattern, returning the parts to be linkified
+ plain_text_parts = HREF_pattern.split(rst_content)
+ anchors = []
+ linkified_parts = [_linkified_part(part, anchors)
+ for part in plain_text_parts]
+ pairs = itertools.izip_longest(
+ linkified_parts,
+ HREF_pattern.findall(rst_content),
+ fillvalue='',
+ )
+ rst_content = ''.join(flatten(pairs))
+
+ anchors = sorted(anchors)
+
+ bitroot = 'http://bitbucket.org/tarek/distribute'
+ rst_content += "\n"
+ for x in anchors:
+ issue = re.findall(r'\d+', x)[0]
+ rst_content += '.. _`%s`: %s/issue/%s\n' % (x, bitroot, issue)
+ rst_content += "\n"
+ return rst_content
+
+def flatten(listOfLists):
+ "Flatten one level of nesting"
+ return itertools.chain.from_iterable(listOfLists)
+
+
+def _linkified_part(text, anchors):
+ """
+ Linkify a part and collect any anchors generated
+ """
+ revision = re.compile(r'\b(issue\s+#?\d+)\b', re.M | re.I)
+
+ anchors.extend(revision.findall(text)) # ['Issue #43', ...]
+ return revision.sub(r'`\1`_', text)
+
if __name__ == '__main__':
do_release()
diff --git a/setup.py b/setup.py
index 6cd15f25..dd31f13a 100755
--- a/setup.py
+++ b/setup.py
@@ -46,7 +46,7 @@ exec(init_file.read(), d)
init_file.close()
SETUP_COMMANDS = d['__all__']
-VERSION = "0.6.36"
+VERSION = "0.6.40"
from setuptools import setup, find_packages
from setuptools.command.build_py import build_py as _build_py
@@ -107,28 +107,16 @@ class test(_test):
f.close()
-# return contents of reStructureText file with linked issue references
-def _linkified(rst_path):
- bitroot = 'http://bitbucket.org/tarek/distribute'
- revision = re.compile(r'\b(issue\s+#?\d+)\b', re.M | re.I)
-
- rst_file = open(rst_path)
- rst_content = rst_file.read()
- rst_file.close()
-
- anchors = revision.findall(rst_content) # ['Issue #43', ...]
- anchors = sorted(set(anchors))
- rst_content = revision.sub(r'`\1`_', rst_content)
- rst_content += "\n"
- for x in anchors:
- issue = re.findall(r'\d+', x)[0]
- rst_content += '.. _`%s`: %s/issue/%s\n' % (x, bitroot, issue)
- rst_content += "\n"
- return rst_content
-
readme_file = open('README.txt')
-long_description = readme_file.read() + _linkified('CHANGES.txt')
+# the release script adds hyperlinks to issues
+if os.path.exists('CHANGES (links).txt'):
+ changes_file = open('CHANGES (links).txt')
+else:
+ # but if the release script has not run, fall back to the source file
+ changes_file = open('CHANGES.txt')
+long_description = readme_file.read() + changes_file.read()
readme_file.close()
+changes_file.close()
dist = setup(
name="setuptools",
@@ -144,7 +132,7 @@ dist = setup(
test_suite = 'setuptools.tests',
src_root = src_root,
packages = find_packages(),
- package_data = {'setuptools':['*.exe']},
+ package_data = {'setuptools':['*.exe'], 'setuptools.command':['*.xml']},
py_modules = ['pkg_resources', 'easy_install', 'site'],
diff --git a/setuptools/cli-32.exe b/setuptools/cli-32.exe
index 9b7717b7..b1487b78 100644
--- a/setuptools/cli-32.exe
+++ b/setuptools/cli-32.exe
Binary files differ
diff --git a/setuptools/cli-64.exe b/setuptools/cli-64.exe
index 265585af..675e6bf3 100644
--- a/setuptools/cli-64.exe
+++ b/setuptools/cli-64.exe
Binary files differ
diff --git a/setuptools/cli-arm-32.exe b/setuptools/cli-arm-32.exe
new file mode 100644
index 00000000..2f40402d
--- /dev/null
+++ b/setuptools/cli-arm-32.exe
Binary files differ
diff --git a/setuptools/cli.exe b/setuptools/cli.exe
deleted file mode 100644
index 9b7717b7..00000000
--- a/setuptools/cli.exe
+++ /dev/null
Binary files differ
diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py
index a2d2ed6a..4cd058bb 100755
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -19,7 +19,9 @@ import zipfile
import re
import stat
import random
+import platform
from glob import glob
+import pkg_resources
from setuptools import Command, _dont_write_bytecode
from setuptools.sandbox import run_setup
from distutils import log, dir_util
@@ -522,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)
@@ -1833,6 +1839,8 @@ 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:
@@ -1846,11 +1854,26 @@ def get_script_args(dist, executable=sys_executable, wininst=False):
name+'.exe', resource_string('setuptools', launcher),
'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)
+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.
diff --git a/setuptools/command/launcher manifest.xml b/setuptools/command/launcher manifest.xml
new file mode 100644
index 00000000..844d2264
--- /dev/null
+++ b/setuptools/command/launcher manifest.xml
@@ -0,0 +1,15 @@
+<?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="%(name)s"
+ 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>
diff --git a/setuptools/gui-32.exe b/setuptools/gui-32.exe
index 3f64af7d..f8d35096 100644
--- a/setuptools/gui-32.exe
+++ b/setuptools/gui-32.exe
Binary files differ
diff --git a/setuptools/gui-64.exe b/setuptools/gui-64.exe
index 3ab4378e..330c51a5 100644
--- a/setuptools/gui-64.exe
+++ b/setuptools/gui-64.exe
Binary files differ
diff --git a/setuptools/gui-arm-32.exe b/setuptools/gui-arm-32.exe
new file mode 100644
index 00000000..537aff37
--- /dev/null
+++ b/setuptools/gui-arm-32.exe
Binary files differ
diff --git a/setuptools/gui.exe b/setuptools/gui.exe
deleted file mode 100644
index 3f64af7d..00000000
--- a/setuptools/gui.exe
+++ /dev/null
Binary files differ
diff --git a/setuptools/tests/win_script_wrapper.txt b/setuptools/tests/win_script_wrapper.txt
index 9f7c81d6..9ccc96f0 100644
--- a/setuptools/tests/win_script_wrapper.txt
+++ b/setuptools/tests/win_script_wrapper.txt
@@ -38,7 +38,7 @@ We'll also copy cli.exe to the sample-directory with the name foo.exe:
>>> import pkg_resources
>>> f = open(os.path.join(sample_directory, 'foo.exe'), 'wb')
>>> f.write(
- ... pkg_resources.resource_string('setuptools', 'cli.exe')
+ ... pkg_resources.resource_string('setuptools', 'cli-32.exe')
... )
>>> f.close()
@@ -83,7 +83,7 @@ enter the interpreter after running the script, you could use -Oi:
>>> f = open(os.path.join(sample_directory, 'foo-script.py'), 'w')
>>> f.write(
- ... """#!%(python_exe)s -Oi
+ ... """#!%(python_exe)s -Oi
... import sys
... input = repr(sys.stdin.read())
... print sys.argv[0][-14:]
@@ -126,7 +126,7 @@ We'll also copy gui.exe to the sample-directory with the name bar.exe:
>>> import pkg_resources
>>> f = open(os.path.join(sample_directory, 'bar.exe'), 'wb')
>>> f.write(
- ... pkg_resources.resource_string('setuptools', 'gui.exe')
+ ... pkg_resources.resource_string('setuptools', 'gui-32.exe')
... )
>>> f.close()
diff --git a/tests/test_pkg_resources.py b/tests/test_pkg_resources.py
new file mode 100644
index 00000000..7009b4ab
--- /dev/null
+++ b/tests/test_pkg_resources.py
@@ -0,0 +1,61 @@
+import sys
+import tempfile
+import os
+import zipfile
+
+import pkg_resources
+
+class EggRemover(unicode):
+ def __call__(self):
+ if self in sys.path:
+ sys.path.remove(self)
+ if os.path.exists(self):
+ os.remove(self)
+
+class TestZipProvider(object):
+ finalizers = []
+
+ @classmethod
+ def setup_class(cls):
+ "create a zip egg and add it to sys.path"
+ egg = tempfile.NamedTemporaryFile(suffix='.egg', delete=False)
+ zip_egg = zipfile.ZipFile(egg, 'w')
+ zip_info = zipfile.ZipInfo()
+ zip_info.filename = 'mod.py'
+ zip_info.date_time = 2013, 5, 12, 13, 25, 0
+ zip_egg.writestr(zip_info, 'x = 3\n')
+ zip_info = zipfile.ZipInfo()
+ zip_info.filename = 'data.dat'
+ zip_info.date_time = 2013, 5, 12, 13, 25, 0
+ zip_egg.writestr(zip_info, 'hello, world!')
+ zip_egg.close()
+ egg.close()
+
+ sys.path.append(egg.name)
+ cls.finalizers.append(EggRemover(egg.name))
+
+ @classmethod
+ def teardown_class(cls):
+ for finalizer in cls.finalizers:
+ finalizer()
+
+ def test_resource_filename_rewrites_on_change(self):
+ """
+ If a previous call to get_resource_filename has saved the file, but
+ the file has been subsequently mutated with different file of the
+ same size and modification time, it should not be overwritten on a
+ subsequent call to get_resource_filename.
+ """
+ import mod
+ manager = pkg_resources.ResourceManager()
+ zp = pkg_resources.ZipProvider(mod)
+ filename = zp.get_resource_filename(manager, 'data.dat')
+ assert os.stat(filename).st_mtime == 1368379500
+ f = open(filename, 'wb')
+ f.write('hello, world?')
+ f.close()
+ os.utime(filename, (1368379500, 1368379500))
+ filename = zp.get_resource_filename(manager, 'data.dat')
+ f = open(filename)
+ assert f.read() == 'hello, world!'
+ manager.cleanup_resources()