Skip to content

Commit

Permalink
plugins.handlers: improve robustness of plugin version lookup
Browse files Browse the repository at this point in the history
Co-authored-by: Florian Strzelecki <[email protected]>
  • Loading branch information
SnoopJ and Exirel committed Oct 31, 2024
1 parent 2e8de02 commit 8d6853e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
22 changes: 16 additions & 6 deletions sopel/plugins/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import importlib.util
import inspect
import itertools
import logging
import os
import sys
from typing import Optional, TYPE_CHECKING, TypedDict
Expand All @@ -61,6 +62,9 @@
from types import ModuleType


LOGGER = logging.getLogger(__name__)


class PluginMetaDescription(TypedDict):
"""Meta description of a plugin, as a dictionary.
Expand Down Expand Up @@ -620,14 +624,20 @@ def get_version(self) -> Optional[str]:

if (
version is None
and hasattr(self.module, "__package__")
and self.module.__package__ is not None
and hasattr(self.entry_point, "dist")
and hasattr(self.entry_point.dist, "name")
):
dist_name = self.entry_point.dist.name
try:
version = importlib.metadata.version(self.module.__package__)
except ValueError:
# package name is probably empty-string; just give up
pass
version = importlib.metadata.version(dist_name)
except (ValueError, importlib.metadata.PackageNotFoundError):
LOGGER.warning("Cannot determine version of %r", dist_name)
except Exception:
LOGGER.warning(
"Unexpected error occurred while checking the version of %r",
dist_name,
exc_info=True,
)

return version

Expand Down
18 changes: 18 additions & 0 deletions test/plugins/test_plugins_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,21 @@ def test_folder_plugin_imports(plugin_folder):
handler = handlers.PyFilePlugin(plugin_folder)
handler.load()
assert handler.module.foo == 'bar baz'


def test_get_version_entrypoint_package_does_not_match(plugin_tmpfile):
# See gh-2593, wherein an entrypoint plugin whose project/package names
# are not equal raised an exception that propagated too far
distrib_dir = os.path.dirname(plugin_tmpfile.strpath)
sys.path.append(distrib_dir)

try:
entry_point = importlib.metadata.EntryPoint(
'test_plugin', 'file_mod', 'sopel.plugins')
plugin = handlers.EntryPointPlugin(entry_point)
plugin.load()
plugin.module.__package__ = "FAKEFAKEFAKE"
# Under gh-2593, this call raises a PackageNotFound error
assert plugin.get_version() is None
finally:
sys.path.remove(distrib_dir)

0 comments on commit 8d6853e

Please sign in to comment.