diff options
author | Paul Moore <p.f.moore@gmail.com> | 2014-03-29 12:28:00 +0000 |
---|---|---|
committer | Paul Moore <p.f.moore@gmail.com> | 2014-03-29 12:28:00 +0000 |
commit | 12a19453932428fe1a52e66f15c45ce70d8cf360 (patch) | |
tree | a338417495e7e0fe70938ee81ae90b9cf62adc20 | |
parent | 4ca300562777bef14e7990d113b6fc8d6816a8a2 (diff) | |
parent | 65eabd5766f6edf1d208d249e1938702014cebc3 (diff) | |
download | wheel-12a19453932428fe1a52e66f15c45ce70d8cf360.tar.gz |
Merged in pmoore/wheel (pull request #42)
Add a --python-tag argument for bdist_wheel
-rw-r--r-- | docs/index.rst | 37 | ||||
-rw-r--r-- | setup.cfg | 2 | ||||
-rw-r--r-- | wheel/bdist_wheel.py | 21 | ||||
-rw-r--r-- | wheel/test/test_tagopt.py | 112 |
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 ------------------------------ @@ -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' + |