From 2ac63f53f622f5b0434550b6f7489a5a7d3a7707 Mon Sep 17 00:00:00 2001 From: Frederik Ring Date: Sun, 3 Jan 2021 19:46:57 +0100 Subject: [PATCH] refactor: move code to plugins module, infer better names for modules --- pelican/__init__.py | 8 +++++--- pelican/plugins/_utils.py | 20 ++++++++++++++++++++ pelican/settings.py | 12 ------------ pelican/tests/test_plugins.py | 13 +++++++++++-- pelican/tests/test_settings.py | 13 ++----------- 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/pelican/__init__.py b/pelican/__init__.py index b5ba46af..e91e634d 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -20,10 +20,10 @@ from pelican.generators import (ArticlesGenerator, # noqa: I100 PagesGenerator, SourceFileGenerator, StaticGenerator, TemplatePagesGenerator) from pelican.plugins import signals -from pelican.plugins._utils import load_plugins +from pelican.plugins._utils import load_plugins, stringify_plugins from pelican.readers import Readers from pelican.server import ComplexHTTPRequestHandler, RootedHTTPServer -from pelican.settings import coerce_overrides, read_settings, stringify_plugins +from pelican.settings import coerce_overrides, read_settings from pelican.utils import (FileSystemWatcher, clean_output_dir, maybe_pluralize) from pelican.writers import Writer @@ -73,7 +73,9 @@ class Pelican: except Exception as e: logger.error('Cannot register plugin `%s`\n%s', plugin.__name__, e) - stringify_plugins(self.settings) + + if 'PLUGINS' in self.settings and self.settings['PLUGINS'] is not None: + self.settings['PLUGINS'] = stringify_plugins(self.settings['PLUGINS']) def run(self): """Run the generators and return""" diff --git a/pelican/plugins/_utils.py b/pelican/plugins/_utils.py index ffe32799..563246e6 100644 --- a/pelican/plugins/_utils.py +++ b/pelican/plugins/_utils.py @@ -1,6 +1,7 @@ import importlib import importlib.machinery import importlib.util +import inspect import logging import pkgutil import sys @@ -107,3 +108,22 @@ def load_plugins(settings): plugins = list(namespace_plugins.values()) return plugins + + +def stringify_plugins(plugins): + """ + Plugins can be passed as module objects, however this breaks caching as + module objects cannot be pickled. To work around this, we stringify all + plugin definitions post-initialization. + """ + return [_stringify_plugin(p) for p in plugins] + + +def _stringify_plugin(plugin): + if isinstance(plugin, str): + return plugin + + if inspect.isclass(plugin): + return plugin.__name__ + + return plugin.__class__.__qualname__ diff --git a/pelican/settings.py b/pelican/settings.py index 1762b400..ea3ee8eb 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -681,15 +681,3 @@ def coerce_overrides(overrides): 'load as json', k, v) coerced[k] = json.loads(v) return coerced - - -def stringify_plugins(settings): - """ - Plugins can be passed as module objects, however this breaks caching as - module objects cannot be pickled. To work around this, we stringify all - plugin definitions post-initialization. - """ - if 'PLUGINS' in settings and settings['PLUGINS'] is not None: - settings['PLUGINS'] = [str(p) for p in settings['PLUGINS']] - - return settings diff --git a/pelican/tests/test_plugins.py b/pelican/tests/test_plugins.py index 29729539..7842d677 100644 --- a/pelican/tests/test_plugins.py +++ b/pelican/tests/test_plugins.py @@ -1,8 +1,9 @@ import os from contextlib import contextmanager -from pelican.plugins._utils import get_namespace_plugins, load_plugins -from pelican.tests.support import unittest +from pelican.plugins._utils import (get_namespace_plugins, load_plugins, + stringify_plugins) +from pelican.tests.support import NoopPlugin, unittest @contextmanager @@ -172,3 +173,11 @@ class PluginTest(unittest.TestCase): self.assertEqual( {'normal plugin', 'namespace plugin'}, get_plugin_names(plugins)) + + def test_stringify_plugins(self): + result = stringify_plugins(['string_plugin', NoopPlugin()]) + # Plugins are converted to string references + self.assertCountEqual( + ['string_plugin', 'NoopPlugin'], + result + ) diff --git a/pelican/tests/test_settings.py b/pelican/tests/test_settings.py index 69d47bf5..83203ae5 100644 --- a/pelican/tests/test_settings.py +++ b/pelican/tests/test_settings.py @@ -8,9 +8,8 @@ from sys import platform from pelican.settings import (DEFAULT_CONFIG, DEFAULT_THEME, _printf_s_to_format_field, coerce_overrides, configure_settings, - handle_deprecated_settings, read_settings, - stringify_plugins) -from pelican.tests.support import NoopPlugin, unittest + handle_deprecated_settings, read_settings) +from pelican.tests.support import unittest class TestSettingsConfiguration(unittest.TestCase): @@ -320,11 +319,3 @@ class TestSettingsConfiguration(unittest.TestCase): 'THEME_STATIC_DIR': 'theme', } self.assertDictEqual(overrides, expected) - - def test_stringify_plugins(self): - settings = { - 'PLUGINS': ['string_plugin', NoopPlugin] - } - stringify_plugins(settings) - # Plugins are converted to string references - self.assertTrue(all(str(p) == p for p in settings['PLUGINS']))