fix: stringify plugin definitions so they can be pickled during caching

This commit is contained in:
Frederik Ring 2021-01-03 11:29:42 +01:00
commit 36c1e1a12f
4 changed files with 30 additions and 3 deletions

View file

@ -23,7 +23,7 @@ from pelican.plugins import signals
from pelican.plugins._utils import load_plugins
from pelican.readers import Readers
from pelican.server import ComplexHTTPRequestHandler, RootedHTTPServer
from pelican.settings import coerce_overrides, read_settings
from pelican.settings import coerce_overrides, read_settings, stringify_plugins
from pelican.utils import (FileSystemWatcher, clean_output_dir, maybe_pluralize)
from pelican.writers import Writer
@ -73,6 +73,7 @@ class Pelican:
except Exception as e:
logger.error('Cannot register plugin `%s`\n%s',
plugin.__name__, e)
stringify_plugins(self.settings)
def run(self):
"""Run the generators and return"""

View file

@ -681,3 +681,15 @@ 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

View file

@ -193,6 +193,11 @@ def get_context(settings=None, **kwargs):
return context
class NoopPlugin:
def register(self):
pass
class LogCountHandler(BufferingHandler):
"""Capturing and counting logged messages."""

View file

@ -8,8 +8,9 @@ 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)
from pelican.tests.support import unittest
handle_deprecated_settings, read_settings,
stringify_plugins)
from pelican.tests.support import NoopPlugin, unittest
class TestSettingsConfiguration(unittest.TestCase):
@ -319,3 +320,11 @@ 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']))