jenkins-bot has submitted this change and it was merged.
Change subject: __str__ / __repr__ should always return str ......................................................................
__str__ / __repr__ should always return str
Change-Id: I7a7f21c68c20e021298fd911292c3706f4c0dd68 --- M pywikibot/data/sparql.py M pywikibot/tools/__init__.py M tests/sparql_tests.py 3 files changed, 83 insertions(+), 24 deletions(-)
Approvals: John Vandenberg: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/data/sparql.py b/pywikibot/data/sparql.py index dd09b21..12ba695 100644 --- a/pywikibot/data/sparql.py +++ b/pywikibot/data/sparql.py @@ -13,6 +13,7 @@ from urllib2 import quote
from pywikibot.comms import http +from pywikibot.tools import UnicodeMixin, py2_encode_utf_8
WIKIDATA = 'http://query.wikidata.org/sparql' DEFAULT_HEADERS = {'cache-control': 'no-cache', @@ -123,7 +124,18 @@ return result_type()
-class URI(object): +class SparqlNode(UnicodeMixin): + """Base class for SPARQL nodes.""" + + def __init__(self, value): + """Create a SparqlNode.""" + self.value = value + + def __unicode__(self): + return self.value + + +class URI(SparqlNode): """Representation of URI result type."""
def __init__(self, data, entity_url, **kwargs): @@ -132,7 +144,7 @@
@type data: dict """ - self.value = data.get('value') + super(URI, self).__init__(data.get('value')) self.entity_url = entity_url
def getID(self): @@ -147,14 +159,12 @@ else: return None
- def __str__(self): - return self.value - + @py2_encode_utf_8 def __repr__(self): return '<' + self.value + '>'
-class Literal(object): +class Literal(SparqlNode): """Representation of RDF literal result type."""
def __init__(self, data, **kwargs): @@ -163,13 +173,11 @@
@type data: dict """ + super(Literal, self).__init__(data.get('value')) self.type = data.get('datatype') self.language = data.get('xml:lang') - self.value = data.get('value')
- def __str__(self): - return self.value - + @py2_encode_utf_8 def __repr__(self): if self.type: return self.value + '^^' + self.type @@ -178,7 +186,7 @@ return self.value
-class Bnode(object): +class Bnode(SparqlNode): """Representation of blank node."""
def __init__(self, data, **kwargs): @@ -187,12 +195,11 @@
@type data: dict """ - self.value = data['value'] + super(Bnode, self).__init__(data.get('value'))
- def __str__(self): - return self.value - + @py2_encode_utf_8 def __repr__(self): return "_:" + self.value
+ VALUE_TYPES = {'uri': URI, 'literal': Literal, 'bnode': Bnode} diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py index e1642dd..5e4cb80 100644 --- a/pywikibot/tools/__init__.py +++ b/pywikibot/tools/__init__.py @@ -159,18 +159,21 @@ yield
-class UnicodeMixin(object): +def py2_encode_utf_8(func): + """Decorator to optionally encode the string result of a function on Python 2.x.""" + if PY2: + return lambda s: func(s).encode('utf-8') + else: + return func
+ +class UnicodeMixin(object): """Mixin class to add __str__ method in Python 2 or 3."""
- if not PY2: - def __str__(self): - """Return the unicode representation as the str representation.""" - return self.__unicode__() - else: - def __str__(self): - """Return the str representation of the UTF-8 encoded Unicode.""" - return self.__unicode__().encode('utf8') + @py2_encode_utf_8 + def __str__(self): + """Return the unicode representation as the str representation.""" + return self.__unicode__()
# From http://python3porting.com/preparing.html diff --git a/tests/sparql_tests.py b/tests/sparql_tests.py index 26a0b7b..94a078e 100644 --- a/tests/sparql_tests.py +++ b/tests/sparql_tests.py @@ -8,6 +8,7 @@ import sys
import pywikibot.data.sparql as sparql +from pywikibot.tools import UnicodeType
from tests.aspects import unittest, TestCase
@@ -166,6 +167,54 @@ res = q.ask('ASK { ?x ?y ?z }') self.assertFalse(res)
+ +class Shared(object): + """Shared test placeholder.""" + + class SparqlNodeTests(TestCase): + """Tests encoding issues.""" + + net = False + object_under_test = None + + def test_is_sparql_node(self): + """Object should be a SparqlNode.""" + self.assertIsInstance(self.object_under_test, sparql.SparqlNode) + + def test__repr__returnsStringType(self): + """__repr__ should return type str.""" + self.assertIsInstance(self.object_under_test.__repr__(), str) + + def test__str__returnsStringType(self): + """__str__ should return type str.""" + self.assertIsInstance(self.object_under_test.__str__(), str) + + def test__unicode__returnsUnicodeType(self): + """__unicode__ should return type unicode.""" + self.assertIsInstance(self.object_under_test.__unicode__(), UnicodeType) + + +class LiteralTests(Shared.SparqlNodeTests): + """Tests for sparql.Literal.""" + + net = False + object_under_test = sparql.Literal({'datatype': '', 'lang': 'en', 'value': 'value'}) + + +class BnodeTests(Shared.SparqlNodeTests): + """Tests for sparql.Bnode.""" + + net = False + object_under_test = sparql.Bnode({'value': 'Foo'}) + + +class URITests(Shared.SparqlNodeTests): + """Tests for sparql.URI.""" + + net = False + object_under_test = sparql.URI({'value': 'http://foo.com%27%7D, 'http://bar.com') + + if __name__ == '__main__': # pragma: no cover try: unittest.main()
pywikibot-commits@lists.wikimedia.org