diff --git a/sentry_sdk/integrations/modules.py b/sentry_sdk/integrations/modules.py index c9066ebda6..76d55c8bbe 100644 --- a/sentry_sdk/integrations/modules.py +++ b/sentry_sdk/integrations/modules.py @@ -18,15 +18,30 @@ _installed_modules = None +def _normalize_module_name(name): + # type: (str) -> str + return name.lower() + + def _generate_installed_modules(): # type: () -> Iterator[Tuple[str, str]] try: - import pkg_resources - except ImportError: - return + from importlib.metadata import distributions, version - for info in pkg_resources.working_set: - yield info.key, info.version + for dist in distributions(): + yield _normalize_module_name(dist.metadata["Name"]), version( + dist.metadata["Name"] + ) + + except ImportError: + # < py3.8 + try: + import pkg_resources + except ImportError: + return + + for info in pkg_resources.working_set: + yield _normalize_module_name(info.key), info.version def _get_installed_modules(): diff --git a/tests/integrations/modules/test_modules.py b/tests/integrations/modules/test_modules.py index 3f4d7bd9dc..bc108f9fb1 100644 --- a/tests/integrations/modules/test_modules.py +++ b/tests/integrations/modules/test_modules.py @@ -1,6 +1,10 @@ import sentry_sdk -from sentry_sdk.integrations.modules import ModulesIntegration +from sentry_sdk.integrations.modules import ( + ModulesIntegration, + _get_installed_modules, + _normalize_module_name, +) def test_basic(sentry_init, capture_events): @@ -12,3 +16,45 @@ def test_basic(sentry_init, capture_events): (event,) = events assert "sentry-sdk" in event["modules"] assert "pytest" in event["modules"] + + +def test_installed_modules(): + try: + from importlib import distributions, version + + importlib_available = True + except ImportError: + importlib_available = False + + try: + import pkg_resources + + pkg_resources_available = True + except ImportError: + pkg_resources_available = False + + installed_modules = _get_installed_modules() + + # This one package is reported differently by importlib + # and pkg_resources, but we don't really care, so let's + # just ignore it + installed_modules.pop("typing-extensions", None) + installed_modules.pop("typing_extensions", None) + + if importlib_available: + importlib_modules = { + _normalize_module_name(dist.metadata["Name"]): version( + dist.metadata["Name"] + ) + for dist in distributions() + } + importlib_modules.pop("typing-extensions", None) + assert installed_modules == importlib_modules + + if pkg_resources_available: + pkg_resources_modules = { + _normalize_module_name(dist.key): dist.version + for dist in pkg_resources.working_set + } + pkg_resources_modules.pop("typing-extensions", None) + assert installed_modules == pkg_resources_modules diff --git a/tests/integrations/pyramid/test_pyramid.py b/tests/integrations/pyramid/test_pyramid.py index 01dd1c6a04..9fc15c052f 100644 --- a/tests/integrations/pyramid/test_pyramid.py +++ b/tests/integrations/pyramid/test_pyramid.py @@ -1,8 +1,6 @@ import json import logging -import pkg_resources import pytest - from io import BytesIO import pyramid.testing @@ -17,9 +15,18 @@ from werkzeug.test import Client -PYRAMID_VERSION = tuple( - map(int, pkg_resources.get_distribution("pyramid").version.split(".")) -) +try: + from importlib.metadata import version + + PYRAMID_VERSION = tuple(map(int, version("pyramid").split("."))) + +except ImportError: + # < py3.8 + import pkg_resources + + PYRAMID_VERSION = tuple( + map(int, pkg_resources.get_distribution("pyramid").version.split(".")) + ) def hi(request):