Hello community, here is the log from the commit of package python3-wheel for openSUSE:Factory checked in at 2016-02-18 11:04:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python3-wheel (Old) and /work/SRC/openSUSE:Factory/.python3-wheel.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python3-wheel" Changes: -------- --- /work/SRC/openSUSE:Factory/python3-wheel/python3-wheel.changes 2015-09-27 08:39:58.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python3-wheel.new/python3-wheel.changes 2016-02-18 12:35:18.000000000 +0100 @@ -1,0 +2,35 @@ +Sat Feb 6 18:53:35 UTC 2016 - a...@gmx.de + +- update to version 0.29.0: + * Fix compression type of files in archive (Issue #155, Pull Request + #62, thanks Xavier Fernandez) + +------------------------------------------------------------------- +Sat Feb 6 04:09:13 UTC 2016 - a...@gmx.de + +- specfile: + * update copyright year + +- update to version 0.28.0: + * Fix file modes in archive (Issue #154) + +- changes from version 0.27.0: + * Support forcing a platform tag using `--plat-name` on pure-Python + wheels, as well as nonstandard platform tags on non-pure wheels + (Pull Request #60, Issue #144, thanks Andrés Díaz) + * Add SOABI tags to platform-specific wheels built for Python 2.X + (Pull Request #55, Issue #63, Issue #101) + * Support reproducible wheel files, wheels that can be rebuilt and + will hash to the same values as previous builds (Pull Request #52, + Issue #143, thanks Barry Warsaw) + * Support for changes in keyring >= 8.0 (Pull Request #61, thanks + Jason R. Coombs) + * Use the file context manager when checking if dependency_links.txt + is empty, fixes problems building wheels under PyPy on Windows + (Issue #150, thanks Cosimo Lupo) + * Don't attempt to (recursively) create a build directory ending + with `..` (invalid on all platforms, but code was only executed on + Windows) (Issue #91) + * Added the PyPA Code of Conduct (Pull Request #56) + +------------------------------------------------------------------- Old: ---- wheel-0.26.0.tar.gz New: ---- wheel-0.29.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python3-wheel.spec ++++++ --- /var/tmp/diff_new_pack.qH2RgJ/_old 2016-02-18 12:35:19.000000000 +0100 +++ /var/tmp/diff_new_pack.qH2RgJ/_new 2016-02-18 12:35:19.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package python3-wheel # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: python3-wheel -Version: 0.26.0 +Version: 0.29.0 Release: 0 Summary: A built-package format for Python License: MIT ++++++ wheel-0.26.0.tar.gz -> wheel-0.29.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/CHANGES.txt new/wheel-0.29.0/CHANGES.txt --- old/wheel-0.26.0/CHANGES.txt 2015-09-18 20:02:17.000000000 +0200 +++ new/wheel-0.29.0/CHANGES.txt 2016-02-06 18:15:18.000000000 +0100 @@ -1,3 +1,31 @@ +0.29.0 +====== +- Fix compression type of files in archive (Issue #155, Pull Request #62, + thanks Xavier Fernandez) + +0.28.0 +====== +- Fix file modes in archive (Issue #154) + +0.27.0 +====== +- Support forcing a platform tag using `--plat-name` on pure-Python wheels, as + well as nonstandard platform tags on non-pure wheels (Pull Request #60, Issue + #144, thanks Andrés Díaz) +- Add SOABI tags to platform-specific wheels built for Python 2.X (Pull Request + #55, Issue #63, Issue #101) +- Support reproducible wheel files, wheels that can be rebuilt and will hash to + the same values as previous builds (Pull Request #52, Issue #143, thanks + Barry Warsaw) +- Support for changes in keyring >= 8.0 (Pull Request #61, thanks Jason R. + Coombs) +- Use the file context manager when checking if dependency_links.txt is empty, + fixes problems building wheels under PyPy on Windows (Issue #150, thanks + Cosimo Lupo) +- Don't attempt to (recursively) create a build directory ending with `..` + (invalid on all platforms, but code was only executed on Windows) (Issue #91) +- Added the PyPA Code of Conduct (Pull Request #56) + 0.26.0 ====== - Fix multiple entrypoint comparison failure on Python 3 (Issue #148) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/PKG-INFO new/wheel-0.29.0/PKG-INFO --- old/wheel-0.26.0/PKG-INFO 2015-09-18 20:03:13.000000000 +0200 +++ new/wheel-0.29.0/PKG-INFO 2016-02-06 18:21:03.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: wheel -Version: 0.26.0 +Version: 0.29.0 Summary: A built-package format for Python. Home-page: https://bitbucket.org/pypa/wheel/ Author: Daniel Holth @@ -48,6 +48,43 @@ reference implementation. + Code of Conduct + --------------- + + Everyone interacting in the wheel project's codebases, issue trackers, chat + rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. + + .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + + + + 0.29.0 + ====== + - Fix compression type of files in archive (Issue #155, Pull Request #62, + thanks Xavier Fernandez) + + 0.28.0 + ====== + - Fix file modes in archive (Issue #154) + + 0.27.0 + ====== + - Support forcing a platform tag using `--plat-name` on pure-Python wheels, as + well as nonstandard platform tags on non-pure wheels (Pull Request #60, Issue + #144, thanks Andrés Díaz) + - Add SOABI tags to platform-specific wheels built for Python 2.X (Pull Request + #55, Issue #63, Issue #101) + - Support reproducible wheel files, wheels that can be rebuilt and will hash to + the same values as previous builds (Pull Request #52, Issue #143, thanks + Barry Warsaw) + - Support for changes in keyring >= 8.0 (Pull Request #61, thanks Jason R. + Coombs) + - Use the file context manager when checking if dependency_links.txt is empty, + fixes problems building wheels under PyPy on Windows (Issue #150, thanks + Cosimo Lupo) + - Don't attempt to (recursively) create a build directory ending with `..` + (invalid on all platforms, but code was only executed on Windows) (Issue #91) + - Added the PyPA Code of Conduct (Pull Request #56) 0.26.0 ====== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/README.txt new/wheel-0.29.0/README.txt --- old/wheel-0.26.0/README.txt 2015-09-15 19:28:15.000000000 +0200 +++ new/wheel-0.29.0/README.txt 2016-02-05 21:42:39.000000000 +0100 @@ -39,3 +39,12 @@ level that is truly easy to install even if you do not want to use the reference implementation. + +Code of Conduct +--------------- + +Everyone interacting in the wheel project's codebases, issue trackers, chat +rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. + +.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/setup.py new/wheel-0.29.0/setup.py --- old/wheel-0.26.0/setup.py 2015-09-15 19:28:15.000000000 +0200 +++ new/wheel-0.29.0/setup.py 2016-02-05 21:42:39.000000000 +0100 @@ -39,8 +39,9 @@ ], extras_require={ ':python_version=="2.6"': ['argparse'], - 'signatures': ['keyring'], + 'signatures': ['keyring', 'keyrings.alt'], 'signatures:sys_platform!="win32"': ['pyxdg'], + 'signatures:python_version=="2.6"': ['importlib'], 'faster-signatures': ['ed25519ll'], 'tool': [] }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel/__init__.py new/wheel-0.29.0/wheel/__init__.py --- old/wheel-0.26.0/wheel/__init__.py 2015-09-18 20:03:01.000000000 +0200 +++ new/wheel-0.29.0/wheel/__init__.py 2016-02-06 18:19:00.000000000 +0100 @@ -1,2 +1,2 @@ # __variables__ with double-quoted values will be available in setup.py: -__version__ = "0.26.0" +__version__ = "0.29.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel/archive.py new/wheel-0.29.0/wheel/archive.py --- old/wheel-0.26.0/wheel/archive.py 2015-09-15 19:28:15.000000000 +0200 +++ new/wheel-0.29.0/wheel/archive.py 2016-02-06 18:14:11.000000000 +0100 @@ -2,6 +2,8 @@ Archive tools for wheel. """ +import os +import time import logging import os.path import zipfile @@ -31,6 +33,15 @@ log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir) + # Some applications need reproducible .whl files, but they can't do this + # without forcing the timestamp of the individual ZipInfo objects. See + # issue #143. + timestamp = os.environ.get('SOURCE_DATE_EPOCH') + if timestamp is None: + date_time = None + else: + date_time = time.gmtime(int(timestamp))[0:6] + # XXX support bz2, xz when available zip = zipfile.ZipFile(open(zip_filename, "wb+"), "w", compression=zipfile.ZIP_DEFLATED) @@ -38,8 +49,16 @@ score = {'WHEEL': 1, 'METADATA': 2, 'RECORD': 3} deferred = [] - def writefile(path): - zip.write(path, path) + def writefile(path, date_time): + st = os.stat(path) + if date_time is None: + mtime = time.gmtime(st.st_mtime) + date_time = mtime[0:6] + zinfo = zipfile.ZipInfo(path, date_time) + zinfo.external_attr = st.st_mode << 16 + zinfo.compress_type = zipfile.ZIP_DEFLATED + with open(path, 'rb') as fp: + zip.writestr(zinfo, fp.read()) log.info("adding '%s'" % path) for dirpath, dirnames, filenames in os.walk(base_dir): @@ -50,11 +69,11 @@ if dirpath.endswith('.dist-info'): deferred.append((score.get(name, 0), path)) else: - writefile(path) + writefile(path, date_time) deferred.sort() for score, path in deferred: - writefile(path) + writefile(path, date_time) zip.close() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel/bdist_wheel.py new/wheel-0.29.0/wheel/bdist_wheel.py --- old/wheel-0.26.0/wheel/bdist_wheel.py 2015-09-15 20:10:36.000000000 +0200 +++ new/wheel-0.29.0/wheel/bdist_wheel.py 2016-02-05 21:42:39.000000000 +0100 @@ -33,7 +33,7 @@ from distutils import log as logger -from .pep425tags import get_abbr_impl, get_impl_ver +from .pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag from .util import native, open_for_csv from .archive import archive_wheelfile from .pkginfo import read_pkg_info, write_pkg_info @@ -85,6 +85,7 @@ self.bdist_dir = None self.data_dir = None self.plat_name = None + self.plat_tag = None self.format = 'zip' self.keep_temp = False self.dist_dir = None @@ -97,6 +98,7 @@ self.group = None self.universal = False self.python_tag = 'py' + get_impl_ver()[0] + self.plat_name_supplied = False def finalize_options(self): if self.bdist_dir is None: @@ -104,6 +106,7 @@ self.bdist_dir = os.path.join(bdist_base, 'wheel') self.data_dir = self.wheel_dist_name + '.data' + self.plat_name_supplied = self.plat_name is not None need_options = ('dist_dir', 'plat_name', 'skip_build') @@ -128,30 +131,30 @@ safer_version(self.distribution.get_version()))) def get_tag(self): - supported_tags = pep425tags.get_supported() + # bdist sets self.plat_name if unset, we should only use it for purepy + # wheels if the user supplied it. + if self.plat_name_supplied: + plat_name = self.plat_name + elif self.root_is_pure: + plat_name = 'any' + else: + plat_name = self.plat_name or get_platform() + plat_name = plat_name.replace('-', '_').replace('.', '_') if self.root_is_pure: if self.universal: impl = 'py2.py3' else: impl = self.python_tag - tag = (impl, 'none', 'any') + tag = (impl, 'none', plat_name) else: - plat_name = self.plat_name - if plat_name is None: - plat_name = get_platform() - plat_name = plat_name.replace('-', '_').replace('.', '_') impl_name = get_abbr_impl() impl_ver = get_impl_ver() - # PEP 3149 -- no SOABI in Py 2 - # For PyPy? - # "pp%s%s" % (sys.pypy_version_info.major, - # sys.pypy_version_info.minor) - abi_tag = sysconfig.get_config_vars().get('SOABI', 'none') - if abi_tag.startswith('cpython-'): - abi_tag = 'cp' + abi_tag.split('-')[1] - + # PEP 3149 + abi_tag = str(get_abi_tag()).lower() tag = (impl_name + impl_ver, abi_tag, plat_name) + supported_tags = pep425tags.get_supported( + supplied_platform=plat_name if self.plat_name_supplied else None) # XXX switch to this alternate implementation for non-pure: assert tag == supported_tags[0] return tag @@ -200,7 +203,7 @@ if os.name == 'nt': # win32 barfs if any of these are ''; could be '.'? # (distutils.command.install:change_roots bug) - basedir_observed = os.path.join(self.data_dir, '..') + basedir_observed = os.path.normpath(os.path.join(self.data_dir, '..')) self.install_libbase = self.install_lib = basedir_observed setattr(install, @@ -378,9 +381,11 @@ 'not-zip-safe',))) # delete dependency_links if it is only whitespace - dependency_links = os.path.join(distinfo_path, 'dependency_links.txt') - if not open(dependency_links, 'r').read().strip(): - adios(dependency_links) + dependency_links_path = os.path.join(distinfo_path, 'dependency_links.txt') + with open(dependency_links_path, 'r') as dependency_links_file: + dependency_links = dependency_links_file.read().strip() + if not dependency_links: + adios(dependency_links_path) write_pkg_info(os.path.join(distinfo_path, 'METADATA'), pkg_info) @@ -410,7 +415,7 @@ pymeta['extensions']['python.details']['document_names']['license'] = license_filename with open(metadata_json_path, "w") as metadata_json: - json.dump(pymeta, metadata_json) + json.dump(pymeta, metadata_json, sort_keys=True) adios(egginfo_path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel/metadata.py new/wheel-0.29.0/wheel/metadata.py --- old/wheel-0.26.0/wheel/metadata.py 2015-09-18 19:56:57.000000000 +0200 +++ new/wheel-0.29.0/wheel/metadata.py 2016-02-05 21:42:39.000000000 +0100 @@ -74,7 +74,14 @@ if may_requires: metadata['run_requires'] = [] - for key, value in may_requires.items(): + def sort_key(item): + # Both condition and extra could be None, which can't be compared + # against strings in Python 3. + key, value = item + if key.condition is None: + return '' + return key.condition + for key, value in sorted(may_requires.items(), key=sort_key): may_requirement = OrderedDict((('requires', value),)) if key.extra: may_requirement['extra'] = key.extra diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel/pep425tags.py new/wheel-0.29.0/wheel/pep425tags.py --- old/wheel-0.26.0/wheel/pep425tags.py 2015-09-15 20:10:36.000000000 +0200 +++ new/wheel-0.29.0/wheel/pep425tags.py 2016-02-05 21:42:39.000000000 +0100 @@ -1,6 +1,7 @@ """Generate and work with PEP 425 Compatibility Tags.""" import sys +import warnings try: import sysconfig @@ -10,6 +11,14 @@ import distutils.util +def get_config_var(var): + try: + return sysconfig.get_config_var(var) + except IOError as e: # pip Issue #1074 + warnings.warn("{0}".format(e), RuntimeWarning) + return None + + def get_abbr_impl(): """Return abbreviated implementation name.""" if hasattr(sys, 'pypy_version_info'): @@ -25,19 +34,76 @@ def get_impl_ver(): """Return implementation version.""" - impl_ver = sysconfig.get_config_var("py_version_nodot") - if not impl_ver: - impl_ver = ''.join(map(str, sys.version_info[:2])) + impl_ver = get_config_var("py_version_nodot") + if not impl_ver or get_abbr_impl() == 'pp': + impl_ver = ''.join(map(str, get_impl_version_info())) return impl_ver +def get_impl_version_info(): + """Return sys.version_info-like tuple for use in decrementing the minor + version.""" + if get_abbr_impl() == 'pp': + # as per https://github.com/pypa/pip/issues/2882 + return (sys.version_info[0], sys.pypy_version_info.major, + sys.pypy_version_info.minor) + else: + return sys.version_info[0], sys.version_info[1] + + +def get_flag(var, fallback, expected=True, warn=True): + """Use a fallback method for determining SOABI flags if the needed config + var is unset or unavailable.""" + val = get_config_var(var) + if val is None: + if warn: + warnings.warn("Config variable '{0}' is unset, Python ABI tag may " + "be incorrect".format(var), RuntimeWarning, 2) + return fallback() + return val == expected + + +def get_abi_tag(): + """Return the ABI tag based on SOABI (if available) or emulate SOABI + (CPython 2, PyPy).""" + soabi = get_config_var('SOABI') + impl = get_abbr_impl() + if not soabi and impl in ('cp', 'pp') and hasattr(sys, 'maxunicode'): + d = '' + m = '' + u = '' + if get_flag('Py_DEBUG', + lambda: hasattr(sys, 'gettotalrefcount'), + warn=(impl == 'cp')): + d = 'd' + if get_flag('WITH_PYMALLOC', + lambda: impl == 'cp', + warn=(impl == 'cp')): + m = 'm' + if get_flag('Py_UNICODE_SIZE', + lambda: sys.maxunicode == 0x10ffff, + expected=4, + warn=(impl == 'cp' and + sys.version_info < (3, 3))) \ + and sys.version_info < (3, 3): + u = 'u' + abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) + elif soabi and soabi.startswith('cpython-'): + abi = 'cp' + soabi.split('-')[1] + elif soabi: + abi = soabi.replace('.', '_').replace('-', '_') + else: + abi = None + return abi + + def get_platform(): """Return our platform name 'win32', 'linux_x86_64'""" # XXX remove distutils dependency return distutils.util.get_platform().replace('.', '_').replace('-', '_') -def get_supported(versions=None): +def get_supported(versions=None, supplied_platform=None): """Return a list of supported tags for each version specified in `versions`. @@ -49,18 +115,19 @@ # Versions must be given with respect to the preference if versions is None: versions = [] - major = sys.version_info[0] + version_info = get_impl_version_info() + major = version_info[:-1] # Support all previous minor Python versions. - for minor in range(sys.version_info[1], -1, -1): - versions.append(''.join(map(str, (major, minor)))) + for minor in range(version_info[-1], -1, -1): + versions.append(''.join(map(str, major + (minor,)))) impl = get_abbr_impl() abis = [] - soabi = sysconfig.get_config_var('SOABI') - if soabi and soabi.startswith('cpython-'): - abis[0:0] = ['cp' + soabi.split('-')[1]] + abi = get_abi_tag() + if abi: + abis[0:0] = [abi] abi3s = set() import imp @@ -72,11 +139,15 @@ abis.append('none') - arch = get_platform() + platforms = [] + if supplied_platform: + platforms.append(supplied_platform) + platforms.append(get_platform()) # Current version, current API (built specifically for our Python): for abi in abis: - supported.append(('%s%s' % (impl, versions[0]), abi, arch)) + for arch in platforms: + supported.append(('%s%s' % (impl, versions[0]), abi, arch)) # No abi / arch, but requires our implementation: for i, version in enumerate(versions): @@ -96,5 +167,3 @@ supported.append(('py%s' % (version[0]), 'none', 'any')) return supported - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel/test/test_tagopt.py new/wheel-0.29.0/wheel/test/test_tagopt.py --- old/wheel-0.26.0/wheel/test/test_tagopt.py 2015-09-15 19:28:15.000000000 +0200 +++ new/wheel-0.29.0/wheel/test/test_tagopt.py 2016-02-05 21:42:39.000000000 +0100 @@ -1,5 +1,6 @@ """ -Tests for the bdist_wheel tag options (--python-tag and --universal) +Tests for the bdist_wheel tag options (--python-tag, --universal, and +--plat-name) """ import sys @@ -10,27 +11,39 @@ import subprocess SETUP_PY = """\ -from setuptools import setup +from setuptools import setup, Extension setup( name="Test", version="1.0", author_email="aut...@example.com", py_modules=["test"], + {ext_modules} ) """ +EXT_MODULES = "ext_modules=[Extension('_test', sources=['test.c'])]," + @pytest.fixture -def temp_pkg(request): +def temp_pkg(request, ext=False): tempdir = tempfile.mkdtemp() def fin(): shutil.rmtree(tempdir) request.addfinalizer(fin) temppath = py.path.local(tempdir) temppath.join('test.py').write('print("Hello, world")') - temppath.join('setup.py').write(SETUP_PY) + if ext: + temppath.join('test.c').write('#include <stdio.h>') + setup_py = SETUP_PY.format(ext_modules=EXT_MODULES) + else: + setup_py = SETUP_PY.format(ext_modules='') + temppath.join('setup.py').write(setup_py) return temppath +@pytest.fixture +def temp_ext_pkg(request): + return temp_pkg(request, ext=True) + def test_default_tag(temp_pkg): subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel'], cwd=str(temp_pkg)) @@ -38,7 +51,7 @@ assert dist_dir.check(dir=1) wheels = dist_dir.listdir() assert len(wheels) == 1 - assert wheels[0].basename.startswith('Test-1.0-py%s-' % (sys.version[0],)) + assert wheels[0].basename == 'Test-1.0-py%s-none-any.whl' % (sys.version[0],) assert wheels[0].ext == '.whl' def test_explicit_tag(temp_pkg): @@ -110,3 +123,54 @@ assert wheels[0].basename.startswith('Test-1.0-py2.py3-') assert wheels[0].ext == '.whl' +def test_plat_name_purepy(temp_pkg): + subprocess.check_call( + [sys.executable, 'setup.py', 'bdist_wheel', '--plat-name=testplat.pure'], + cwd=str(temp_pkg)) + dist_dir = temp_pkg.join('dist') + assert dist_dir.check(dir=1) + wheels = dist_dir.listdir() + assert len(wheels) == 1 + assert wheels[0].basename.endswith('-testplat_pure.whl') + assert wheels[0].ext == '.whl' + +def test_plat_name_ext(temp_ext_pkg): + try: + subprocess.check_call( + [sys.executable, 'setup.py', 'bdist_wheel', '--plat-name=testplat.arch'], + cwd=str(temp_ext_pkg)) + except subprocess.CalledProcessError: + pytest.skip("Cannot compile C Extensions") + dist_dir = temp_ext_pkg.join('dist') + assert dist_dir.check(dir=1) + wheels = dist_dir.listdir() + assert len(wheels) == 1 + assert wheels[0].basename.endswith('-testplat_arch.whl') + assert wheels[0].ext == '.whl' + +def test_plat_name_purepy_in_setupcfg(temp_pkg): + temp_pkg.join('setup.cfg').write('[bdist_wheel]\nplat_name=testplat.pure') + subprocess.check_call( + [sys.executable, 'setup.py', 'bdist_wheel'], + cwd=str(temp_pkg)) + dist_dir = temp_pkg.join('dist') + assert dist_dir.check(dir=1) + wheels = dist_dir.listdir() + assert len(wheels) == 1 + assert wheels[0].basename.endswith('-testplat_pure.whl') + assert wheels[0].ext == '.whl' + +def test_plat_name_ext_in_setupcfg(temp_ext_pkg): + temp_ext_pkg.join('setup.cfg').write('[bdist_wheel]\nplat_name=testplat.arch') + try: + subprocess.check_call( + [sys.executable, 'setup.py', 'bdist_wheel'], + cwd=str(temp_ext_pkg)) + except subprocess.CalledProcessError: + pytest.skip("Cannot compile C Extensions") + dist_dir = temp_ext_pkg.join('dist') + assert dist_dir.check(dir=1) + wheels = dist_dir.listdir() + assert len(wheels) == 1 + assert wheels[0].basename.endswith('-testplat_arch.whl') + assert wheels[0].ext == '.whl' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel/test/test_tool.py new/wheel-0.29.0/wheel/test/test_tool.py --- old/wheel-0.26.0/wheel/test/test_tool.py 2015-09-15 19:28:15.000000000 +0200 +++ new/wheel-0.29.0/wheel/test/test_tool.py 2016-02-05 21:42:39.000000000 +0100 @@ -1,17 +1,14 @@ from .. import tool -def test_keygen(): +def test_keygen(): def get_keyring(): WheelKeys, keyring = tool.get_keyring() - + class WheelKeysTest(WheelKeys): def save(self): pass - + class keyringTest: - backend = keyring.backend - class backends: - file = keyring.backends.file @classmethod def get_keyring(cls): class keyringTest2: @@ -20,9 +17,9 @@ self.pw = c def get_password(self, a, b): return self.pw - + return keyringTest2() - + return WheelKeysTest, keyringTest - + tool.keygen(get_keyring=get_keyring) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel/test/test_wheelfile.py new/wheel-0.29.0/wheel/test/test_wheelfile.py --- old/wheel-0.26.0/wheel/test/test_wheelfile.py 2015-09-15 19:28:15.000000000 +0200 +++ new/wheel-0.29.0/wheel/test/test_wheelfile.py 2016-02-06 18:05:31.000000000 +0100 @@ -1,11 +1,48 @@ +import os import wheel.install +import wheel.archive import hashlib try: from StringIO import StringIO except ImportError: from io import BytesIO as StringIO +import codecs import zipfile import pytest +import shutil +import tempfile +from contextlib import contextmanager + +@contextmanager +def environ(key, value): + old_value = os.environ.get(key) + try: + os.environ[key] = value + yield + finally: + if old_value is None: + del os.environ[key] + else: + os.environ[key] = old_value + +@contextmanager +def temporary_directory(): + # tempfile.TemporaryDirectory doesn't exist in Python 2. + tempdir = tempfile.mkdtemp() + try: + yield tempdir + finally: + shutil.rmtree(tempdir) + +@contextmanager +def readable_zipfile(path): + # zipfile.ZipFile() isn't a context manager under Python 2. + zf = zipfile.ZipFile(path, 'r') + try: + yield zf + finally: + zf.close() + def test_verifying_zipfile(): if not hasattr(zipfile.ZipExtFile, '_update_crc'): @@ -66,4 +103,40 @@ zf = wheel.install.VerifyingZipFile(sio, 'r') assert len(zf.infolist()) == 1 - \ No newline at end of file + +def test_zipfile_timestamp(): + # An environment variable can be used to influence the timestamp on + # TarInfo objects inside the zip. See issue #143. TemporaryDirectory is + # not a context manager under Python 3. + with temporary_directory() as tempdir: + for filename in ('one', 'two', 'three'): + path = os.path.join(tempdir, filename) + with codecs.open(path, 'w', encoding='utf-8') as fp: + fp.write(filename + '\n') + zip_base_name = os.path.join(tempdir, 'dummy') + # The earliest date representable in TarInfos, 1980-01-01 + with environ('SOURCE_DATE_EPOCH', '315576060'): + zip_filename = wheel.archive.make_wheelfile_inner( + zip_base_name, tempdir) + with readable_zipfile(zip_filename) as zf: + for info in zf.infolist(): + assert info.date_time[:3] == (1980, 1, 1) + +def test_zipfile_attributes(): + # With the change from ZipFile.write() to .writestr(), we need to manually + # set member attributes. + with temporary_directory() as tempdir: + files = (('foo', 0o644), ('bar', 0o755)) + for filename, mode in files: + path = os.path.join(tempdir, filename) + with codecs.open(path, 'w', encoding='utf-8') as fp: + fp.write(filename + '\n') + os.chmod(path, mode) + zip_base_name = os.path.join(tempdir, 'dummy') + zip_filename = wheel.archive.make_wheelfile_inner( + zip_base_name, tempdir) + with readable_zipfile(zip_filename) as zf: + for filename, mode in files: + info = zf.getinfo(os.path.join(tempdir, filename)) + assert info.external_attr == (mode | 0o100000) << 16 + assert info.compress_type == zipfile.ZIP_DEFLATED diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel/tool/__init__.py new/wheel-0.29.0/wheel/tool/__init__.py --- old/wheel-0.26.0/wheel/tool/__init__.py 2015-09-15 19:28:15.000000000 +0200 +++ new/wheel-0.29.0/wheel/tool/__init__.py 2016-02-05 21:42:39.000000000 +0100 @@ -10,7 +10,7 @@ from glob import iglob from .. import signatures -from ..util import (urlsafe_b64decode, urlsafe_b64encode, native, binary, +from ..util import (urlsafe_b64decode, urlsafe_b64encode, native, binary, matches_requirement) from ..install import WheelFile @@ -29,8 +29,9 @@ try: from ..signatures import keys import keyring - except ImportError: - raise WheelError("Install wheel[signatures] (requires keyring, pyxdg) for signatures.") + assert keyring.get_keyring().priority + except (ImportError, AssertionError): + raise WheelError("Install wheel[signatures] (requires keyring, keyrings.alt, pyxdg) for signatures.") return keys.WheelKeys, keyring def keygen(get_keyring=get_keyring): @@ -47,10 +48,7 @@ kr = keyring.get_keyring() kr.set_password("wheel", vk, sk) sys.stdout.write("Created Ed25519 keypair with vk={0}\n".format(vk)) - if isinstance(kr, keyring.backends.file.BaseKeyring): - sys.stdout.write("in {0}\n".format(kr.file_path)) - else: - sys.stdout.write("in %r\n" % kr.__class__) + sys.stdout.write("in {0!r}\n".format(kr)) sk2 = kr.get_password('wheel', vk) if sk2 != sk: @@ -94,9 +92,9 @@ def unsign(wheelfile): """ Remove RECORD.jws from a wheel by truncating the zip file. - - RECORD.jws must be at the end of the archive. The zip file must be an - ordinary archive, with the compressed files and the directory in the same + + RECORD.jws must be at the end of the archive. The zip file must be an + ordinary archive, with the compressed files and the directory in the same order, and without any non-zip content after the truncation point. """ import wheel.install @@ -109,8 +107,8 @@ def verify(wheelfile): """Verify a wheel. - - The signature will be verified for internal consistency ONLY and printed. + + The signature will be verified for internal consistency ONLY and printed. Wheel's own unpack/install commands verify the manifest against the signature and file contents. """ @@ -142,7 +140,7 @@ wheel_dirs=None, force=False, list_files=False, dry_run=False): """Install wheels. - + :param requirements: A list of requirements or wheel files to install. :param requirements_file: A file containing requirements to install. :param wheel_dirs: A list of directories to search for wheels. @@ -243,7 +241,7 @@ def convert(installers, dest_dir, verbose): require_pkgresources('wheel convert') - + # Only support wheel convert if pkg_resources is present from ..wininst2wheel import bdist_wininst2wheel from ..egg2wheel import egg2wheel @@ -318,7 +316,7 @@ "but don't actually install anything.") install_parser.set_defaults(func=install_f) - def install_scripts_f(args): + def install_scripts_f(args): install_scripts(args.distributions) install_scripts_parser = s.add_parser('install-scripts', help='Install console_scripts') install_scripts_parser.add_argument('distributions', nargs='*', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel.egg-info/PKG-INFO new/wheel-0.29.0/wheel.egg-info/PKG-INFO --- old/wheel-0.26.0/wheel.egg-info/PKG-INFO 2015-09-18 20:03:12.000000000 +0200 +++ new/wheel-0.29.0/wheel.egg-info/PKG-INFO 2016-02-06 18:21:02.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: wheel -Version: 0.26.0 +Version: 0.29.0 Summary: A built-package format for Python. Home-page: https://bitbucket.org/pypa/wheel/ Author: Daniel Holth @@ -48,6 +48,43 @@ reference implementation. + Code of Conduct + --------------- + + Everyone interacting in the wheel project's codebases, issue trackers, chat + rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. + + .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + + + + 0.29.0 + ====== + - Fix compression type of files in archive (Issue #155, Pull Request #62, + thanks Xavier Fernandez) + + 0.28.0 + ====== + - Fix file modes in archive (Issue #154) + + 0.27.0 + ====== + - Support forcing a platform tag using `--plat-name` on pure-Python wheels, as + well as nonstandard platform tags on non-pure wheels (Pull Request #60, Issue + #144, thanks Andrés Díaz) + - Add SOABI tags to platform-specific wheels built for Python 2.X (Pull Request + #55, Issue #63, Issue #101) + - Support reproducible wheel files, wheels that can be rebuilt and will hash to + the same values as previous builds (Pull Request #52, Issue #143, thanks + Barry Warsaw) + - Support for changes in keyring >= 8.0 (Pull Request #61, thanks Jason R. + Coombs) + - Use the file context manager when checking if dependency_links.txt is empty, + fixes problems building wheels under PyPy on Windows (Issue #150, thanks + Cosimo Lupo) + - Don't attempt to (recursively) create a build directory ending with `..` + (invalid on all platforms, but code was only executed on Windows) (Issue #91) + - Added the PyPA Code of Conduct (Pull Request #56) 0.26.0 ====== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wheel-0.26.0/wheel.egg-info/requires.txt new/wheel-0.29.0/wheel.egg-info/requires.txt --- old/wheel-0.26.0/wheel.egg-info/requires.txt 2015-09-18 20:03:12.000000000 +0200 +++ new/wheel-0.29.0/wheel.egg-info/requires.txt 2016-02-06 18:21:02.000000000 +0100 @@ -7,6 +7,10 @@ [signatures] keyring +keyrings.alt + +[signatures:python_version=="2.6"] +importlib [signatures:sys_platform!="win32"] pyxdg