diff options
author | Armin Ronacher <armin.ronacher@active-4.com> | 2013-05-20 19:11:32 +0100 |
---|---|---|
committer | Armin Ronacher <armin.ronacher@active-4.com> | 2013-05-20 19:11:32 +0100 |
commit | 08c34a3315ec94b237100dd42d4ddd7f406942d9 (patch) | |
tree | f58f4db3470f70d6a9a598927c5731119b3de592 | |
parent | 7415f6f8816e8eae1e34db76504062e98e5e6ab0 (diff) | |
download | markupsafe-08c34a3315ec94b237100dd42d4ddd7f406942d9.tar.gz |
Switch to native port and remove 2to3
-rw-r--r-- | markupsafe/__init__.py | 60 | ||||
-rw-r--r-- | markupsafe/_native.py | 7 | ||||
-rw-r--r-- | markupsafe/tests.py | 52 | ||||
-rw-r--r-- | setup.py | 6 |
4 files changed, 45 insertions, 80 deletions
diff --git a/markupsafe/__init__.py b/markupsafe/__init__.py index 480252c..6a8dc5e 100644 --- a/markupsafe/__init__.py +++ b/markupsafe/__init__.py @@ -9,7 +9,7 @@ :license: BSD, see LICENSE for more details. """ import re -from itertools import imap +from markupsafe._compat import text_type, string_types, imap, unichr, PY2 __all__ = ['Markup', 'soft_unicode', 'escape', 'escape_silent'] @@ -19,7 +19,7 @@ _striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)') _entity_re = re.compile(r'&([^;]+);') -class Markup(unicode): +class Markup(text_type): r"""Marks a string as being safe for inclusion in HTML/XML output without needing to be escaped. This implements the `__html__` interface a couple of frameworks and web applications use. :class:`Markup` is a direct @@ -68,25 +68,25 @@ class Markup(unicode): if hasattr(base, '__html__'): base = base.__html__() if encoding is None: - return unicode.__new__(cls, base) - return unicode.__new__(cls, base, encoding, errors) + return text_type.__new__(cls, base) + return text_type.__new__(cls, base, encoding, errors) def __html__(self): return self def __add__(self, other): - if isinstance(other, basestring) or hasattr(other, '__html__'): + if isinstance(other, string_types) or hasattr(other, '__html__'): return self.__class__(super(Markup, self).__add__(self.escape(other))) return NotImplemented def __radd__(self, other): - if hasattr(other, '__html__') or isinstance(other, basestring): + if hasattr(other, '__html__') or isinstance(other, string_types): return self.escape(other).__add__(self) return NotImplemented def __mul__(self, num): if isinstance(num, (int, long)): - return self.__class__(unicode.__mul__(self, num)) + return self.__class__(text_type.__mul__(self, num)) return NotImplemented __rmul__ = __mul__ @@ -95,32 +95,32 @@ class Markup(unicode): arg = tuple(imap(_MarkupEscapeHelper, arg, self.escape)) else: arg = _MarkupEscapeHelper(arg, self.escape) - return self.__class__(unicode.__mod__(self, arg)) + return self.__class__(text_type.__mod__(self, arg)) def __repr__(self): return '%s(%s)' % ( self.__class__.__name__, - unicode.__repr__(self) + text_type.__repr__(self) ) def join(self, seq): - return self.__class__(unicode.join(self, imap(self.escape, seq))) - join.__doc__ = unicode.join.__doc__ + return self.__class__(text_type.join(self, imap(self.escape, seq))) + join.__doc__ = text_type.join.__doc__ def split(self, *args, **kwargs): - return map(self.__class__, unicode.split(self, *args, **kwargs)) - split.__doc__ = unicode.split.__doc__ + return map(self.__class__, text_type.split(self, *args, **kwargs)) + split.__doc__ = text_type.split.__doc__ def rsplit(self, *args, **kwargs): - return map(self.__class__, unicode.rsplit(self, *args, **kwargs)) - rsplit.__doc__ = unicode.rsplit.__doc__ + return map(self.__class__, text_type.rsplit(self, *args, **kwargs)) + rsplit.__doc__ = text_type.rsplit.__doc__ def splitlines(self, *args, **kwargs): - return map(self.__class__, unicode.splitlines(self, *args, **kwargs)) - splitlines.__doc__ = unicode.splitlines.__doc__ + return map(self.__class__, text_type.splitlines(self, *args, **kwargs)) + splitlines.__doc__ = text_type.splitlines.__doc__ def unescape(self): - r"""Unescape markup again into an unicode string. This also resolves + r"""Unescape markup again into an text_type string. This also resolves known HTML4 and XHTML entities: >>> Markup("Main » <em>About</em>").unescape() @@ -139,10 +139,10 @@ class Markup(unicode): except ValueError: pass return u'' - return _entity_re.sub(handle_match, unicode(self)) + return _entity_re.sub(handle_match, text_type(self)) def striptags(self): - r"""Unescape markup into an unicode string and strip all tags. This + r"""Unescape markup into an text_type string and strip all tags. This also resolves known HTML4 and XHTML entities. Whitespace is normalized to one: @@ -164,7 +164,7 @@ class Markup(unicode): return rv def make_wrapper(name): - orig = getattr(unicode, name) + orig = getattr(text_type, name) def func(self, *args, **kwargs): args = _escape_argspec(list(args), enumerate(args), self.escape) #_escape_argspec(kwargs, kwargs.iteritems(), None) @@ -180,20 +180,20 @@ class Markup(unicode): locals()[method] = make_wrapper(method) # new in python 2.5 - if hasattr(unicode, 'partition'): + if hasattr(text_type, 'partition'): def partition(self, sep): return tuple(map(self.__class__, - unicode.partition(self, self.escape(sep)))) + text_type.partition(self, self.escape(sep)))) def rpartition(self, sep): return tuple(map(self.__class__, - unicode.rpartition(self, self.escape(sep)))) + text_type.rpartition(self, self.escape(sep)))) # new in python 2.6 - if hasattr(unicode, 'format'): + if hasattr(text_type, 'format'): format = make_wrapper('format') # not in python 3 - if hasattr(unicode, '__getslice__'): + if hasattr(text_type, '__getslice__'): __getslice__ = make_wrapper('__getslice__') del method, make_wrapper @@ -202,7 +202,7 @@ class Markup(unicode): def _escape_argspec(obj, iterable, escape): """Helper for various string-wrapped functions.""" for key, value in iterable: - if hasattr(value, '__html__') or isinstance(value, basestring): + if hasattr(value, '__html__') or isinstance(value, string_types): obj[key] = escape(value) return obj @@ -215,7 +215,7 @@ class _MarkupEscapeHelper(object): self.escape = escape __getitem__ = lambda s, x: _MarkupEscapeHelper(s.obj[x], s.escape) - __unicode__ = lambda s: unicode(s.escape(s.obj)) + __unicode__ = __str__ = lambda s: text_type(s.escape(s.obj)) __repr__ = lambda s: str(s.escape(repr(s.obj))) __int__ = lambda s: int(s.obj) __float__ = lambda s: float(s.obj) @@ -228,4 +228,6 @@ try: except ImportError: from markupsafe._native import escape, escape_silent, soft_unicode -# vim:sts=4:sw=4:et: +if not PY2: + soft_str = soft_unicode + __all__.append('soft_str') diff --git a/markupsafe/_native.py b/markupsafe/_native.py index 3acf91b..5e83f10 100644 --- a/markupsafe/_native.py +++ b/markupsafe/_native.py @@ -9,6 +9,7 @@ :license: BSD, see LICENSE for more details. """ from markupsafe import Markup +from markupsafe._compat import text_type def escape(s): @@ -18,7 +19,7 @@ def escape(s): """ if hasattr(s, '__html__'): return s.__html__() - return Markup(unicode(s) + return Markup(text_type(s) .replace('&', '&') .replace('>', '>') .replace('<', '<') @@ -40,6 +41,6 @@ def soft_unicode(s): """Make a string unicode if it isn't already. That way a markup string is not converted back to unicode. """ - if not isinstance(s, unicode): - s = unicode(s) + if not isinstance(s, text_type): + s = text_type(s) return s diff --git a/markupsafe/tests.py b/markupsafe/tests.py index dbb3125..12cd69b 100644 --- a/markupsafe/tests.py +++ b/markupsafe/tests.py @@ -2,16 +2,18 @@ import gc import unittest from markupsafe import Markup, escape, escape_silent +from markupsafe._compat import text_type class MarkupTestCase(unittest.TestCase): - def test_markup_operations(self): + def test_adding(self): # adding two strings should escape the unsafe one unsafe = '<script type="application/x-some-script">alert("foo");</script>' safe = Markup('<em>username</em>') - assert unsafe + safe == unicode(escape(unsafe)) + unicode(safe) + assert unsafe + safe == text_type(escape(unsafe)) + text_type(safe) + def test_string_interpolation(self): # string interpolations are safe to use too assert Markup('<em>%s</em>') % '<bad user>' == \ '<em><bad user></em>' @@ -22,6 +24,7 @@ class MarkupTestCase(unittest.TestCase): assert Markup('%i') % 3.14 == '3' assert Markup('%.2f') % 3.14 == '3.14' + def test_type_behavior(self): # an escaped object is markup too assert type(Markup('foo') + 'bar') is Markup @@ -29,16 +32,19 @@ class MarkupTestCase(unittest.TestCase): x = Markup("foo") assert x.__html__() is x + def test_html_interop(self): # it also knows how to treat __html__ objects class Foo(object): def __html__(self): return '<em>awesome</em>' def __unicode__(self): return 'awesome' + __str__ = __unicode__ assert Markup(Foo()) == '<em>awesome</em>' assert Markup('<strong>%s</strong>') % Foo() == \ '<strong><em>awesome</em></strong>' + def test_escaping(self): # escaping and unescaping assert escape('"<>&\'') == '"<>&'' assert Markup("<em>Foo & Bar</em>").striptags() == "Foo & Bar" @@ -59,8 +65,8 @@ class MarkupLeakTestCase(unittest.TestCase): def test_markup_leaks(self): counts = set() - for count in xrange(20): - for item in xrange(1000): + for count in range(20): + for item in range(1000): escape("foo") escape("<foo>") escape(u"foo") @@ -68,48 +74,10 @@ class MarkupLeakTestCase(unittest.TestCase): counts.add(len(gc.get_objects())) assert len(counts) == 1, 'ouch, c extension seems to leak objects' -class EncodedMarkup(Markup): - __slots__ = () - encoding = 'utf8' - - @classmethod - def escape(cls, s): - if isinstance(s, str): - s = s.decode('utf8') - return super(EncodedMarkup, cls).escape(s) - -class MarkupSubclassTestCase(unittest.TestCase): - # The Russian name of Russia (Rossija) - russia = u'Россия' - utf8 = russia.encode('utf8') - - def test_escape(self): - myval = EncodedMarkup.escape(self.utf8) - assert myval == self.russia, repr(myval) - def test_add(self): - myval = EncodedMarkup() + self.utf8 - assert myval == self.russia, repr(myval) - def test_radd(self): - myval = self.utf8 + EncodedMarkup() - assert myval == self.russia, repr(myval) - def test_join(self): - myval = EncodedMarkup().join([self.utf8]) - assert myval == self.russia, repr(myval) - def test_partition(self): - assert EncodedMarkup(self.russia).partition(self.utf8)[1] == self.russia - assert EncodedMarkup(self.russia).rpartition(self.utf8)[1] == self.russia - def test_mod(self): - assert EncodedMarkup('%s') % self.utf8 == self.russia - assert EncodedMarkup('%r') % self.utf8 == escape(repr(self.utf8)) - def test_strip(self): - assert EncodedMarkup(self.russia).strip(self.utf8) == u'' - assert EncodedMarkup(self.russia).rstrip(self.utf8) == u'' - def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(MarkupTestCase)) - suite.addTest(unittest.makeSuite(MarkupSubclassTestCase)) # this test only tests the c extension if not hasattr(escape, 'func_code'): @@ -28,11 +28,6 @@ if sys.platform == 'win32' and sys.version_info > (2, 6): ext_errors += (IOError,) -extra = {} -if sys.version_info >= (3, 0): - extra['use_2to3'] = True - - class BuildFailed(Exception): pass @@ -96,7 +91,6 @@ def run_setup(with_binary): include_package_data=True, cmdclass={'build_ext': ve_build_ext}, features=features, - **extra ) |