summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Moore <p.f.moore@gmail.com>2014-03-29 12:28:00 +0000
committerPaul Moore <p.f.moore@gmail.com>2014-03-29 12:28:00 +0000
commit12a19453932428fe1a52e66f15c45ce70d8cf360 (patch)
treea338417495e7e0fe70938ee81ae90b9cf62adc20
parent4ca300562777bef14e7990d113b6fc8d6816a8a2 (diff)
parent65eabd5766f6edf1d208d249e1938702014cebc3 (diff)
downloadwheel-12a19453932428fe1a52e66f15c45ce70d8cf360.tar.gz
Merged in pmoore/wheel (pull request #42)
Add a --python-tag argument for bdist_wheel
-rw-r--r--docs/index.rst37
-rw-r--r--setup.cfg2
-rw-r--r--wheel/bdist_wheel.py21
-rw-r--r--wheel/test/test_tagopt.py112
4 files changed, 161 insertions, 11 deletions
diff --git a/docs/index.rst b/docs/index.rst
index 3ddeccf..6cd20d3 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -97,6 +97,43 @@ contain the setuptools script wrappers. The wheel tool `python -m wheel
install-scripts packagename` calls setuptools to write the appropriate
scripts wrappers after an install.
+Defining the Python version
+---------------------------
+
+The `bdist_wheel` command automatically determines the correct tags to use for
+the generated wheel. These are based on the Python interpreter used to
+generate the wheel and whether the project contains C extension code or not.
+While this is usually correct for C code, it can be too conservative for pure
+Python code. The bdist_wheel command therefore supports two flags that can be
+used to specify the Python version tag to use more precisely::
+
+ --universal Specifies that a pure-python wheel is "universal"
+ (i.e., it works on any version of Python). This
+ equates to the tag "py2.py3".
+ --python-tag XXX Specifies the precide python version tag to use for
+ a pure-python wheel.
+
+Neither of these two flags have any effect when used on a project that includes
+C extension code.
+
+A reasonable use of the `--python-tag` argument would be for a project that
+uses Python syntax only introduced in a particular Python version. There are
+no current examples of this, but if wheels had been available when Python 2.5
+was released (the first version containing the `with` statement), wheels for a
+project that used the `with` statement would typically use `--python-tag py25`.
+
+Typically, projects would not specify python tags on the command line, but
+would use `setup.cfg` to set them as a project default::
+
+ [bdist_wheel]
+ universal=1
+
+or::
+
+ [bdist_wheel]
+ python-tag = py32
+
+
Automatically sign wheel files
------------------------------
diff --git a/setup.cfg b/setup.cfg
index 34226ca..9a562c0 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -13,6 +13,6 @@ requires-dist =
ed25519ll; extra == 'faster-signatures'
license-file = LICENSE.txt
-[wheel]
+[bdist_wheel]
# use py2.py3 tag for pure-python dist:
universal=1
diff --git a/wheel/bdist_wheel.py b/wheel/bdist_wheel.py
index 8401bd9..9c57f3e 100644
--- a/wheel/bdist_wheel.py
+++ b/wheel/bdist_wheel.py
@@ -77,6 +77,9 @@ class bdist_wheel(Command):
('universal', None,
"make a universal wheel"
" (default: false)"),
+ ('python-tag=', None,
+ "Python implementation compatibility tag"
+ " (default: py%s)" % get_impl_ver()[0]),
]
boolean_options = ['keep-temp', 'skip-build', 'relative', 'universal']
@@ -97,6 +100,7 @@ class bdist_wheel(Command):
self.group = None
self.skip_scripts = False
self.universal = False
+ self.python_tag = 'py' + get_impl_ver()[0]
def finalize_options(self):
if self.bdist_dir is None:
@@ -129,27 +133,24 @@ class bdist_wheel(Command):
def get_tag(self):
supported_tags = pep425tags.get_supported()
- purity = self.distribution.is_pure()
- impl_ver = get_impl_ver()
- abi_tag = 'none'
- plat_name = 'any'
- impl_name = 'py'
- if purity:
+ if self.distribution.is_pure():
if self.universal:
- impl_name = 'py2.py3'
- impl_ver = ''
- tag = (impl_name + impl_ver, abi_tag, plat_name)
+ impl = 'py2.py3'
+ else:
+ impl = self.python_tag
+ tag = (impl, 'none', 'any')
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', abi_tag)
+ abi_tag = sysconfig.get_config_vars().get('SOABI', 'none')
if abi_tag.startswith('cpython-'):
abi_tag = 'cp' + abi_tag.rsplit('-', 1)[-1]
diff --git a/wheel/test/test_tagopt.py b/wheel/test/test_tagopt.py
new file mode 100644
index 0000000..e013092
--- /dev/null
+++ b/wheel/test/test_tagopt.py
@@ -0,0 +1,112 @@
+"""
+Tests for the bdist_wheel tag options (--python-tag and --universal)
+"""
+
+import os
+import sys
+import pytest
+import py.path
+import tempfile
+import subprocess
+
+SETUP_PY = """\
+from setuptools import setup
+
+setup(
+ name="Test",
+ version="1.0",
+ author_email="author@example.com",
+ py_modules=["test"],
+)
+"""
+
+@pytest.fixture
+def temp_pkg(request):
+ tempdir = tempfile.TemporaryDirectory()
+ def fin():
+ tempdir.cleanup()
+ request.addfinalizer(fin)
+ temppath = py.path.local(tempdir.name)
+ temppath.join('test.py').write('print("Hello, world")')
+ temppath.join('setup.py').write(SETUP_PY)
+ return temppath
+
+def test_default_tag(temp_pkg):
+ 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.startswith('Test-1.0-py%s-' % (sys.version[0],))
+ assert wheels[0].ext == '.whl'
+
+def test_explicit_tag(temp_pkg):
+ subprocess.check_call(
+ [sys.executable, 'setup.py', 'bdist_wheel', '--python-tag=py32'],
+ 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.startswith('Test-1.0-py32-')
+ assert wheels[0].ext == '.whl'
+
+def test_universal_tag(temp_pkg):
+ subprocess.check_call(
+ [sys.executable, 'setup.py', 'bdist_wheel', '--universal'],
+ 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.startswith('Test-1.0-py2.py3-')
+ assert wheels[0].ext == '.whl'
+
+def test_universal_beats_explicit_tag(temp_pkg):
+ subprocess.check_call(
+ [sys.executable, 'setup.py', 'bdist_wheel', '--universal', '--python-tag=py32'],
+ 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.startswith('Test-1.0-py2.py3-')
+ assert wheels[0].ext == '.whl'
+
+def test_universal_in_setup_cfg(temp_pkg):
+ temp_pkg.join('setup.cfg').write('[bdist_wheel]\nuniversal=1')
+ 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.startswith('Test-1.0-py2.py3-')
+ assert wheels[0].ext == '.whl'
+
+def test_pythontag_in_setup_cfg(temp_pkg):
+ temp_pkg.join('setup.cfg').write('[bdist_wheel]\npython_tag=py32')
+ 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.startswith('Test-1.0-py32-')
+ assert wheels[0].ext == '.whl'
+
+def test_legacy_wheel_section_in_setup_cfg(temp_pkg):
+ temp_pkg.join('setup.cfg').write('[wheel]\nuniversal=1')
+ 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.startswith('Test-1.0-py2.py3-')
+ assert wheels[0].ext == '.whl'
+