Add Py2.6 compatibility
This commit is contained in:
parent
abf6cfdb4c
commit
686d87d30f
|
@ -1,6 +1,7 @@
|
|||
# http://travis-ci.org/#!/FSX/misaka
|
||||
language: python
|
||||
python:
|
||||
- 2.6
|
||||
- 2.7
|
||||
- 3.2
|
||||
- 3.3
|
||||
|
|
|
@ -20,7 +20,7 @@ Documentation can be found at: http://misaka.61924.nl/
|
|||
Installation
|
||||
------------
|
||||
|
||||
Misaka has been tested on CPython 2.7, 3.2, 3.3, 3.4, 3.5 and PyPy 2.6. It needs
|
||||
Misaka has been tested on CPython 2.6, 2.7, 3.2, 3.3, 3.4, 3.5 and PyPy 2.6. It needs
|
||||
CFFI 1.0 or newer, because of this it will not work on PyPy 2.5 and older.
|
||||
|
||||
With pip::
|
||||
|
|
50
build_ffi.py
50
build_ffi.py
|
@ -82,33 +82,33 @@ ffi.cdef("""\
|
|||
|
||||
typedef enum hoedown_extensions {{
|
||||
/* block-level extensions */
|
||||
HOEDOWN_EXT_TABLES = {},
|
||||
HOEDOWN_EXT_FENCED_CODE = {},
|
||||
HOEDOWN_EXT_FOOTNOTES = {},
|
||||
HOEDOWN_EXT_AUTOLINK = {},
|
||||
HOEDOWN_EXT_STRIKETHROUGH = {},
|
||||
HOEDOWN_EXT_UNDERLINE = {},
|
||||
HOEDOWN_EXT_HIGHLIGHT = {},
|
||||
HOEDOWN_EXT_QUOTE = {},
|
||||
HOEDOWN_EXT_SUPERSCRIPT = {},
|
||||
HOEDOWN_EXT_MATH = {},
|
||||
HOEDOWN_EXT_NO_INTRA_EMPHASIS = {},
|
||||
HOEDOWN_EXT_SPACE_HEADERS = {},
|
||||
HOEDOWN_EXT_MATH_EXPLICIT = {},
|
||||
HOEDOWN_EXT_DISABLE_INDENTED_CODE = {}
|
||||
HOEDOWN_EXT_TABLES = {0},
|
||||
HOEDOWN_EXT_FENCED_CODE = {1},
|
||||
HOEDOWN_EXT_FOOTNOTES = {2},
|
||||
HOEDOWN_EXT_AUTOLINK = {3},
|
||||
HOEDOWN_EXT_STRIKETHROUGH = {4},
|
||||
HOEDOWN_EXT_UNDERLINE = {5},
|
||||
HOEDOWN_EXT_HIGHLIGHT = {6},
|
||||
HOEDOWN_EXT_QUOTE = {7},
|
||||
HOEDOWN_EXT_SUPERSCRIPT = {8},
|
||||
HOEDOWN_EXT_MATH = {9},
|
||||
HOEDOWN_EXT_NO_INTRA_EMPHASIS = {10},
|
||||
HOEDOWN_EXT_SPACE_HEADERS = {11},
|
||||
HOEDOWN_EXT_MATH_EXPLICIT = {12},
|
||||
HOEDOWN_EXT_DISABLE_INDENTED_CODE = {13}
|
||||
}} hoedown_extensions;
|
||||
|
||||
typedef enum hoedown_list_flags {{
|
||||
HOEDOWN_LIST_ORDERED = {},
|
||||
HOEDOWN_LI_BLOCK = {}
|
||||
HOEDOWN_LIST_ORDERED = {14},
|
||||
HOEDOWN_LI_BLOCK = {15}
|
||||
}} hoedown_list_flags;
|
||||
|
||||
typedef enum hoedown_table_flags {{
|
||||
HOEDOWN_TABLE_ALIGN_LEFT = {},
|
||||
HOEDOWN_TABLE_ALIGN_RIGHT = {},
|
||||
HOEDOWN_TABLE_ALIGN_CENTER = {},
|
||||
HOEDOWN_TABLE_ALIGNMASK = {},
|
||||
HOEDOWN_TABLE_HEADER = {}
|
||||
HOEDOWN_TABLE_ALIGN_LEFT = {16},
|
||||
HOEDOWN_TABLE_ALIGN_RIGHT = {17},
|
||||
HOEDOWN_TABLE_ALIGN_CENTER = {18},
|
||||
HOEDOWN_TABLE_ALIGNMASK = {19},
|
||||
HOEDOWN_TABLE_HEADER = {20}
|
||||
}} hoedown_table_flags;
|
||||
|
||||
// ----------------------
|
||||
|
@ -116,10 +116,10 @@ typedef enum hoedown_table_flags {{
|
|||
// ----------------------
|
||||
|
||||
typedef enum hoedown_html_flags {{
|
||||
HOEDOWN_HTML_SKIP_HTML = {},
|
||||
HOEDOWN_HTML_ESCAPE = {},
|
||||
HOEDOWN_HTML_HARD_WRAP = {},
|
||||
HOEDOWN_HTML_USE_XHTML = {}
|
||||
HOEDOWN_HTML_SKIP_HTML = {21},
|
||||
HOEDOWN_HTML_ESCAPE = {22},
|
||||
HOEDOWN_HTML_HARD_WRAP = {23},
|
||||
HOEDOWN_HTML_USE_XHTML = {24}
|
||||
}} hoedown_html_flags;
|
||||
""".format(
|
||||
EXT_TABLES,
|
||||
|
|
|
@ -15,7 +15,7 @@ See the :doc:`/changelog` for all changes.
|
|||
Installation
|
||||
------------
|
||||
|
||||
Misaka has been tested on CPython 2.7, 3.2, 3.3, 3.4, 3.5 and PyPy 2.6.
|
||||
Misaka has been tested on CPython 2.6, 2.7, 3.2, 3.3, 3.4, 3.5 and PyPy 2.6.
|
||||
CFFI 1.0 or newer is required. This means Misaka will not work on PyPy 2.5
|
||||
and older versions.
|
||||
|
||||
|
|
|
@ -41,13 +41,13 @@ if __name__ == '__main__':
|
|||
elif arg.startswith('--ext-'):
|
||||
arg = arg[6:]
|
||||
if not arg in extension_map:
|
||||
print('--ext-{} is not a valid Markdown extension'.format(arg))
|
||||
print('--ext-{0} is not a valid Markdown extension'.format(arg))
|
||||
sys.exit(1)
|
||||
extensions.append(arg)
|
||||
elif arg.startswith('--html-'):
|
||||
arg = arg[7:]
|
||||
if not arg in html_flag_map:
|
||||
print('--html-{} is not a valid HTML render flag'.format(arg))
|
||||
print('--html-{0} is not a valid HTML render flag'.format(arg))
|
||||
sys.exit(1)
|
||||
flags.append(arg)
|
||||
else:
|
||||
|
|
9
setup.py
9
setup.py
|
@ -6,6 +6,12 @@ import sys
|
|||
from setuptools import setup, Command
|
||||
|
||||
|
||||
install_requires=['cffi>=1.0.0']
|
||||
try:
|
||||
import importlib
|
||||
except ImportError:
|
||||
install_requires.append('importlib')
|
||||
|
||||
dirname = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
|
@ -52,6 +58,7 @@ setup(
|
|||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Programming Language :: C',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.2',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
|
@ -64,6 +71,6 @@ setup(
|
|||
'Topic :: Utilities'
|
||||
],
|
||||
setup_requires=['cffi>=1.0.0'],
|
||||
install_requires=['cffi>=1.0.0'],
|
||||
install_requires=install_requires,
|
||||
cffi_modules=['build_ffi.py:ffi'],
|
||||
)
|
||||
|
|
|
@ -36,20 +36,20 @@ def _exc_name(exception_class):
|
|||
if not inspect.isclass(exception_class):
|
||||
exception_class = exception_class.__class__
|
||||
|
||||
return '<{}.{}>'.format(
|
||||
return '<{0}.{1}>'.format(
|
||||
exception_class.__module__,
|
||||
exception_class.__name__)
|
||||
|
||||
|
||||
def readable_duration(s, suffix=''):
|
||||
if s >= 1:
|
||||
f = '{:.2f} s'.format(s)
|
||||
f = '{0:.2f} s'.format(s)
|
||||
elif s < 1:
|
||||
ms = 1000 * s
|
||||
if ms >= 1:
|
||||
f = '{:.2f} ms'.format(ms)
|
||||
f = '{0:.2f} ms'.format(ms)
|
||||
elif ms < 1:
|
||||
f = '{:.2f} us'.format(ms * 1000)
|
||||
f = '{0:.2f} us'.format(ms * 1000)
|
||||
|
||||
return f + suffix
|
||||
|
||||
|
@ -60,38 +60,38 @@ class AssertionObject(object):
|
|||
|
||||
def __lt__(self, other):
|
||||
if not self._target < other:
|
||||
raise AssertionError('{!r} < {!r}'.format(self._target, other))
|
||||
raise AssertionError('{0!r} < {1!r}'.format(self._target, other))
|
||||
|
||||
def __le__(self, other):
|
||||
if not self._target <= other:
|
||||
raise AssertionError('{!r} <= {!r}'.format(self._target, other))
|
||||
raise AssertionError('{0!r} <= {1!r}'.format(self._target, other))
|
||||
|
||||
def __eq__(self, other):
|
||||
if not self._target == other:
|
||||
raise AssertionError('{!r} == {!r}'.format(self._target, other))
|
||||
raise AssertionError('{0!r} == {1!r}'.format(self._target, other))
|
||||
|
||||
def __ne__(self, other):
|
||||
if not self._target != other:
|
||||
raise AssertionError('{!r} != {!r}'.format(self._target, other))
|
||||
raise AssertionError('{0!r} != {1!r}'.format(self._target, other))
|
||||
|
||||
def __gt__(self, other):
|
||||
if not self._target > other:
|
||||
raise AssertionError('{!r} > {!r}'.format(self._target, other))
|
||||
raise AssertionError('{0!r} > {1!r}'.format(self._target, other))
|
||||
|
||||
def __ge__(self, other):
|
||||
if not self._target >= other:
|
||||
raise AssertionError('{!r} >= {!r}'.format(self._target, other))
|
||||
raise AssertionError('{0!r} >= {1!r}'.format(self._target, other))
|
||||
|
||||
def length(self, other):
|
||||
target_length = len(self._target)
|
||||
|
||||
if target_length > other:
|
||||
raise AssertionError(
|
||||
'Higher than desired length: {!r} > {!r}'
|
||||
'Higher than desired length: {0!r} > {1!r}'
|
||||
.format(target_length, other))
|
||||
elif target_length < other:
|
||||
raise AssertionError(
|
||||
'Lower than desired length: {!r} < {!r}'
|
||||
'Lower than desired length: {0!r} < {1!r}'
|
||||
.format(target_length, other))
|
||||
|
||||
def diff(self, other):
|
||||
|
@ -103,11 +103,11 @@ class AssertionObject(object):
|
|||
|
||||
def contains(self, other):
|
||||
if other not in self._target:
|
||||
raise AssertionError('{!r} in {!r}'.format(other, self._target))
|
||||
raise AssertionError('{0!r} in {1!r}'.format(other, self._target))
|
||||
|
||||
def not_contains(self, other):
|
||||
if other in self._target:
|
||||
raise AssertionError('{!r} not in {!r}'.format(other, self._target))
|
||||
raise AssertionError('{0!r} not in {1!r}'.format(other, self._target))
|
||||
|
||||
def raises(self, exception_class=Exception):
|
||||
name = _exc_name(exception_class)
|
||||
|
@ -120,10 +120,10 @@ class AssertionObject(object):
|
|||
except exception_class:
|
||||
pass
|
||||
except Exception as e:
|
||||
raise AssertionError('Expected {}, but got {}:\n{}'
|
||||
raise AssertionError('Expected {0}, but got {1}:\n{2}'
|
||||
.format(name, _exc_name(e), e))
|
||||
else:
|
||||
raise AssertionError('{} not raised'.format(name))
|
||||
raise AssertionError('{0} not raised'.format(name))
|
||||
|
||||
def not_raises(self, exception_class=Exception):
|
||||
name = _exc_name(exception_class)
|
||||
|
@ -134,9 +134,9 @@ class AssertionObject(object):
|
|||
try:
|
||||
self._target()
|
||||
except exception_class as e:
|
||||
raise AssertionError('{} raised:\n{}'.format(name, e))
|
||||
raise AssertionError('{0} raised:\n{1}'.format(name, e))
|
||||
except Exception as e:
|
||||
raise AssertionError('Expected {} when failing, but got {}:\n{}'
|
||||
raise AssertionError('Expected {0} when failing, but got {1}:\n{2}'
|
||||
.format(name, _exc_name(e), e))
|
||||
|
||||
|
||||
|
@ -159,9 +159,9 @@ class TestResult(object):
|
|||
return 'PASSED' if self.passed else 'FAILED'
|
||||
|
||||
def __str__(self):
|
||||
s = '{} ... {}'.format(self.name(), self.status())
|
||||
s = '{0} ... {1}'.format(self.name(), self.status())
|
||||
if self.message:
|
||||
s += '\n{}\n{}\n{}'.format(LINE, self.message, LINE)
|
||||
s += '\n{0}\n{1}\n{2}'.format(LINE, self.message, LINE)
|
||||
|
||||
return s
|
||||
|
||||
|
@ -175,16 +175,16 @@ class BenchmarkResult(TestResult):
|
|||
|
||||
def __str__(self):
|
||||
if self.passed:
|
||||
s = '{:<25} {:>8} {:>16} {:>16}'.format(
|
||||
s = '{0:<25} {1:>8} {2:>16} {3:>16}'.format(
|
||||
self.name(),
|
||||
self.repetitions,
|
||||
readable_duration(self.timing, suffix='/t'),
|
||||
readable_duration(self.timing / self.repetitions, suffix='/op'))
|
||||
else:
|
||||
s = '{} ... FAILED'.format(self.name())
|
||||
s = '{0} ... FAILED'.format(self.name())
|
||||
|
||||
if self.message:
|
||||
s += '\n{}\n{}\n{}'.format(LINE, self.message, LINE)
|
||||
s += '\n{0}\n{1}\n{2}'.format(LINE, self.message, LINE)
|
||||
|
||||
return s
|
||||
|
||||
|
@ -202,7 +202,7 @@ class TestCase(object):
|
|||
def name(cls):
|
||||
name = _get_doc_line(cls)
|
||||
if name:
|
||||
return '{} ({})'.format(name, cls.__name__)
|
||||
return '{0} ({1})'.format(name, cls.__name__)
|
||||
else:
|
||||
return cls.__name__
|
||||
|
||||
|
@ -299,7 +299,7 @@ def runner(testcases, setup_func=None, teardown_func=None, config={}):
|
|||
for testcase in testcases:
|
||||
tests = testcase(config)
|
||||
|
||||
print('>> {}'.format(testcase.name()))
|
||||
print('>> {0}'.format(testcase.name()))
|
||||
|
||||
for result in tests.run():
|
||||
if result.passed:
|
||||
|
@ -313,6 +313,6 @@ def runner(testcases, setup_func=None, teardown_func=None, config={}):
|
|||
if teardown_func:
|
||||
teardown_func()
|
||||
|
||||
print('{} passed; {} failed.'.format(passed, failed))
|
||||
print('{0} passed; {1} failed.'.format(passed, failed))
|
||||
if failed > 0:
|
||||
sys.exit(1)
|
||||
|
|
|
@ -43,7 +43,7 @@ class MarkdownConformanceTest_10(TestCase):
|
|||
name = name.replace(' - ', '_')
|
||||
name = name.replace(' ', '_')
|
||||
name = re.sub('[(),]', '', name)
|
||||
return 'test_{}'.format(name.lower())
|
||||
return 'test_{0}'.format(name.lower())
|
||||
|
||||
|
||||
class MarkdownConformanceTest_103(MarkdownConformanceTest_10):
|
||||
|
|
|
@ -221,19 +221,19 @@ class TestRenderer(m.BaseRenderer):
|
|||
return '[PARAGRAPH] {0}\n'.format(text)
|
||||
|
||||
def table(self, content):
|
||||
return '[TABLE]\n{}'.format(content)
|
||||
return '[TABLE]\n{0}'.format(content)
|
||||
|
||||
def table_header(self, content):
|
||||
return '[TABLE_HEADER]\n{}'.format(content)
|
||||
return '[TABLE_HEADER]\n{0}'.format(content)
|
||||
|
||||
def table_body(self, content):
|
||||
return '[TABLE_BODY]\n{}'.format(content)
|
||||
return '[TABLE_BODY]\n{0}'.format(content)
|
||||
|
||||
def table_row(self, content):
|
||||
return '[TABLE_ROW]\n{0}\n'.format(content)
|
||||
|
||||
def table_cell(self, text, align, is_header):
|
||||
align = 'align={} '.format(align) if align else ''
|
||||
align = 'align={0} '.format(align) if align else ''
|
||||
header = 'header=true ' if is_header else ''
|
||||
return '[TABLE_CELL {2}{1}text={0}]'.format(text, align, header)
|
||||
|
||||
|
@ -278,7 +278,7 @@ class TestRenderer(m.BaseRenderer):
|
|||
return '[LINEBREAK]'
|
||||
|
||||
def link(self, content, link, title):
|
||||
return '[LINK link={} title={}] {}'.format(link, title, content)
|
||||
return '[LINK link={0} title={1}] {2}'.format(link, title, content)
|
||||
|
||||
def strikethrough(self, text):
|
||||
return '[STRIKETHROUGH] {0}'.format(text)
|
||||
|
@ -293,7 +293,7 @@ class TestRenderer(m.BaseRenderer):
|
|||
return '[TRIPLE_EMPHASIS] {0}'.format(text)
|
||||
|
||||
def math(self, text, displaymode):
|
||||
return '[MATH] {}'.format(text)
|
||||
return '[MATH] {0}'.format(text)
|
||||
|
||||
def normal_text(self, text):
|
||||
return text
|
||||
|
@ -312,10 +312,10 @@ class TestRendererLowlevel(m.BaseRenderer):
|
|||
return text
|
||||
|
||||
def entity(self, text):
|
||||
return '[ENTITY] {}'.format(text)
|
||||
return '[ENTITY] {0}'.format(text)
|
||||
|
||||
def normal_text(self, text):
|
||||
return '[NORMAL_TEXT] {}'.format(text)
|
||||
return '[NORMAL_TEXT] {0}'.format(text)
|
||||
|
||||
|
||||
class CustomRendererTest(TestCase):
|
||||
|
|
Loading…
Reference in New Issue