Skip to content

Commit

Permalink
Merge pull request #453 from jherland/symlinked-packages-work
Browse files Browse the repository at this point in the history
Detecting and handling PDM's symlinked packages
  • Loading branch information
jaraco committed Jun 18, 2023
2 parents 62144eb + 53e47d9 commit f604d3e
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
7 changes: 7 additions & 0 deletions CHANGES.rst
@@ -1,3 +1,10 @@
v6.7.0
======

* #453: When inferring top-level names that are importable for
distributions in ``package_distributions``, now symlinks to
other directories are honored.

v6.6.0
======

Expand Down
8 changes: 6 additions & 2 deletions importlib_metadata/__init__.py
Expand Up @@ -981,30 +981,34 @@ def _topmost(name: PackagePath) -> Optional[str]:
return top if rest else None


def _get_toplevel_name(name: PackagePath) -> Optional[str]:
def _get_toplevel_name(name: PackagePath) -> str:
"""
Infer a possibly importable module name from a name presumed on
sys.path.
>>> _get_toplevel_name(PackagePath('foo.py'))
'foo'
>>> _get_toplevel_name(PackagePath('foo'))
'foo'
>>> _get_toplevel_name(PackagePath('foo.pyc'))
'foo'
>>> _get_toplevel_name(PackagePath('foo/__init__.py'))
'foo'
>>> _get_toplevel_name(PackagePath('foo.pth'))
'foo.pth'
>>> _get_toplevel_name(PackagePath('foo.dist-info'))
'foo.dist-info'
"""
return _topmost(name) or (
# python/typeshed#10328
inspect.getmodulename(name) # type: ignore
or str(name)
)


def _top_level_inferred(dist):
opt_names = set(map(_get_toplevel_name, always_iterable(dist.files)))

@pass_none
def importable_name(name):
return '.' not in name

Expand Down
22 changes: 22 additions & 0 deletions tests/test_main.py
Expand Up @@ -9,6 +9,7 @@

from . import fixtures
from ._context import suppress
from ._path import Symlink
from importlib_metadata import (
Distribution,
EntryPoint,
Expand Down Expand Up @@ -399,6 +400,27 @@ def test_packages_distributions_all_module_types(self):

assert not any(name.endswith('.dist-info') for name in distributions)

def test_packages_distributions_symlinked_top_level(self):
"""
Distribution is resolvable from a simple top-level symlink in RECORD.
See #452.
"""

files: fixtures.FilesSpec = {
"symlinked_pkg-1.0.0.dist-info": {
"METADATA": """
Name: symlinked-pkg
Version: 1.0.0
""",
"RECORD": "symlinked,,\n",
},
".symlink.target": {},
"symlinked": Symlink(".symlink.target"),
}

fixtures.build_files(files, self.site_dir)
assert packages_distributions()['symlinked'] == ['symlinked-pkg']


class PackagesDistributionsEggTest(
fixtures.EggInfoPkg,
Expand Down

0 comments on commit f604d3e

Please sign in to comment.