Skip to content

Commit

Permalink
WheelFile: finish from_wheelfile
Browse files Browse the repository at this point in the history
  • Loading branch information
MrMino committed Aug 2, 2021
1 parent c7d29c4 commit 57df729
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ Versioning](https://semver.org/spec/v2.0.0.html).
wheel name (`.build_tag`).

### Added
- `WheelFile.from_wheelfile` - a constructor class-method that makes it
possible to recreate a wheel and: rename it (change distname, version,
buildnumber and/or tags), append files to it, change its metadata, etc.
- `WheelFile.METADATA_FILENAMES` - a static field with a set of names of
metadata files managed by this class.
- `WheelFile.writestr_distinfo` - similar to `write_distinfo`, this is a safe
Expand Down
14 changes: 13 additions & 1 deletion tests/test_wheelfile_cloning.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,23 @@ def test_raises_VE_when_same_path_used(self, wf, buf, tmp_file):
with pytest.raises(ValueError):
WheelFile.from_wheelfile(wf, tmp_file)

def test_raises_VE_when_same_path_used_relatively(self, wf, buf, tmp_path):
def test_raises_VE_when_same_path_used_relatively(self, wf, tmp_path):
(tmp_path / 'relative/').mkdir()
(tmp_path / 'path/').mkdir()
path = (tmp_path / 'relative/../path/../')
assert path.is_dir()
with WheelFile(path, mode='w', distname='_', version='0') as wf:
with pytest.raises(ValueError):
WheelFile.from_wheelfile(wf, tmp_path)

@pytest.fixture
def tmp_cwd(self, tmp_path):
old_dir = os.getcwd()
os.chdir(tmp_path)
yield tmp_path
os.chdir(old_dir)

def test_raises_VE_when_same_path_used_via_curdir(self, tmp_cwd):
with WheelFile(tmp_cwd, mode='w', distname='_', version='0') as wf:
with pytest.raises(ValueError):
WheelFile.from_wheelfile(wf)
36 changes: 36 additions & 0 deletions wheelfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -1342,6 +1342,12 @@ def from_wheelfile(
if platform_tag is cls._unspecified:
platform_tag = wf.platform_tag

# Required for the path check below
if isinstance(version, str):
version = Version(version)
if isinstance(file_or_path, str):
file_or_path = Path(file_or_path)

# For MyPy
assert isinstance(distname, str) or distname is None
assert isinstance(version, (str, Version)) or version is None
Expand All @@ -1356,6 +1362,36 @@ def from_wheelfile(
"same as the one used by the other WheelFile object."
)

f_o_p = file_or_path # For brevity
dir_path = (
f_o_p.resolve() if isinstance(f_o_p, Path) and f_o_p.is_dir() else
f_o_p.parent.resolve() if isinstance(f_o_p, Path) else
getattr(f_o_p, 'name', None)
)

# wf.zipfile.filename is not None only when it is writing to a file
both_are_files = (
wf.zipfile.filename is not None
and dir_path is not None
)

if both_are_files:
assert wf.zipfile.filename is not None # For MyPy
# Ensure we won't overwrite wf
wf_dir_path = Path(wf.zipfile.filename).parent.resolve()
if wf_dir_path == dir_path and (
wf.distname == distname
and wf.version == version
and wf.build_tag == build_tag
and wf.language_tag == language_tag
and wf.abi_tag == abi_tag
and wf.platform_tag == platform_tag
):
raise ValueError(
"Operation would overwrite the old wheel - "
"both objects' paths point at the same file."
)

new_wf = WheelFile(
file_or_path, mode,
distname=distname,
Expand Down

0 comments on commit 57df729

Please sign in to comment.