Skip to content

Commit cf7a338

Browse files
Fix import hook warnings for Python 3.10+. (#437)
* Fix import hook warnings for py310. * [Mega-Linter] Apply linters fixes * Trigger test run. Co-authored-by: TimPansino <[email protected]> Co-authored-by: Uma Annamalai <[email protected]>
1 parent 1be16b7 commit cf7a338

File tree

1 file changed

+65
-2
lines changed

1 file changed

+65
-2
lines changed

newrelic/api/import_hook.py

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,17 +162,32 @@ def load_module(self, fullname):
162162
module = self.loader.load_module(fullname)
163163

164164
# Call the import hooks on the module being handled.
165-
166165
_notify_import_hooks(fullname, module)
167166

168167
return module
169168

169+
def create_module(self, spec):
170+
return self.loader.create_module(spec)
171+
172+
def exec_module(self, module):
173+
self.loader.exec_module(module)
174+
175+
# Call the import hooks on the module being handled.
176+
_notify_import_hooks(module.__name__, module)
177+
170178

171179
class ImportHookFinder:
172180
def __init__(self):
173181
self._skip = {}
174182

175183
def find_module(self, fullname, path=None):
184+
"""
185+
Find spec and patch import hooks into loader before returning.
186+
187+
Required for Python 2.
188+
189+
https://docs.python.org/3/library/importlib.html#importlib.abc.MetaPathFinder.find_module
190+
"""
176191

177192
# If not something we are interested in we can return.
178193

@@ -200,7 +215,7 @@ def find_module(self, fullname, path=None):
200215
spec = find_spec(fullname)
201216
loader = getattr(spec, "loader", None)
202217

203-
if loader:
218+
if loader and not isinstance(loader, (_ImportHookChainedLoader, _ImportHookLoader)):
204219
return _ImportHookChainedLoader(loader)
205220

206221
else:
@@ -216,6 +231,54 @@ def find_module(self, fullname, path=None):
216231
finally:
217232
del self._skip[fullname]
218233

234+
def find_spec(self, fullname, path=None, target=None):
235+
"""
236+
Find spec and patch import hooks into loader before returning.
237+
238+
Required for Python 3.10+ to avoid warnings.
239+
240+
https://docs.python.org/3/library/importlib.html#importlib.abc.MetaPathFinder.find_spec
241+
"""
242+
# raise ValueError((name, path, target))
243+
244+
# If not something we are interested in we can return.
245+
246+
if fullname not in _import_hooks:
247+
return None
248+
249+
# Check whether this is being called on the second time
250+
# through and return.
251+
252+
if fullname in self._skip:
253+
return None
254+
255+
# We are now going to call back into import. We set a
256+
# flag to see we are handling the module so that check
257+
# above drops out on subsequent pass and we don't go
258+
# into an infinite loop.
259+
260+
self._skip[fullname] = True
261+
262+
try:
263+
# For Python 3 we need to use find_spec() from the importlib
264+
# module.
265+
266+
if find_spec:
267+
spec = find_spec(fullname)
268+
loader = getattr(spec, "loader", None)
269+
270+
if loader and not isinstance(loader, (_ImportHookChainedLoader, _ImportHookLoader)):
271+
spec.loader = _ImportHookChainedLoader(loader)
272+
273+
return spec
274+
275+
else:
276+
# Not possible, Python 3 defines find_spec and Python 2 does not have find_spec on Finders
277+
return None
278+
279+
finally:
280+
del self._skip[fullname]
281+
219282

220283
def import_hook(name):
221284
def decorator(wrapped):

0 commit comments

Comments
 (0)