aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWaylan Limberg <waylan@gmail.com>2014-07-29 21:34:58 -0400
committerWaylan Limberg <waylan@gmail.com>2014-07-29 21:34:58 -0400
commitaae373860b5c5cbb40f126bf5acb9693dc577c4a (patch)
treeb7193438629aa4e1a6e07c229e76198cfb341b85
parenta8396c322a4d836dee399cd3cc3dce0a964fe5c0 (diff)
downloadmarkdown-aae373860b5c5cbb40f126bf5acb9693dc577c4a.tar.gz
markdown-aae373860b5c5cbb40f126bf5acb9693dc577c4a.tar.bz2
markdown-aae373860b5c5cbb40f126bf5acb9693dc577c4a.zip
Refactor markdown.extensions.Extension.__init__()
As pointed out in #325, setting up Extension configs is kind of a mess. Some places pass a list of tuples on initialization, others a dict. And sometimes they're passed as an arg, othertimes a kwarg. Addiitonaly, the docs are just as inconsistant. This refactor addresses all those sinerios with tests included. The existing extensions still need refactored. But the fact that their tests still pass means we havn't broken third party extensions either. This refactor also introduces a new API, which is the prefered method going forward. All docs should be updated to match. Whereas previously one might do: ```python MyExtension(configs={'key': 'foo', 'otherkey': 'bar'}) ``` This can now be done: ```python MyExtension(key='foo', otherkey='bar') ``` Of course, the old way still works for backward compatability. But that means the `configs` keyword has special status and cannot be used for another purpose.
-rw-r--r--markdown/extensions/__init__.py36
-rw-r--r--tests/test_extensions.py31
2 files changed, 59 insertions, 8 deletions
diff --git a/markdown/extensions/__init__.py b/markdown/extensions/__init__.py
index 184c4d1..296ce0c 100644
--- a/markdown/extensions/__init__.py
+++ b/markdown/extensions/__init__.py
@@ -7,14 +7,28 @@ from __future__ import unicode_literals
class Extension(object):
""" Base class for extensions to subclass. """
- def __init__(self, configs = {}):
- """Create an instance of an Extention.
+
+ # Default config -- to be overriden by a subclass
+ # Must be of the following format:
+ # {
+ # 'key': ['value', 'description']
+ # }
+ # Note that Extension.setConfig will raise a KeyError
+ # if a default is not set here.
+ config = {}
+
+ def __init__(self, *args, **kwargs):
+ """ Initiate Extension and set up configs. """
- Keyword arguments:
-
- * configs: A dict of configuration setting used by an Extension.
- """
- self.config = configs
+ # check for configs arg for backward compat.
+ # (there only ever used to be one so we use arg[0])
+ if len(args):
+ self.setConfigs(args[0])
+ # check for configs kwarg for backward compat.
+ self.setConfigs(kwargs.pop('configs', {}))
+ # finally, use kwargs
+ self.setConfigs(kwargs)
+
def getConfig(self, key, default=''):
""" Return a setting for the given key or an empty string. """
@@ -35,6 +49,14 @@ class Extension(object):
""" Set a config setting for `key` with the given `value`. """
self.config[key][0] = value
+ def setConfigs(self, items):
+ """ Set multiple config settings given a dict or list of tuples. """
+ if hasattr(items, 'items'):
+ # it's a dict
+ items = items.items()
+ for key, value in items:
+ self.setConfig(key, value)
+
def extendMarkdown(self, md, md_globals):
"""
Add the various proccesors and patterns to the Markdown Instance.
diff --git a/tests/test_extensions.py b/tests/test_extensions.py
index 8cd6c31..e763576 100644
--- a/tests/test_extensions.py
+++ b/tests/test_extensions.py
@@ -15,12 +15,17 @@ class TestExtensionClass(unittest.TestCase):
""" Test markdown.extensions.Extension. """
def setUp(self):
- self.ext = markdown.extensions.Extension(configs={'foo':['bar', 'Description of foo']})
+ class TestExtension(markdown.extensions.Extension):
+ config = {'foo': ['bar', 'Description of foo']}
+
+ self.ext = TestExtension()
+ self.ExtKlass = TestExtension
def testGetConfig(self):
self.assertEqual(self.ext.getConfig('foo'), 'bar')
def testGetConfigDefault(self):
+ self.assertEqual(self.ext.getConfig('baz'), '')
self.assertEqual(self.ext.getConfig('baz', default='missing'), 'missing')
def testGetConfigs(self):
@@ -33,6 +38,30 @@ class TestExtensionClass(unittest.TestCase):
self.ext.setConfig('foo', 'baz')
self.assertEqual(self.ext.getConfigs(), {'foo': 'baz'})
+ def testSetConfigWithBadKey(self):
+ # self.ext.setConfig('bad', 'baz) ==> KeyError
+ self.assertRaises(KeyError, self.ext.setConfig, 'bad', 'baz')
+
+ def testConfigAsArgListOnInit(self):
+ ext = self.ExtKlass([('foo', 'baz')])
+ self.assertEqual(ext.getConfigs(), {'foo': 'baz'})
+
+ def testConfigAsArgDictOnInit(self):
+ ext = self.ExtKlass({'foo': 'baz'})
+ self.assertEqual(ext.getConfigs(), {'foo': 'baz'})
+
+ def testConfigAsKwargListOnInit(self):
+ ext = self.ExtKlass(configs=[('foo', 'baz')])
+ self.assertEqual(ext.getConfigs(), {'foo': 'baz'})
+
+ def testConfigAsKwargDictOnInit(self):
+ ext = self.ExtKlass(configs={'foo': 'baz'})
+ self.assertEqual(ext.getConfigs(), {'foo': 'baz'})
+
+ def testConfigAsKwargsOnInit(self):
+ ext = self.ExtKlass(foo='baz')
+ self.assertEqual(ext.getConfigs(), {'foo': 'baz'})
+
class TestAbbr(unittest.TestCase):
""" Test abbr extension. """