Skip to content

Commit e50ebd7

Browse files
committed
Extract _topmost and _get_toplevel_name functions.
1 parent a063f66 commit e50ebd7

File tree

1 file changed

+31
-25
lines changed

1 file changed

+31
-25
lines changed

importlib_metadata/__init__.py

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@
3131
from importlib import import_module
3232
from importlib.abc import MetaPathFinder
3333
from itertools import starmap
34-
from typing import Iterable, Iterator, List, Mapping, Optional, Set, cast
35-
34+
from typing import Iterable, List, Mapping, Optional, Set, cast
3635

3736
__all__ = [
3837
'Distribution',
@@ -974,35 +973,42 @@ def _top_level_declared(dist):
974973
return (dist.read_text('top_level.txt') or '').split()
975974

976975

977-
def _walk_dirs(package_paths: Iterable[PackagePath]) -> Iterator[PackagePath]:
978-
for package_path in package_paths:
976+
def _topmost(name: PackagePath) -> Optional[str]:
977+
"""
978+
Return the top-most parent as long as there is a parent.
979+
"""
980+
top, *rest = name.parts
981+
return top if rest else None
979982

980-
def make_file(name):
981-
result = PackagePath(name)
982-
result.hash = None
983-
result.size = None
984-
result.dist = package_path.dist
985-
return result
986983

987-
real_path = package_path.locate()
988-
real_sitedir = package_path.dist.locate_file("") # type: ignore
989-
if real_path.is_dir() and real_path.is_symlink():
990-
# .files only mentions symlink, we must recurse into it ourselves:
991-
for root, dirs, files in os.walk(real_path):
992-
for filename in files:
993-
real_file = pathlib.Path(root, filename)
994-
yield make_file(real_file.relative_to(real_sitedir))
995-
else:
996-
yield package_path
984+
def _get_toplevel_name(name: PackagePath) -> str:
985+
"""
986+
Infer a possibly importable module name from a name presumed on
987+
sys.path.
988+
989+
>>> _get_toplevel_name(PackagePath('foo.py'))
990+
'foo'
991+
>>> _get_toplevel_name(PackagePath('foo'))
992+
'foo'
993+
>>> _get_toplevel_name(PackagePath('foo.pyc'))
994+
'foo'
995+
>>> _get_toplevel_name(PackagePath('foo.dist-info'))
996+
'foo.dist-info'
997+
>>> _get_toplevel_name(PackagePath('foo.pth'))
998+
'foo.pth'
999+
>>> _get_toplevel_name(PackagePath('foo/__init__.py'))
1000+
'foo'
1001+
"""
1002+
return _topmost(name) or (
1003+
# python/typeshed#10328
1004+
inspect.getmodulename(name) # type: ignore
1005+
or str(name)
1006+
)
9971007

9981008

9991009
def _top_level_inferred(dist):
1000-
opt_names = {
1001-
f.parts[0] if len(f.parts) > 1 else inspect.getmodulename(f)
1002-
for f in _walk_dirs(always_iterable(dist.files))
1003-
}
1010+
opt_names = set(map(_get_toplevel_name, always_iterable(dist.files)))
10041011

1005-
@pass_none
10061012
def importable_name(name):
10071013
return '.' not in name
10081014

0 commit comments

Comments
 (0)