Repository: django-wiki/django-wiki

Issue:
Possible memory leak in markdown extensions
When looking at an error log from our project using django-wiki, we noticed a kind of _possibly longer than necessary_ value of django setting WIKI_MARKDOWN_KWARGS.. 

It seems that each of the extension is appended to the 'extensions' array multiple times and I think that it should be enough for each extension to be there only once. When looking for a cause, I've found this piece of code, that appends the extensions to the global extensions array in django settings every time it is called... 
https://github.com/django-wiki/django-wiki/blob/master/wiki/core/markdown/__init__.py#L26

for reference, this is how it looked in our error log:

```
Settings:
[...]
WIKI_MARKDOWN_KWARGS = {'extension_configs': {'toc': {'title': <django.utils.functional.__proxy__ object at 0x7f6d36b67850>}, 'pymdownx.github': {'no_nl2br': True}}, 'extensions': ['pymdownx.github', 'attr_list', 'codehilite', 'sane_lists', 'footnotes', 'wikilinks', <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d3956c290>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d3956c990>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d395da790>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d396d67d0>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d396d6dd0>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d396d6050>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d396f1bd0>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d396f1c10>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d3978ca50>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d3978cc50>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d395b48d0>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d395b46d0>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39791050>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39795d50>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39775d10>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d3977a5d0>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d396e2590>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d396e2b10>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d396f4ad0>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d396f4f90>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39334590>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39334c50>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d396f9510>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d396f9f90>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d395d2410>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d395d2a90>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d397d0a50>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39790f10>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39c05510>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39c05710>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39be38d0>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39be3710>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d3948c990>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d3948cd10>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39a25810>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39a25850>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39d78d90>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39d78d10>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39ba7f10>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39ba7250>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39d42bd0>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39d42f90>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39b33e90>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39b33050>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>, <wiki.core.markdown.mdx.previewlinks.PreviewLinksExtension object at 0x7f6d39c042d0>, <wiki.core.markdown.mdx.responsivetable.ResponsiveTableExtension object at 0x7f6d39c04290>, <wiki.plugins.attachments.markdown_extensions.AttachmentExtension object at 0x7f6d38c90710>, <wiki.plugins.images.markdown_extensions.ImageExtension object at 0x7f6d38ca2410>, <wiki.plugins.macros.mdx.wikilinks.WikiLinkExtension object at 0x7f6d38ca2f10>, <wiki.plugins.macros.mdx.macro.MacroExtension object at 0x7f6d38ca2d50>, <wiki.plugins.macros.mdx.toc.WikiTocExtension object at 0x7f6d38ca2fd0>], 'output_format': 'html5', 'safe_mode': False}
```



Discussion:
Thanks for reporting the issue. 

I'll fix it right away. 


Resolving patch:
diff --git a/wiki/core/markdown/__init__.py b/wiki/core/markdown/__init__.py
--- a/wiki/core/markdown/__init__.py
+++ b/wiki/core/markdown/__init__.py
@@ -22,7 +22,7 @@ def core_extensions(self):
 
     def get_markdown_extensions(self):
         kwargs = settings.MARKDOWN_KWARGS
-        extensions = kwargs.get('extensions', [])
+        extensions = list(kwargs.get('extensions', []))
         extensions += self.core_extensions()
         extensions += plugin_registry.get_markdown_extensions()
         return extensions


Test patch:
diff --git a/wiki/tests/test_markdown.py b/wiki/tests/test_markdown.py
--- a/wiki/tests/test_markdown.py
+++ b/wiki/tests/test_markdown.py
@@ -2,7 +2,18 @@
 
 from django.test import TestCase
 import markdown
+from wiki.core.markdown import ArticleMarkdown
 from wiki.core.markdown.mdx.responsivetable import ResponsiveTableExtension
+from mock import patch
+
+class ArticleMarkdownTests(TestCase):
+    @patch('wiki.core.markdown.settings')
+    def test_do_not_modify_extensions(self, settings):
+        extensions = ['footnotes', 'attr_list', 'sane_lists']
+        settings.MARKDOWN_KWARGS = {'extensions': extensions}
+        number_of_extensions = len(extensions)
+        ArticleMarkdown(None)
+        self.assertEqual(len(extensions), number_of_extensions)
 
 class ResponsiveTableTests(TestCase):
     def setUp(self):