Skip to content

Commit 7d9af50

Browse files
committed
Update implementation of import hook loaders to use find_spec.
1 parent 218a933 commit 7d9af50

File tree

2 files changed

+47
-26
lines changed

2 files changed

+47
-26
lines changed

newrelic/api/import_hook.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818

1919
_logger = logging.getLogger(__name__)
2020

21+
try:
22+
from importlib.util import find_spec
23+
except ImportError:
24+
find_spec = None
25+
2126
_import_hooks = {}
2227

2328
_ok_modules = (
@@ -168,14 +173,26 @@ def find_module(self, fullname, path=None):
168173
self._skip[fullname] = True
169174

170175
try:
171-
try:
172-
from importlib.util import find_spec
173-
return _ImportHookChainedLoader(find_spec(fullname).loader)
174-
except AttributeError:
175-
return None
176-
except ImportError:
176+
# For Python 3 we need to use find_spec() from the importlib
177+
# module.
178+
179+
if find_spec:
180+
spec = find_spec(fullname)
181+
loader = getattr(spec, 'loader', None)
182+
183+
if loader:
184+
return _ImportHookChainedLoader(loader)
185+
186+
else:
177187
__import__(fullname)
188+
189+
# If we get this far then the module we are
190+
# interested in does actually exist and so return
191+
# our loader to trigger import hooks and then return
192+
# the module.
193+
178194
return _ImportHookLoader()
195+
179196
finally:
180197
del self._skip[fullname]
181198

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,47 @@
1-
from pytest import raises
1+
import sys
22

3+
import newrelic.api.import_hook as import_hook
4+
import newrelic.packages.six as six
5+
import pytest
36

4-
def test_import_hook_finder():
7+
# a dummy hook just to be able to register hooks for modules
8+
def hook(*args, **kwargs):
9+
pass
10+
11+
12+
def test_import_hook_finder(monkeypatch):
513
"""
614
This asserts the behavior of ImportHookFinder.find_module. It behaves
715
differently depending on whether or not the module it is looking for
816
exists, has been registered with an import hook, and across different
917
python versions.
1018
"""
11-
from newrelic.api.import_hook import ImportHookFinder, register_import_hook
12-
import sys
13-
14-
PY2 = sys.version_info[0] == 2
15-
16-
finder = ImportHookFinder()
19+
finder = import_hook.ImportHookFinder()
1720

18-
# a dummy hook just to be able to register hooks for modules
19-
def hook(*args, **kwargs):
20-
pass
21+
# Override the registered import hooks for the scope of this test
22+
registered_hooks = {
23+
"registered_but_does_not_exist": hook,
24+
"newrelic.api": hook,
25+
}
26+
monkeypatch.setattr(import_hook, "_import_hooks", registered_hooks)
2127

2228
# Finding a module that does not exist and is not registered returns None.
23-
module = finder.find_module('some_module_that_does_not_exist')
29+
module = finder.find_module("module_does_not_exist")
2430
assert module is None
2531

2632
# Finding a module that does not exist and is registered behaves
2733
# differently on python 2 vs python 3.
28-
register_import_hook('some_module_that_does_not_exist', hook)
29-
if PY2:
30-
with raises(ImportError):
31-
module = finder.find_module('some_module_that_does_not_exist')
34+
if six.PY2:
35+
with pytest.raises(ImportError):
36+
module = finder.find_module("registered_but_does_not_exist")
3237
else:
33-
module = finder.find_module('some_module_that_does_not_exist')
38+
module = finder.find_module("registered_but_does_not_exist")
3439
assert module is None
3540

3641
# Finding a module that exists, but is not registered returns None.
37-
module = finder.find_module('newrelic')
42+
module = finder.find_module("newrelic")
3843
assert module is None
3944

4045
# Finding a module that exists, and is registered, finds that module.
41-
register_import_hook('newrelic', hook)
42-
module = finder.find_module('newrelic')
46+
module = finder.find_module("newrelic.api")
4347
assert module is not None

0 commit comments

Comments
 (0)