Skip to content

Commit 12ab8ef

Browse files
committed
_check_module.find(): support namespace package traversal
1 parent c1e6b23 commit 12ab8ef

File tree

1 file changed

+7
-26
lines changed

1 file changed

+7
-26
lines changed

argcomplete/_check_module.py

+7-26
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,7 @@
1010
import os
1111
import sys
1212
import tokenize
13-
14-
try:
15-
from importlib.util import find_spec # type:ignore
16-
except ImportError:
17-
import typing as t
18-
from collections import namedtuple
19-
from imp import find_module # type:ignore
20-
21-
ModuleSpec = namedtuple("ModuleSpec", ["origin", "has_location", "submodule_search_locations"])
22-
23-
def find_spec( # type:ignore
24-
name: str,
25-
package: t.Optional[str] = None,
26-
) -> t.Optional[ModuleSpec]:
27-
"""Minimal implementation as required by `find`."""
28-
try:
29-
f, path, _ = find_module(name)
30-
except ImportError:
31-
return None
32-
has_location = path is not None
33-
if f is None:
34-
return ModuleSpec(None, has_location, [path])
35-
f.close()
36-
return ModuleSpec(path, has_location, None)
13+
from importlib.util import find_spec
3714

3815

3916
class ArgcompleteMarkerNotFound(RuntimeError):
@@ -42,7 +19,11 @@ class ArgcompleteMarkerNotFound(RuntimeError):
4219

4320
def find(name, return_package=False):
4421
names = name.split(".")
45-
spec = find_spec(names[0])
22+
for package_name_boundary in range(len(names)):
23+
spec = find_spec(".".join(names[:package_name_boundary+1]))
24+
if spec is not None and spec.origin is not None:
25+
break
26+
4627
if spec is None:
4728
raise ArgcompleteMarkerNotFound('no module named "{}"'.format(names[0]))
4829
if not spec.has_location:
@@ -53,7 +34,7 @@ def find(name, return_package=False):
5334
return spec.origin
5435
if len(spec.submodule_search_locations) != 1:
5536
raise ArgcompleteMarkerNotFound("expecting one search location")
56-
path = os.path.join(spec.submodule_search_locations[0], *names[1:])
37+
path = os.path.join(spec.submodule_search_locations[0], *names[package_name_boundary+1:])
5738
if os.path.isdir(path):
5839
filename = "__main__.py"
5940
if return_package:

0 commit comments

Comments
 (0)