Browse Source

Make StringMixIn a lot simpler thanks to __getattr__.

tags/v0.3.3
Ben Kurtovic 10 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 sys import getdefaultencoding

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

__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):
"""Implement the interface for ``unicode``/``str`` in a dynamic manner.

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

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

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

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

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

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

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

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

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

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

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:
@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
import re

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


+ 8
- 8
tests/test_string_mixin.py View File

@@ -59,8 +59,8 @@ class TestStringMixIn(unittest.TestCase):
else:
methods.append("decode")
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)

def test_types(self):
@@ -109,12 +109,12 @@ class TestStringMixIn(unittest.TestCase):
self.assertFalse(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):
"""test other magically implemented features, like len() and iter()"""


Loading…
Cancel
Save