_importlib_metadata.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. # Copyright The OpenTelemetry Authors
  2. # SPDX-License-Identifier: Apache-2.0
  3. """
  4. Caching and compatibility wrapper for standard library ``importlib.metadata``.
  5. This module caches ``entry_points()`` to avoid reloading entry points from disk on every call.
  6. It also normalizes minor differences across python versions 3.10+. References to issues:
  7. - https://github.com/open-telemetry/opentelemetry-python/pull/4735
  8. - https://github.com/open-telemetry/opentelemetry-python/pull/5203
  9. """
  10. import itertools
  11. from functools import cache
  12. from importlib.metadata import (
  13. Distribution,
  14. EntryPoint,
  15. EntryPoints,
  16. PackageNotFoundError,
  17. distributions,
  18. requires,
  19. version,
  20. )
  21. from importlib.metadata import entry_points as original_entry_points
  22. from typing import Any
  23. def _as_entry_points(eps: Any) -> EntryPoints:
  24. # Python versions greater than 3.11 return EntryPoints.
  25. if isinstance(eps, EntryPoints):
  26. return eps
  27. # In Python 3.10 and 3.11 entry_points() returns
  28. # a dict-like SelectableGroups object.
  29. # Use dict.values() instead of eps.values() to avoid the DeprecationWarning
  30. # that SelectableGroups raises when calling .values().
  31. if isinstance(eps, dict):
  32. return EntryPoints(itertools.chain.from_iterable(dict.values(eps)))
  33. # This case should be unreachable, but is included as a fallback.
  34. return EntryPoints(
  35. ep for group in eps.groups for ep in eps.select(group=group)
  36. )
  37. @cache
  38. def _original_entry_points_cached() -> EntryPoints:
  39. return _as_entry_points(original_entry_points())
  40. def entry_points(**params) -> EntryPoints:
  41. return _original_entry_points_cached().select(**params)
  42. __all__ = [
  43. "entry_points",
  44. "version",
  45. "EntryPoint",
  46. "EntryPoints",
  47. "requires",
  48. "Distribution",
  49. "distributions",
  50. "PackageNotFoundError",
  51. ]