2525import sys
2626from glob import iglob
2727from configparser import ConfigParser
28- from importlib .machinery import ModuleSpec
28+ from importlib .machinery import ModuleSpec , all_suffixes
2929from itertools import chain
3030from typing import (
3131 TYPE_CHECKING ,
4747from distutils .errors import DistutilsOptionError
4848
4949from .._path import same_path as _same_path , StrPath
50+ from ..discovery import find_package_path
5051from ..warnings import SetuptoolsWarning
5152
5253if TYPE_CHECKING :
5354 from setuptools .dist import Distribution # noqa
54- from setuptools .discovery import ConfigDiscovery # noqa
55- from distutils .dist import DistributionMetadata # noqa
5655
57- chain_iter = chain .from_iterable
5856_K = TypeVar ("_K" )
5957_V = TypeVar ("_V" , covariant = True )
6058
@@ -187,7 +185,7 @@ def read_attr(
187185 attr_name = attrs_path .pop ()
188186 module_name = '.' .join (attrs_path )
189187 module_name = module_name or '__init__'
190- _parent_path , path , module_name = _find_module (module_name , package_dir , root_dir )
188+ path = _find_module (module_name , package_dir , root_dir )
191189 spec = _find_spec (module_name , path )
192190
193191 try :
@@ -220,36 +218,25 @@ def _load_spec(spec: ModuleSpec, module_name: str) -> ModuleType:
220218
221219def _find_module (
222220 module_name : str , package_dir : Optional [Mapping [str , str ]], root_dir : StrPath
223- ) -> Tuple [StrPath , Optional [str ], str ]:
224- """Given a module (that could normally be imported by ``module_name``
225- after the build is complete), find the path to the parent directory where
226- it is contained and the canonical name that could be used to import it
227- considering the ``package_dir`` in the build configuration and ``root_dir``
221+ ) -> Optional [str ]:
222+ """Find the path to the module named ``module_name``,
223+ considering the ``package_dir`` in the build configuration and ``root_dir``.
224+
225+ >>> tmp = getfixture('tmpdir')
226+ >>> _ = tmp.ensure("a/b/c.py")
227+ >>> _ = tmp.ensure("a/b/d/__init__.py")
228+ >>> r = lambda x: x.replace(str(tmp), "tmp").replace(os.sep, "/")
229+ >>> r(_find_module("a.b.c", None, tmp))
230+ 'tmp/a/b/c.py'
231+ >>> r(_find_module("f.g.h", {"": "1", "f": "2", "f.g": "3", "f.g.h": "a/b/d"}, tmp))
232+ 'tmp/a/b/d/__init__.py'
228233 """
229- parent_path = root_dir
230- module_parts = module_name .split ('.' )
231- if package_dir :
232- if module_parts [0 ] in package_dir :
233- # A custom path was specified for the module we want to import
234- custom_path = package_dir [module_parts [0 ]]
235- parts = custom_path .rsplit ('/' , 1 )
236- if len (parts ) > 1 :
237- parent_path = os .path .join (root_dir , parts [0 ])
238- parent_module = parts [1 ]
239- else :
240- parent_module = custom_path
241- module_name = "." .join ([parent_module , * module_parts [1 :]])
242- elif '' in package_dir :
243- # A custom parent directory was specified for all root modules
244- parent_path = os .path .join (root_dir , package_dir ['' ])
245-
246- path_start = os .path .join (parent_path , * module_name .split ("." ))
247- candidates = chain (
248- (f"{ path_start } .py" , os .path .join (path_start , "__init__.py" )),
249- iglob (f"{ path_start } .*" ),
234+ path_start = find_package_path (module_name , package_dir or {}, root_dir )
235+ candidates = chain .from_iterable (
236+ (f"{ path_start } { ext } " , os .path .join (path_start , f"__init__{ ext } " ))
237+ for ext in all_suffixes ()
250238 )
251- module_path = next ((x for x in candidates if os .path .isfile (x )), None )
252- return parent_path , module_path , module_name
239+ return next ((x for x in candidates if os .path .isfile (x )), None )
253240
254241
255242def resolve_class (
@@ -263,8 +250,8 @@ def resolve_class(
263250 class_name = qualified_class_name [idx + 1 :]
264251 pkg_name = qualified_class_name [:idx ]
265252
266- _parent_path , path , module_name = _find_module (pkg_name , package_dir , root_dir )
267- module = _load_spec (_find_spec (module_name , path ), module_name )
253+ path = _find_module (pkg_name , package_dir , root_dir )
254+ module = _load_spec (_find_spec (pkg_name , path ), pkg_name )
268255 return getattr (module , class_name )
269256
270257
0 commit comments