Skip to content

Commit 218a933

Browse files
authored
Fix DeprecationWarning in import_hook. (#26)
* Fix DeprecationWarning in import_hook For Python >=3.4, using find_loader is deprecated, and importing it generates a DeprecationWarning. Mirroring wrapt's implementation of a similar construct in its importer.py (on which this code seems modeled), we can try to use the new find_spec first, then the old python 2.7 fallback, as before. Since the newrelic python agent only supports 2.7+ and 3.5+, there is no need to keep support for the deprecated find_loader at all. The immediate result of this change is that one less DeprecationWarning is fired at runtime when using the newrelic python agent. There are still other DeprecationWarnings originating in this file that are not fixed by this commit.
1 parent d41fb46 commit 218a933

File tree

2 files changed

+49
-22
lines changed

2 files changed

+49
-22
lines changed

newrelic/api/import_hook.py

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

1919
_logger = logging.getLogger(__name__)
2020

21-
try:
22-
from importlib import find_loader
23-
except ImportError:
24-
find_loader = None
25-
2621
_import_hooks = {}
2722

2823
_ok_modules = (
@@ -173,25 +168,14 @@ def find_module(self, fullname, path=None):
173168
self._skip[fullname] = True
174169

175170
try:
176-
# For Python 3 we need to use find_loader() from the new
177-
# importlib module.
178-
179-
if find_loader:
180-
loader = find_loader(fullname, path)
181-
182-
if loader:
183-
return _ImportHookChainedLoader(loader)
184-
185-
else:
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:
186177
__import__(fullname)
187-
188-
# If we get this far then the module we are
189-
# interested in does actually exist and so return
190-
# our loader to trigger import hooks and then return
191-
# the module.
192-
193178
return _ImportHookLoader()
194-
195179
finally:
196180
del self._skip[fullname]
197181

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from pytest import raises
2+
3+
4+
def test_import_hook_finder():
5+
"""
6+
This asserts the behavior of ImportHookFinder.find_module. It behaves
7+
differently depending on whether or not the module it is looking for
8+
exists, has been registered with an import hook, and across different
9+
python versions.
10+
"""
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()
17+
18+
# a dummy hook just to be able to register hooks for modules
19+
def hook(*args, **kwargs):
20+
pass
21+
22+
# Finding a module that does not exist and is not registered returns None.
23+
module = finder.find_module('some_module_that_does_not_exist')
24+
assert module is None
25+
26+
# Finding a module that does not exist and is registered behaves
27+
# 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')
32+
else:
33+
module = finder.find_module('some_module_that_does_not_exist')
34+
assert module is None
35+
36+
# Finding a module that exists, but is not registered returns None.
37+
module = finder.find_module('newrelic')
38+
assert module is None
39+
40+
# Finding a module that exists, and is registered, finds that module.
41+
register_import_hook('newrelic', hook)
42+
module = finder.find_module('newrelic')
43+
assert module is not None

0 commit comments

Comments
 (0)