Browse Source

Make StringMixIn a lot simpler thanks to __getattr__.

tags/v0.3.3
Ben Kurtovic 11 years ago
parent
commit
39c0756130
3 changed files with 17 additions and 277 deletions
  1. +8
    -268
      mwparserfromhell/string_mixin.py
  2. +1
    -1
      mwparserfromhell/wikicode.py
  3. +8
    -8
      tests/test_string_mixin.py

+ 8
- 268
mwparserfromhell/string_mixin.py View File

@@ -26,20 +26,12 @@ interface for the ``unicode`` type (``str`` on py3k) in a dynamic manner.
""" """


from __future__ import unicode_literals from __future__ import unicode_literals
from sys import getdefaultencoding


from .compat import py3k, py32, str
from .compat import bytes, py3k, str


__all__ = ["StringMixIn"] __all__ = ["StringMixIn"]


def inheritdoc(method):
"""Set __doc__ of *method* to __doc__ of *method* in its parent class.

Since this is used on :py:class:`~.StringMixIn`, the "parent class" used is
``str``. This function can be used as a decorator.
"""
method.__doc__ = getattr(str, method.__name__).__doc__
return method

class StringMixIn(object): class StringMixIn(object):
"""Implement the interface for ``unicode``/``str`` in a dynamic manner. """Implement the interface for ``unicode``/``str`` in a dynamic manner.


@@ -55,10 +47,10 @@ class StringMixIn(object):
return self.__unicode__() return self.__unicode__()


def __bytes__(self): def __bytes__(self):
return self.__unicode__().encode("utf8")
return bytes(self.__unicode__(), getdefaultencoding())
else: else:
def __str__(self): def __str__(self):
return self.__unicode__().encode("utf8")
return bytes(self.__unicode__())


def __unicode__(self): def __unicode__(self):
raise NotImplementedError() raise NotImplementedError()
@@ -67,33 +59,21 @@ class StringMixIn(object):
return repr(self.__unicode__()) return repr(self.__unicode__())


def __lt__(self, other): def __lt__(self, other):
if isinstance(other, StringMixIn):
return self.__unicode__() < other.__unicode__()
return self.__unicode__() < other return self.__unicode__() < other


def __le__(self, other): def __le__(self, other):
if isinstance(other, StringMixIn):
return self.__unicode__() <= other.__unicode__()
return self.__unicode__() <= other return self.__unicode__() <= other


def __eq__(self, other): def __eq__(self, other):
if isinstance(other, StringMixIn):
return self.__unicode__() == other.__unicode__()
return self.__unicode__() == other return self.__unicode__() == other


def __ne__(self, other): def __ne__(self, other):
if isinstance(other, StringMixIn):
return self.__unicode__() != other.__unicode__()
return self.__unicode__() != other return self.__unicode__() != other


def __gt__(self, other): def __gt__(self, other):
if isinstance(other, StringMixIn):
return self.__unicode__() > other.__unicode__()
return self.__unicode__() > other return self.__unicode__() > other


def __ge__(self, other): def __ge__(self, other):
if isinstance(other, StringMixIn):
return self.__unicode__() >= other.__unicode__()
return self.__unicode__() >= other return self.__unicode__() >= other


if py3k: if py3k:
@@ -117,250 +97,10 @@ class StringMixIn(object):
return reversed(self.__unicode__()) return reversed(self.__unicode__())


def __contains__(self, item): def __contains__(self, item):
if isinstance(item, StringMixIn):
return str(item) in self.__unicode__()
return item in self.__unicode__()

@inheritdoc
def capitalize(self):
return self.__unicode__().capitalize()

if py3k and not py32:
@inheritdoc
def casefold(self):
return self.__unicode__().casefold()

@inheritdoc
def center(self, width, fillchar=None):
if fillchar is None:
return self.__unicode__().center(width)
return self.__unicode__().center(width, fillchar)

