From 068e97f43f8d4d59441ba05315e768a3526f6bfe Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Fri, 7 Jun 2024 09:38:18 +0200 Subject: [PATCH] Add an unregister method to renderers --- CHANGELOG.rst | 4 ++ feincms3/renderer.py | 17 ++++++ tests/testapp/test_region_renderer.py | 76 +++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index abbb9d1..6e1aad6 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,10 @@ Change log Next version ~~~~~~~~~~~~ +- Added ``RegionRenderer.copy()`` and ``RegionRenderer.unregister`` methods to + allow modifying existing renderers without having to reach into internal + attributes. + 5.1 (2024-06-06) ~~~~~~~~~~~~~~~~ diff --git a/feincms3/renderer.py b/feincms3/renderer.py index ce4081c..40ee11f 100644 --- a/feincms3/renderer.py +++ b/feincms3/renderer.py @@ -108,6 +108,23 @@ def copy(self): obj._marks = dict(self._marks) return obj + def unregister(self, *plugins, keep=()): + if bool(plugins) == bool(keep): + raise ImproperlyConfigured( + "Only ever provide either a list of plugins or a list of plugins to keep." + ) + + test = ( + (lambda cls: not issubclass(cls, plugins)) + if plugins + else (lambda cls: issubclass(cls, tuple(keep))) + ) + + self._fetch = [p for p in self._fetch if test(p)] + self._renderers = {p: r for p, r in self._renderers.items() if test(p)} + self._subregions = {p: s for p, s in self._subregions.items() if test(p)} + self._marks = {p: m for p, m in self._marks.items() if test(p)} + def register( self, plugin, diff --git a/tests/testapp/test_region_renderer.py b/tests/testapp/test_region_renderer.py index 67e0e3a..671a41a 100644 --- a/tests/testapp/test_region_renderer.py +++ b/tests/testapp/test_region_renderer.py @@ -147,3 +147,79 @@ def test_invalid_renderer(self): ImproperlyConfigured, r"has less than the two required arguments" ): r.register(1, lambda plugin: "") + + def test_register_unregister(self): + richtext_renderer = template_renderer("renderer/richtext.html") + html_renderer = template_renderer("renderer/html.html") + + renderer = RegionRenderer() + renderer.register(RichText, richtext_renderer) + renderer.register(HTML, html_renderer) + + r2 = renderer.copy() + r2.unregister(RichText) + + r3 = renderer.copy() + r3.unregister(keep=[HTML]) + + self.assertEqual(renderer._fetch, [RichText, HTML]) + self.assertEqual( + renderer._renderers, + { + RichText: richtext_renderer, + HTML: html_renderer, + }, + ) + self.assertEqual( + renderer._subregions, + {RichText: "default", HTML: "default"}, + ) + self.assertEqual( + renderer._subregions, + {RichText: "default", HTML: "default"}, + ) + self.assertEqual( + renderer._marks, + {RichText: {"default"}, HTML: {"default"}}, + ) + + self.assertEqual( + r2._renderers, + { + HTML: html_renderer, + }, + ) + self.assertEqual( + r2._subregions, + {HTML: "default"}, + ) + self.assertEqual( + r2._subregions, + {HTML: "default"}, + ) + self.assertEqual( + r2._marks, + {HTML: {"default"}}, + ) + + self.assertEqual( + r3._renderers, + { + HTML: html_renderer, + }, + ) + self.assertEqual( + r3._subregions, + {HTML: "default"}, + ) + self.assertEqual( + r3._subregions, + {HTML: "default"}, + ) + self.assertEqual( + r3._marks, + {HTML: {"default"}}, + ) + + with self.assertRaises(ImproperlyConfigured): + renderer.unregister(HTML, keep=[RichText])