2
2
3
3
import importlib .abc
4
4
import importlib .util
5
+ import importlib .machinery
6
+ import importlib .readers # Might be Python version specific?
5
7
import os
6
8
import subprocess
7
9
import sys
@@ -76,6 +78,26 @@ def release(self) -> None:
76
78
fcntl .flock (self .lock_file_fd , fcntl .LOCK_UN )
77
79
os .close (self .lock_file_fd )
78
80
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
+
79
101
80
102
class ScikitBuildRedirectingFinder (importlib .abc .MetaPathFinder ):
81
103
def __init__ (
@@ -153,6 +175,7 @@ def find_spec(
153
175
submodule_search_locations = submodule_search_locations
154
176
if redir .endswith (("__init__.py" , "__init__.pyc" ))
155
177
else None ,
178
+ loader = ScikitBuildRedirectingLoader (fullname , os .path .join (self .dir , redir )),
156
179
)
157
180
if fullname in self .known_source_files :
158
181
redir = self .known_source_files [fullname ]
@@ -162,6 +185,7 @@ def find_spec(
162
185
submodule_search_locations = submodule_search_locations
163
186
if redir .endswith (("__init__.py" , "__init__.pyc" ))
164
187
else None ,
188
+ loader = ScikitBuildRedirectingLoader (fullname , redir ),
165
189
)
166
190
return None
167
191
0 commit comments