aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--docs/release-2.5.txt5
-rw-r--r--markdown/__init__.py38
-rwxr-xr-xsetup.py1
-rw-r--r--tests/test_apis.py25
-rw-r--r--tox.ini2
6 files changed, 45 insertions, 27 deletions
diff --git a/.travis.yml b/.travis.yml
index 1931a20..e912c73 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,5 @@
language: python
env:
- - TOXENV=py26
- TOXENV=py27
- TOXENV=py32
- TOXENV=py33
diff --git a/docs/release-2.5.txt b/docs/release-2.5.txt
index 0d895bb..eb9c44c 100644
--- a/docs/release-2.5.txt
+++ b/docs/release-2.5.txt
@@ -10,11 +10,14 @@ Python-Markdown 2.5 Release Notes
We are pleased to release Python-Markdown 2.5 which adds a few new features
and fixes various bugs. See the list of changes below for details.
-Python-Markdown supports Python versions 2.6, 2.7, 3.2, 3.3, and 3.4.
+Python-Markdown supports Python versions 2.7, 3.2, 3.3, and 3.4.
Backwards-incompatible Changes
------------------------------
+* Python-Markdown no longer supports Python version 2.6. You must be using Python 2.7+
+or Python-Markdown 2.5 will not load.
+
* The `force_linenos` config key on the [CodeHilite Extension] has been deprecated
and will raise a `KeyError` if provided. In the previous release (2.4), it was issuing
a `DeprecationWarning`. The [`linenums`][linenums] keyword should be used instead,
diff --git a/markdown/__init__.py b/markdown/__init__.py
index 59dda4c..6190dd2 100644
--- a/markdown/__init__.py
+++ b/markdown/__init__.py
@@ -36,6 +36,7 @@ from .__version__ import version, version_info
import codecs
import sys
import logging
+import importlib
from . import util
from .preprocessors import build_preprocessors
from .blockprocessors import build_block_parser
@@ -163,6 +164,8 @@ class Markdown(object):
ext = self.build_extension(ext, configs.get(ext, []))
if isinstance(ext, Extension):
ext.extendMarkdown(self, globals())
+ logger.info('Successfully loaded extension "%s.%s".'
+ % (ext.__class__.__module__, ext.__class__.__name__))
elif ext is not None:
raise TypeError(
'Extension "%s.%s" must be of type: "markdown.Extension"'
@@ -187,23 +190,28 @@ class Markdown(object):
pairs = [x.split("=") for x in ext_args.split(",")]
configs.update([(x.strip(), y.strip()) for (x, y) in pairs])
- # Setup the module name
- module_name = ext_name
- if '.' not in ext_name:
- module_name = '.'.join(['markdown.extensions', ext_name])
-
# Try loading the extension first from one place, then another
- try: # New style (markdown.extensions.<extension>)
- module = __import__(module_name, {}, {}, [str(module_name.rpartition('.')[0])])
+ try:
+ # Assume string uses dot syntax (`path.to.some.module`)
+ module = importlib.import_module(ext_name)
+ logger.debug('Successfuly imported extension module "%s".' % ext_name)
except ImportError:
- module_name_old_style = '_'.join(['mdx', ext_name])
- try: # Old style (mdx_<extension>)
- module = __import__(module_name_old_style)
- except ImportError as e:
- message = "Failed loading extension '%s' from '%s' or '%s'" \
- % (ext_name, module_name, module_name_old_style)
- e.args = (message,) + e.args[1:]
- raise
+ # Preppend `markdown.extensions.` to name
+ module_name = '.'.join(['markdown.extensions', ext_name])
+ try:
+ module = importlib.import_module(module_name)
+ logger.debug('Successfuly imported extension module "%s".' % module_name)
+ except ImportError:
+ # Preppend `mdx_` to name
+ module_name_old_style = '_'.join(['mdx', ext_name])
+ try:
+ module = importlib.import_module(module_name_old_style)
+ logger.debug('Successfuly imported extension module "%s".' % module_name_old_style)
+ except ImportError as e:
+ message = "Failed loading extension '%s' from '%s', '%s' or '%s'" \
+ % (ext_name, ext_name, module_name, module_name_old_style)
+ e.args = (message,) + e.args[1:]
+ raise
# If the module is loaded successfully, we expect it to define a
# function called makeExtension()
diff --git a/setup.py b/setup.py
index 568e8c5..f635b48 100755
--- a/setup.py
+++ b/setup.py
@@ -235,7 +235,6 @@ setup(
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
diff --git a/tests/test_apis.py b/tests/test_apis.py
index a5e0d73..f0c7f3d 100644
--- a/tests/test_apis.py
+++ b/tests/test_apis.py
@@ -276,24 +276,33 @@ class TestErrors(unittest.TestCase):
def testLoadBadExtension(self):
""" Test loading of an Extension with no makeExtension function. """
- _create_fake_extension(name='fake', has_factory_func=False)
- self.assertRaises(AttributeError, markdown.Markdown, extensions=['fake'])
+ _create_fake_extension(name='fake_a', has_factory_func=False)
+ self.assertRaises(AttributeError, markdown.Markdown, extensions=['fake_a'])
def testNonExtension(self):
""" Test loading a non Extension object as an extension. """
- _create_fake_extension(name='fake', is_wrong_type=True)
- self.assertRaises(TypeError, markdown.Markdown, extensions=['fake'])
+ _create_fake_extension(name='fake_b', is_wrong_type=True)
+ self.assertRaises(TypeError, markdown.Markdown, extensions=['fake_b'])
def testBaseExtention(self):
""" Test that the base Extension class will raise NotImplemented. """
- _create_fake_extension(name='fake')
+ _create_fake_extension(name='fake_c')
self.assertRaises(NotImplementedError,
- markdown.Markdown, extensions=['fake'])
+ markdown.Markdown, extensions=['fake_c'])
+
+ def testDotSyntaxExtention(self):
+ """ Test that dot syntax imports properly (not using mdx_). """
+ _create_fake_extension(name='fake_d', use_old_style=False)
+ self.assertRaises(NotImplementedError,
+ markdown.Markdown, extensions=['fake_d'])
-def _create_fake_extension(name, has_factory_func=True, is_wrong_type=False):
+def _create_fake_extension(name, has_factory_func=True, is_wrong_type=False, use_old_style=True):
""" Create a fake extension module for testing. """
- mod_name = '_'.join(['mdx', name])
+ if use_old_style:
+ mod_name = '_'.join(['mdx', name])
+ else:
+ mod_name = name
if not PY3:
# mod_name must be bytes in Python 2.x
mod_name = bytes(mod_name)
diff --git a/tox.ini b/tox.ini
index 7968fba..5ccefce 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py26, py27, py31, py32, py33, py34
+envlist = py27, py31, py32, py33, py34
[testenv]
downloadcache = {toxworkdir}/cache