diff options
| -rw-r--r-- | docs/news.rst | 3 | ||||
| -rw-r--r-- | src/wheel/bdist_wheel.py | 9 | ||||
| -rw-r--r-- | tests/test_bdist_wheel.py | 19 |
3 files changed, 27 insertions, 4 deletions
diff --git a/docs/news.rst b/docs/news.rst index 731c4d4..ef16d4e 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -9,8 +9,9 @@ Release Notes - Updated project packaging and testing configuration for :pep:`517` - Moved the contents of setup.py to setup.cfg - Fixed duplicate RECORD file when using "wheel pack" on Windows +- Fixed bdist_wheel failing at cleanup on Windows with a read-only source tree - Switched the project to use the "src" layout -. Switched to setuptools_scm_ for versioning +- Switched to setuptools_scm_ for versioning .. _setuptools_scm: https://github.com/pypa/setuptools_scm/ diff --git a/src/wheel/bdist_wheel.py b/src/wheel/bdist_wheel.py index 014983c..ce82eb6 100644 --- a/src/wheel/bdist_wheel.py +++ b/src/wheel/bdist_wheel.py @@ -6,6 +6,7 @@ A wheel is a built archive format. import os import shutil +import stat import sys import re from email.generator import Generator @@ -40,6 +41,12 @@ def safer_version(version): return safe_version(version).replace('-', '_') +def remove_readonly(func, path, excinfo): + print(str(excinfo[1])) + os.chmod(path, stat.S_IWRITE) + func(path) + + class bdist_wheel(Command): description = 'create a wheel distribution' @@ -267,7 +274,7 @@ class bdist_wheel(Command): if not self.keep_temp: logger.info('removing %s', self.bdist_dir) if not self.dry_run: - rmtree(self.bdist_dir) + rmtree(self.bdist_dir, onerror=remove_readonly) def write_wheelfile(self, wheelfile_base, generator='bdist_wheel (' + wheel_version + ')'): from email.message import Message diff --git a/tests/test_bdist_wheel.py b/tests/test_bdist_wheel.py index 4c98eda..de8d46f 100644 --- a/tests/test_bdist_wheel.py +++ b/tests/test_bdist_wheel.py @@ -1,5 +1,7 @@ # coding: utf-8 -import os +import os.path +import shutil +import stat import subprocess import sys from zipfile import ZipFile @@ -20,7 +22,7 @@ DEFAULT_LICENSE_FILES = { } -@pytest.fixture(scope='module') +@pytest.fixture def dummy_dist(tmpdir_factory): basedir = tmpdir_factory.mktemp('dummy_dist') basedir.join('setup.py').write("""\ @@ -113,3 +115,16 @@ def test_limited_abi(monkeypatch, tmpdir): monkeypatch.chdir(source_dir) subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel', '-b', str(build_dir), '-d', str(dist_dir)]) + + +def test_build_from_readonly_tree(dummy_dist, monkeypatch, tmpdir): + basedir = str(tmpdir.join('dummy')) + shutil.copytree(str(dummy_dist), basedir) + monkeypatch.chdir(basedir) + + # Make the tree read-only + for root, dirs, files in os.walk(basedir): + for fname in files: + os.chmod(os.path.join(root, fname), stat.S_IREAD) + + subprocess.check_call([sys.executable, 'setup.py', 'bdist_wheel']) |
