diff --git a/importlib_metadata/__init__.py b/importlib_metadata/__init__.py index 61325221..c2c4b1e9 100644 --- a/importlib_metadata/__init__.py +++ b/importlib_metadata/__init__.py @@ -19,6 +19,7 @@ import posixpath import collections +from .compat.py38 import relative_fix from . import _adapters, _meta, _py39compat from ._collections import FreezableDefaultDict, Pair from ._compat import ( @@ -562,31 +563,14 @@ def _read_files_egginfo_installed(self): if not text or not subdir: return - site_path = self.locate_file('').resolve() paths = ( - self._relative_to( - (subdir / name).resolve(), - site_path, - ).as_posix() + relative_fix((subdir / name).resolve()) + .relative_to(self.locate_file('').resolve(), walk_up=True) + .as_posix() for name in text.splitlines() ) return map('"{}"'.format, paths) - def _relative_to(self, path, root): - """ - Workaround for https://github.com/python/cpython/issues/67271 where ".." - isn't added by pathlib.Path.relative_to() when path is not - a subpath of root. - - One example of such a package is dask-labextension, which uses - jupyter-packaging to install JupyterLab javascript files outside - of site-packages. - """ - try: - return path.relative_to(root) - except ValueError: - return pathlib.Path(os.path.relpath(path, root)) - def _read_files_egginfo_sources(self): """ Read SOURCES.txt and return lines in a similar CSV-parsable diff --git a/importlib_metadata/compat/py38.py b/importlib_metadata/compat/py38.py new file mode 100644 index 00000000..2499c3f6 --- /dev/null +++ b/importlib_metadata/compat/py38.py @@ -0,0 +1,23 @@ +import os +import pathlib +import sys +import types + + +def wrap(path): + """ + Workaround for https://github.com/python/cpython/issues/67271 where ".." + isn't added by pathlib.Path.relative_to() when path is not + a subpath of root. + One example of such a package is dask-labextension, which uses + jupyter-packaging to install JupyterLab javascript files outside + of site-packages. + """ + + def relative_to(root, *, walk_up=False): + return pathlib.Path(os.path.relpath(path, root)) + + return types.SimpleNamespace(relative_to=relative_to) + + +relative_fix = wrap if sys.version_info < (3, 9) else lambda x: x