From 92ab6de74c88cda477adf7fda045d9a0c2b73d97 Mon Sep 17 00:00:00 2001
From: dgw <dgw@technobabbl.es>
Date: Sun, 10 Nov 2024 17:33:07 -0600
Subject: [PATCH] Backport entrypoint version check using dist name from #2594
 to 8.0.1

---
 sopel/plugins/handlers.py             | 22 ++++++++++++++++------
 test/plugins/test_plugins_handlers.py | 18 ++++++++++++++++++
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/sopel/plugins/handlers.py b/sopel/plugins/handlers.py
index 9216b7a53..eee1c056d 100644
--- a/sopel/plugins/handlers.py
+++ b/sopel/plugins/handlers.py
@@ -48,6 +48,7 @@
 import importlib.util
 import inspect
 import itertools
+import logging
 import os
 import sys
 from typing import Optional, TYPE_CHECKING, TypedDict
@@ -61,6 +62,9 @@
     from types import ModuleType
 
 
+LOGGER = logging.getLogger(__name__)
+
+
 class PluginMetaDescription(TypedDict):
     """Meta description of a plugin, as a dictionary.
 
@@ -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
 
diff --git a/test/plugins/test_plugins_handlers.py b/test/plugins/test_plugins_handlers.py
index 15546d14d..67a2d6034 100644
--- a/test/plugins/test_plugins_handlers.py
+++ b/test/plugins/test_plugins_handlers.py
@@ -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)