@inheritdoc
def count(self, sub, start=None, end=None):
return self.__unicode__().count(sub, start, end)
return str(item) in self.__unicode__()


if not py3k:
@inheritdoc
def decode(self, encoding=None, errors=None):
kwargs = {}
if encoding is not None:
kwargs["encoding"] = encoding
if errors is not None:
kwargs["errors"] = errors
return self.__unicode__().decode(**kwargs)

@inheritdoc
def encode(self, encoding=None, errors=None):
kwargs = {}
if encoding is not None:
kwargs["encoding"] = encoding
if errors is not None:
kwargs["errors"] = errors
return self.__unicode__().encode(**kwargs)

@inheritdoc
def endswith(self, prefix, start=None, end=None):
return self.__unicode__().endswith(prefix, start, end)

@inheritdoc
def expandtabs(self, tabsize=None):
if tabsize is None:
return self.__unicode__().expandtabs()
return self.__unicode__().expandtabs(tabsize)

@inheritdoc
def find(self, sub, start=None, end=None):
return self.__unicode__().find(sub, start, end)

@inheritdoc
def format(self, *args, **kwargs):
return self.__unicode__().format(*args, **kwargs)
def __getattr__(self, attr):
return getattr(self.__unicode__(), attr)


if py3k: if py3k:
@inheritdoc
def format_map(self, mapping):
return self.__unicode__().format_map(mapping)

@inheritdoc
def index(self, sub, start=None, end=None):
return self.__unicode__().index(sub, start, end)

@inheritdoc
def isalnum(self):
return self.__unicode__().isalnum()

@inheritdoc
def isalpha(self):
return self.__unicode__().isalpha()

@inheritdoc
def isdecimal(self):
return self.__unicode__().isdecimal()

@inheritdoc
def isdigit(self):
return self.__unicode__().isdigit()

if py3k:
@inheritdoc
def isidentifier(self):
return self.__unicode__().isidentifier()

@inheritdoc
def islower(self):
return self.__unicode__().islower()

@inheritdoc
def isnumeric(self):
return self.__unicode__().isnumeric()

if py3k:
@inheritdoc
def isprintable(self):
return self.__unicode__().isprintable()

@inheritdoc
def isspace(self):
return self.__unicode__().isspace()

@inheritdoc
def istitle(self):
return self.__unicode__().istitle()

@inheritdoc
def isupper(self):
return self.__unicode__().isupper()

@inheritdoc
def join(self, iterable):
return self.__unicode__().join(iterable)

@inheritdoc
def ljust(self, width, fillchar=None):
if fillchar is None:
return self.__unicode__().ljust(width)
return self.__unicode__().ljust(width, fillchar)

@inheritdoc
def lower(self):
return self.__unicode__().lower()

@inheritdoc
def lstrip(self, chars=None):
return self.__unicode__().lstrip(chars)

if py3k:
@staticmethod
@inheritdoc
def maketrans(x, y=None, z=None):
if z is None:
if y is None:
return str.maketrans(x)
return str.maketrans(x, y)
return str.maketrans(x, y, z)

@inheritdoc
def partition(self, sep):
return self.__unicode__().partition(sep)

@inheritdoc
def replace(self, old, new, count=None):
if count is None:
return self.__unicode__().replace(old, new)
return self.__unicode__().replace(old, new, count)

@inheritdoc
def rfind(self, sub, start=None, end=None):
return self.__unicode__().rfind(sub, start, end)

@inheritdoc
def rindex(self, sub, start=None, end=None):
return self.__unicode__().rindex(sub, start, end)

@inheritdoc
def rjust(self, width, fillchar=None):
if fillchar is None:
return self.__unicode__().rjust(width)
return self.__unicode__().rjust(width, fillchar)

@inheritdoc
def rpartition(self, sep):
return self.__unicode__().rpartition(sep)

