1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00

Separate RECORD path from source file path

When we start processing files directly from the wheel, all we will have
are the files with their zip path (which should match a `RECORD`
entry). Separating this from the source file path (used for copying)
and annotating it with our `RecordPath` type makes it clear what the
format of this public property is, and that it should match what is in
`RECORD`.
This commit is contained in:
Chris Hunt 2020-07-05 14:42:04 -04:00
parent 239accb1b6
commit a3b977330a

View file

@ -71,7 +71,7 @@ else:
InstalledCSVRow = Tuple[RecordPath, str, Union[int, str]] InstalledCSVRow = Tuple[RecordPath, str, Union[int, str]]
class File(Protocol): class File(Protocol):
src_path = None # type: text_type src_record_path = None # type: RecordPath
dest_path = None # type: text_type dest_path = None # type: text_type
changed = None # type: bool changed = None # type: bool
@ -398,10 +398,11 @@ def get_console_script_specs(console):
class DiskFile(object): class DiskFile(object):
def __init__(self, src_path, dest_path): def __init__(self, src_record_path, dest_path, src_disk_path):
# type: (text_type, text_type) -> None # type: (RecordPath, text_type, text_type) -> None
self.src_path = src_path self.src_record_path = src_record_path
self.dest_path = dest_path self.dest_path = dest_path
self._src_disk_path = src_disk_path
self.changed = False self.changed = False
def save(self): def save(self):
@ -428,18 +429,18 @@ class DiskFile(object):
# directories) as well as to ensure that we are not copying # directories) as well as to ensure that we are not copying
# over any metadata because we want more control over what # over any metadata because we want more control over what
# metadata we actually copy over. # metadata we actually copy over.
shutil.copyfile(self.src_path, self.dest_path) shutil.copyfile(self._src_disk_path, self.dest_path)
# Copy over the metadata for the file, currently this only # Copy over the metadata for the file, currently this only
# includes the atime and mtime. # includes the atime and mtime.
st = os.stat(self.src_path) st = os.stat(self._src_disk_path)
if hasattr(os, "utime"): if hasattr(os, "utime"):
os.utime(self.dest_path, (st.st_atime, st.st_mtime)) os.utime(self.dest_path, (st.st_atime, st.st_mtime))
# If our file is executable, then make our destination file # If our file is executable, then make our destination file
# executable. # executable.
if os.access(self.src_path, os.X_OK): if os.access(self._src_disk_path, os.X_OK):
st = os.stat(self.src_path) st = os.stat(self._src_disk_path)
permissions = ( permissions = (
st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
) )
@ -450,7 +451,7 @@ class ScriptFile(object):
def __init__(self, file): def __init__(self, file):
# type: (File) -> None # type: (File) -> None
self._file = file self._file = file
self.src_path = self._file.src_path self.src_record_path = self._file.src_record_path
self.dest_path = self._file.dest_path self.dest_path = self._file.dest_path
self.changed = False self.changed = False
@ -525,11 +526,10 @@ def install_unpacked_wheel(
generated = [] # type: List[str] generated = [] # type: List[str]
def record_installed(srcfile, destfile, modified=False): def record_installed(srcfile, destfile, modified=False):
# type: (text_type, text_type, bool) -> None # type: (RecordPath, text_type, bool) -> None
"""Map archive RECORD paths to installation RECORD paths.""" """Map archive RECORD paths to installation RECORD paths."""
oldpath = _fs_to_record_path(srcfile, wheeldir)
newpath = _fs_to_record_path(destfile, lib_dir) newpath = _fs_to_record_path(destfile, lib_dir)
installed[oldpath] = newpath installed[srcfile] = newpath
if modified: if modified:
changed.add(_fs_to_record_path(destfile)) changed.add(_fs_to_record_path(destfile))
@ -544,9 +544,12 @@ def install_unpacked_wheel(
if is_base and basedir == '': if is_base and basedir == '':
subdirs[:] = [s for s in subdirs if not s.endswith('.data')] subdirs[:] = [s for s in subdirs if not s.endswith('.data')]
for f in files: for f in files:
srcfile = os.path.join(dir, f) srcfile = os.path.join(basedir, f).replace(os.path.sep, "/")
destfile = os.path.join(dest, basedir, f) destfile = os.path.join(dest, basedir, f)
yield DiskFile(srcfile, destfile) src_disk_path = os.path.join(dir, f)
yield DiskFile(
cast('RecordPath', srcfile), destfile, src_disk_path
)
files = files_to_process( files = files_to_process(
ensure_text(source, encoding=sys.getfilesystemencoding()), ensure_text(source, encoding=sys.getfilesystemencoding()),
@ -602,7 +605,7 @@ def install_unpacked_wheel(
for file in files: for file in files:
file.save() file.save()
record_installed(file.src_path, file.dest_path, file.changed) record_installed(file.src_record_path, file.dest_path, file.changed)
def pyc_source_file_paths(): def pyc_source_file_paths():
# type: () -> Iterator[text_type] # type: () -> Iterator[text_type]
@ -647,7 +650,10 @@ def install_unpacked_wheel(
if success: if success:
pyc_path = pyc_output_path(path) pyc_path = pyc_output_path(path)
assert os.path.exists(pyc_path) assert os.path.exists(pyc_path)
record_installed(pyc_path, pyc_path) record_installed(
_fs_to_record_path(pyc_path, wheeldir),
pyc_path,
)
logger.debug(stdout.getvalue()) logger.debug(stdout.getvalue())
maker = PipScriptMaker(None, scheme.scripts) maker = PipScriptMaker(None, scheme.scripts)