Skip to content

Commit

Permalink
Handle change to plugin loading in recent yapsy (#3700) (#3701)
Browse files Browse the repository at this point in the history
tibonihoo/yapsy#11 changes yapsy plugin
loading to not use the deprecated imp module any more. However,
as a side effect of that, it breaks this already-kinda-ugly
hack, and we have to make it even uglier!

yapsy used to import the module like this:

imp.load_module(plugin_module_name,plugin_file...)

where `plugin_module_name` was the modified, "unique" name it
creates early in `loadPlugins`. Interestingly, when you import
a module like that, it gets added to `sys.modules` under *both*
the modified name and its 'real' name, viz:

>>> import sys
>>> import imp
>>> imp.load_module("someothername", None, "/usr/lib/python3.12/site-packages/yapsy/__init__.py", ("py", "r", imp.PKG_DIRECTORY))
<module 'someothername' from '/usr/lib/python3.12/site-packages/yapsy/__init__.py'>
>>> sys.modules["someothername"]
<module 'someothername' from '/usr/lib/python3.12/site-packages/yapsy/__init__.py'>
>>> sys.modules["yapsy"]
<module 'yapsy' from '/usr/lib/python3.12/site-packages/yapsy/__init__.py'>

That's why this hack worked. However, now yapsy imports the
module using importlib, then adds it to `sys.modules` itself,
*only* under the modified "unique" name, not under its original
name. So sys.modules["unmodifiedpluginname"] is now a KeyError.

I can't think of a less ugly fix than this, unfortunately. We
*could* try sending a patch for yapsy to add it under both the
modified and unmodified names, but that would be somewhat tricky
in yapsy's design, and I also suspect yapsy would consider it
to actually be unwanted behavior.

Maybe what we really need is to send a patch for yapsy to just
provide an interface to find a plugin's filesystem path...

Signed-off-by: Adam Williamson <[email protected]>
  • Loading branch information
AdamWill committed Jul 15, 2023
1 parent 69a633f commit 4f51e2e
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion nikola/plugin_categories.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,31 @@ def set_site(self, site):
def inject_templates(self):
"""Inject 'templates/<engine>' (if exists) very early in the theme chain."""
try:
mod_candidate = None
# since https://github.com/tibonihoo/yapsy/pull/11 ,
# yapsy only adds each imported plugin to sys.modules
# under its modified, "unique" name (see early in
# PluginManager.loadPlugins), so we recreate the
# modified name here to find it. we fudge the serial
# number here, assuming that if a plugin is loaded
# under the same name multiple times, the location
# will also be the same, so we can just use 0.
possible_names = (
self.__class__.__module__,
"yapsy_loaded_plugin_" + self.__class__.__module__ + "_0",
"yapsy_loaded_plugin_" + self.name + "_0",
)
for possible_name in possible_names:
mod_candidate = sys.modules.get(possible_name)
if mod_candidate:
break
if not mod_candidate:
# well, we tried. we wind up here for the dummy
# plugins; honestly I'm not sure exactly why/how,
# but they don't have templates, so it's okay
return
# Sorry, found no other way to get this
mod_path = sys.modules[self.__class__.__module__].__file__
mod_path = mod_candidate.__file__
mod_dir = os.path.dirname(mod_path)
tmpl_dir = os.path.join(
mod_dir, 'templates', self.site.template_system.name
Expand Down

0 comments on commit 4f51e2e

Please sign in to comment.