if py3k and not py32:
@inheritdoc
def rsplit(self, sep=None, maxsplit=None):
kwargs = {}
if sep is not None:
kwargs["sep"] = sep
if maxsplit is not None:
kwargs["maxsplit"] = maxsplit
return self.__unicode__().rsplit(**kwargs)
else:
@inheritdoc
def rsplit(self, sep=None, maxsplit=None):
if maxsplit is None:
if sep is None:
return self.__unicode__().rsplit()
return self.__unicode__().rsplit(sep)
return self.__unicode__().rsplit(sep, maxsplit)

@inheritdoc
def rstrip(self, chars=None):
return self.__unicode__().rstrip(chars)

if py3k and not py32:
@inheritdoc
def split(self, sep=None, maxsplit=None):
kwargs = {}
if sep is not None:
kwargs["sep"] = sep
if maxsplit is not None:
kwargs["maxsplit"] = maxsplit
return self.__unicode__().split(**kwargs)
else:
@inheritdoc
def split(self, sep=None, maxsplit=None):
if maxsplit is None:
if sep is None:
return self.__unicode__().split()
return self.__unicode__().split(sep)
return self.__unicode__().split(sep, maxsplit)

@inheritdoc
def splitlines(self, keepends=None):
if keepends is None:
return self.__unicode__().splitlines()
return self.__unicode__().splitlines(keepends)

@inheritdoc
def startswith(self, prefix, start=None, end=None):
return self.__unicode__().startswith(prefix, start, end)

@inheritdoc
def strip(self, chars=None):
return self.__unicode__().strip(chars)

@inheritdoc
def swapcase(self):
return self.__unicode__().swapcase()

@inheritdoc
def title(self):
return self.__unicode__().title()

@inheritdoc
def translate(self, table):
return self.__unicode__().translate(table)

@inheritdoc
def upper(self):
return self.__unicode__().upper()

@inheritdoc
def zfill(self, width):
return self.__unicode__().zfill(width)


del inheritdoc
maketrans = str.maketrans # Static method can't rely on __getattr__

+ 1
- 1
mwparserfromhell/wikicode.py View File

@@ -23,7 +23,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import re import re


from .compat import maxsize, py3k, str
from .compat import py3k, str
from .nodes import (Argument, Comment, ExternalLink, Heading, HTMLEntity, from .nodes import (Argument, Comment, ExternalLink, Heading, HTMLEntity,
Node, Tag, Template, Text, Wikilink) Node, Tag, Template, Text, Wikilink)
from .string_mixin import StringMixIn from .string_mixin import StringMixIn


+ 8
- 8
tests/test_string_mixin.py View File

@@ -59,8 +59,8 @@ class TestStringMixIn(unittest.TestCase):
else: else:
methods.append("decode") methods.append("decode")
for meth in methods: for meth in methods:
expected = getattr(str, meth).__doc__
actual = getattr(StringMixIn, meth).__doc__
expected = getattr("foo", meth).__doc__
actual = getattr(_FakeString("foo"), meth).__doc__
self.assertEqual(expected, actual) self.assertEqual(expected, actual)


def test_types(self): def test_types(self):
@@ -109,12 +109,12 @@ class TestStringMixIn(unittest.TestCase):
self.assertFalse(str1 < str4) self.assertFalse(str1 < str4)
self.assertTrue(str1 <= str4) self.assertTrue(str1 <= str4)


self.assertTrue(str1 > str5)
self.assertTrue(str1 >= str5)
self.assertFalse(str1 == str5)
self.assertTrue(str1 != str5)
self.assertFalse(str1 < str5)
self.assertFalse(str1 <= str5)
self.assertFalse(str5 > str1)
self.assertFalse(str5 >= str1)
self.assertFalse(str5 == str1)
self.assertTrue(str5 != str1)
self.assertTrue(str5 < str1)
self.assertTrue(str5 <= str1)


def test_other_magics(self): def test_other_magics(self):
"""test other magically implemented features, like len() and iter()""" """test other magically implemented features, like len() and iter()"""


Loading…
Cancel
Save