Skip to content

Commit f02d43a

Browse files
test: Import integrations with empty shadow modules
1 parent 7b7ea33 commit f02d43a

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

tests/test_shadowed_module.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import sys
2+
import ast
3+
import types
4+
import pkgutil
5+
import importlib
6+
import pathlib
7+
import pytest
8+
9+
from sentry_sdk import integrations
10+
from sentry_sdk.integrations import _DEFAULT_INTEGRATIONS, Integration
11+
12+
13+
def unrecognized_dependencies(tree):
14+
"""
15+
Finds unrecognized imports in the AST for a Python module. In an empty
16+
environment, the set of non-standard library modules are returned.
17+
"""
18+
unrecognized_dependency = set()
19+
package_name = lambda name: name.split(".")[0]
20+
21+
for node in ast.walk(tree):
22+
if isinstance(node, ast.Import):
23+
for alias in node.names:
24+
root = package_name(alias.name)
25+
26+
try:
27+
if not importlib.util.find_spec(root):
28+
unrecognized_dependency.add(root)
29+
except ValueError:
30+
continue
31+
32+
elif isinstance(node, ast.ImportFrom):
33+
# if node.level is not 0 the import is relative
34+
if node.level > 0 or node.module is None:
35+
continue
36+
37+
root = package_name(node.module)
38+
39+
try:
40+
if not importlib.util.find_spec(root):
41+
unrecognized_dependency.add(root)
42+
except ValueError:
43+
continue
44+
45+
return unrecognized_dependency
46+
47+
48+
def test_shadowed_module(sentry_init):
49+
"""
50+
Check that importing integrations for third-party module raises an
51+
DidNotEnable exception when the associated module is shadowed by an empty
52+
module.
53+
54+
An integration is determined to be for a third-party module if it cannot
55+
be imported in the environment in which the tests run.
56+
"""
57+
for _, submodule_name, _ in pkgutil.walk_packages(integrations.__path__):
58+
module_path = f"sentry_sdk.integrations.{submodule_name}"
59+
60+
try:
61+
importlib.import_module(module_path)
62+
continue
63+
except integrations.DidNotEnable:
64+
spec = importlib.util.find_spec(module_path)
65+
source = pathlib.Path(spec.origin).read_text(encoding="utf-8")
66+
tree = ast.parse(source, filename=spec.origin)
67+
integration_dependencies = unrecognized_dependencies(tree)
68+
for dependency in integration_dependencies:
69+
sys.modules[dependency] = types.ModuleType(dependency)
70+
with pytest.raises(integrations.DidNotEnable):
71+
importlib.import_module(module_path)

0 commit comments

Comments
 (0)