@@ -5,7 +5,7 @@ mwparserfromhell | |||||
that provides an easy-to-use and outrageously powerful parser for MediaWiki_ | that provides an easy-to-use and outrageously powerful parser for MediaWiki_ | ||||
wikicode. It supports Python 2 and Python 3. | wikicode. It supports Python 2 and Python 3. | ||||
Developed by Earwig_ and named by `Σ`_. | |||||
Developed by Earwig_ with help from `Σ`_. | |||||
Installation | Installation | ||||
------------ | ------------ | ||||
@@ -1,16 +1,25 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
""" | |||||
Implements support for both Python 2 and Python 3. | |||||
""" | |||||
import sys | import sys | ||||
v = sys.version_info[0] | |||||
py3k = sys.version_info.major == 3 | |||||
if v >= 3: | |||||
if py3k: | |||||
bytes = bytes | bytes = bytes | ||||
str = str | str = str | ||||
basestring = (str, bytes) | |||||
import html.entities as htmlentitydefs | |||||
basestring = str | |||||
maxsize = sys.maxsize | |||||
import html.entities as htmlentities | |||||
else: | else: | ||||
bytes = str | bytes = str | ||||
str = unicode | str = unicode | ||||
basestring = basestring | basestring = basestring | ||||
import htmlentitydefs | |||||
maxsize = sys.maxint | |||||
import htmlentitydefs as htmlentities | |||||
del sys |
@@ -20,7 +20,7 @@ | |||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
# SOFTWARE. | # SOFTWARE. | ||||
import sys | |||||
from .compat import maxsize, py3k | |||||
__all__ = ["SmartList"] | __all__ = ["SmartList"] | ||||
@@ -50,7 +50,7 @@ class SmartList(list): | |||||
for child, (start, stop, step) in self._children.itervalues(): | for child, (start, stop, step) in self._children.itervalues(): | ||||
if start >= key.stop: | if start >= key.stop: | ||||
self._children[id(child)][1][0] += diff | self._children[id(child)][1][0] += diff | ||||
if stop >= key.stop and stop != sys.maxint: | |||||
if stop >= key.stop and stop != maxsize: | |||||
self._children[id(child)][1][1] += diff | self._children[id(child)][1][1] += diff | ||||
def __delitem__(self, key): | def __delitem__(self, key): | ||||
@@ -64,14 +64,15 @@ class SmartList(list): | |||||
if stop >= key.stop: | if stop >= key.stop: | ||||
self._children[id(child)][1][1] -= diff | self._children[id(child)][1][1] -= diff | ||||
def __getslice__(self, start, stop): | |||||
return self.__getitem__(slice(start, stop)) | |||||
if not py3k: | |||||
def __getslice__(self, start, stop): | |||||
return self.__getitem__(slice(start, stop)) | |||||
def __setslice__(self, start, stop, iterable): | |||||
self.__setitem__(slice(start, stop), iterable) | |||||
def __setslice__(self, start, stop, iterable): | |||||
self.__setitem__(slice(start, stop), iterable) | |||||
def __delslice__(self, start, stop): | |||||
self.__delitem__(slice(start, stop)) | |||||
def __delslice__(self, start, stop): | |||||
self.__delitem__(slice(start, stop)) | |||||
def __add__(self, other): | def __add__(self, other): | ||||
return SmartList(list(self) + other) | return SmartList(list(self) + other) | ||||
@@ -165,8 +166,12 @@ class _ListProxy(list): | |||||
return self._render() >= list(other) | return self._render() >= list(other) | ||||
return self._render() >= other | return self._render() >= other | ||||
def __nonzero__(self): | |||||
return bool(self._render()) | |||||
if py3k: | |||||
def __bool__(self): | |||||
return bool(self._render()) | |||||
else: | |||||
def __nonzero__(self): | |||||
return bool(self._render()) | |||||
def __len__(self): | def __len__(self): | ||||
return (self._stop - self._start) / self._step | return (self._stop - self._start) / self._step | ||||
@@ -205,14 +210,15 @@ class _ListProxy(list): | |||||
def __contains__(self, item): | def __contains__(self, item): | ||||
return item in self._render() | return item in self._render() | ||||
def __getslice__(self, start, stop): | |||||
return self.__getitem__(slice(start, stop)) | |||||
if not py3k: | |||||
def __getslice__(self, start, stop): | |||||
return self.__getitem__(slice(start, stop)) | |||||
def __setslice__(self, start, stop, iterable): | |||||
self.__setitem__(slice(start, stop), iterable) | |||||
def __setslice__(self, start, stop, iterable): | |||||
self.__setitem__(slice(start, stop), iterable) | |||||
def __delslice__(self, start, stop): | |||||
self.__delitem__(slice(start, stop)) | |||||
def __delslice__(self, start, stop): | |||||
self.__delitem__(slice(start, stop)) | |||||
def __add__(self, other): | def __add__(self, other): | ||||
return SmartList(list(self) + other) | return SmartList(list(self) + other) | ||||
@@ -21,26 +21,30 @@ | |||||
# SOFTWARE. | # SOFTWARE. | ||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
from .compat import str, bytes, v | |||||
from .compat import py3k, str | |||||
__all__ = ["StringMixIn"] | __all__ = ["StringMixIn"] | ||||
def inheritdoc(method): | def inheritdoc(method): | ||||
try: | |||||
method.__doc__ = getattr(str, method.__name__).__doc__ | |||||
except AttributeError: | |||||
method.__doc__ = "This feature is only available on Python 2." | |||||
method.__doc__ = getattr(str, method.__name__).__doc__ | |||||
return method | return method | ||||
class StringMixIn(object): | class StringMixIn(object): | ||||
if v >= 3: | |||||
def __str__(self): | |||||
return self.__unicode__() | |||||
if py3k: | |||||
def __str__(self): | |||||
return self.__unicode__() | |||||
def __bytes__(self): | |||||
return self.__unicode__().encode("utf8") | |||||
else: | else: | ||||
def __str__(self): | def __str__(self): | ||||
return self.__unicode__().encode("utf8") | return self.__unicode__().encode("utf8") | ||||
def __unicode__(self): | |||||
raise NotImplementedError() | |||||
def __repr__(self): | def __repr__(self): | ||||
return repr(self.__unicode__()) | return repr(self.__unicode__()) | ||||
@@ -74,11 +78,12 @@ class StringMixIn(object): | |||||
return self.__unicode__() >= other.__unicode__() | return self.__unicode__() >= other.__unicode__() | ||||
return self.__unicode__() >= other | return self.__unicode__() >= other | ||||
def __nonzero__(self): | |||||
return bool(self.__unicode__()) | |||||
def __unicode__(self): | |||||
raise NotImplementedError() | |||||
if py3k: | |||||
def __bool__(self): | |||||
return bool(self.__unicode__()) | |||||
else: | |||||
def __nonzero__(self): | |||||
return bool(self.__unicode__()) | |||||
def __len__(self): | def __len__(self): | ||||
return len(self.__unicode__()) | return len(self.__unicode__()) | ||||
@@ -92,7 +97,7 @@ class StringMixIn(object): | |||||
def __contains__(self, item): | def __contains__(self, item): | ||||
if isinstance(item, StringMixIn): | if isinstance(item, StringMixIn): | ||||
return unicode(item) in self.__unicode__() | |||||
return str(item) in self.__unicode__() | |||||
return item in self.__unicode__() | return item in self.__unicode__() | ||||
@inheritdoc | @inheritdoc | ||||
@@ -107,9 +112,10 @@ class StringMixIn(object): | |||||
def count(self, sub=None, start=None, end=None): | def count(self, sub=None, start=None, end=None): | ||||
return self.__unicode__().count(sub, start, end) | return self.__unicode__().count(sub, start, end) | ||||
@inheritdoc | |||||
def decode(self, encoding=None, errors=None): | |||||
return self.__unicode__().decode(encoding, errors) | |||||
if not py3k: | |||||
@inheritdoc | |||||
def decode(self, encoding=None, errors=None): | |||||
return self.__unicode__().decode(encoding, errors) | |||||
@inheritdoc | @inheritdoc | ||||
def encode(self, encoding=None, errors=None): | def encode(self, encoding=None, errors=None): | ||||
@@ -23,21 +23,24 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import mwparserfromhell | import mwparserfromhell | ||||
from .compat import basestring, bytes, str | |||||
from .nodes import Node | from .nodes import Node | ||||
from .smart_list import SmartList | from .smart_list import SmartList | ||||
from .compat import str, bytes, basestring | |||||
def parse_anything(value): | def parse_anything(value): | ||||
wikicode = mwparserfromhell.wikicode.Wikicode | wikicode = mwparserfromhell.wikicode.Wikicode | ||||
if isinstance(value, wikicode): | if isinstance(value, wikicode): | ||||
return value | return value | ||||
if isinstance(value, Node): | |||||
elif isinstance(value, Node): | |||||
return wikicode(SmartList([value])) | return wikicode(SmartList([value])) | ||||
if isinstance(value, basestring): | |||||
elif isinstance(value, basestring): | |||||
return mwparserfromhell.parse(value) | return mwparserfromhell.parse(value) | ||||
if isinstance(value, int): | |||||
elif isinstance(value, bytes): | |||||
# This should only happen in py3k when bytes is not in basestring: | |||||
return mwparserfromhell.parse(value.decode("utf8")) | |||||
elif isinstance(value, int): | |||||
return mwparserfromhell.parse(str(value)) | return mwparserfromhell.parse(str(value)) | ||||
if value is None: | |||||
elif value is None: | |||||
return wikicode(SmartList()) | return wikicode(SmartList()) | ||||
try: | try: | ||||
nodelist = SmartList() | nodelist = SmartList() | ||||