22
33import importlib .abc
44import importlib .util
5+ import importlib .machinery
6+ import importlib .readers # Might be Python version specific?
57import os
68import subprocess
79import sys
@@ -76,6 +78,26 @@ def release(self) -> None:
7678 fcntl .flock (self .lock_file_fd , fcntl .LOCK_UN )
7779 os .close (self .lock_file_fd )
7880
81+ # Note: This solution relies on importlib's call stack in Python 3.11. Python 3.9 looks
82+ # different, so might require a different solution, but I haven't gone deeper into that
83+ # yet since I don't have a solution for the 3.11 case yet anyway.
84+ class ScikitBuildRedirectingReader (importlib .readers .FileReader ):
85+ def files (self ):
86+ # ATTENTION: This is where the problem is. The expectation is that this returns
87+ # a Traversable object. We could hack together an object that satisfies that
88+ # API, but methods like `joinpath` don't have sensible implementations if
89+ # `files` could return multiple paths instead of a single one. We could do some
90+ # hackery to figure out which paths exist on the backend by hiding some internal
91+ # representation that knows both possible roots and checks for existence when
92+ # necessary, but that seriously violates the principle of least surprise for the
93+ # user so I'd be quite skeptical.
94+ return self .path
95+
96+
97+ class ScikitBuildRedirectingLoader (importlib .machinery .SourceFileLoader ):
98+ def get_resource_reader (self , module ):
99+ return ScikitBuildRedirectingReader (self )
100+
79101
80102class ScikitBuildRedirectingFinder (importlib .abc .MetaPathFinder ):
81103 def __init__ (
@@ -153,6 +175,7 @@ def find_spec(
153175 submodule_search_locations = submodule_search_locations
154176 if redir .endswith (("__init__.py" , "__init__.pyc" ))
155177 else None ,
178+ loader = ScikitBuildRedirectingLoader (fullname , os .path .join (self .dir , redir )),
156179 )
157180 if fullname in self .known_source_files :
158181 redir = self .known_source_files [fullname ]
@@ -162,6 +185,7 @@ def find_spec(
162185 submodule_search_locations = submodule_search_locations
163186 if redir .endswith (("__init__.py" , "__init__.pyc" ))
164187 else None ,
188+ loader = ScikitBuildRedirectingLoader (fullname , redir ),
165189 )
166190 return None
167191
0 commit comments