jenkins-bot has submitted this change and it was merged.
Change subject: Class Property as super of PropertyPage and Claim ......................................................................
Class Property as super of PropertyPage and Claim
- move 'types' structure into Property to be expanded and reused - add Property.type getter - use 'globe-coordinate' consistently - deprecate Property.getType, which returns 'globecoordinate'
Change-Id: Id63969c045ac63a5b0276f696ce5797c4ee8b6df --- M pywikibot/page.py M pywikibot/site.py M tests/wikibase_tests.py 3 files changed, 98 insertions(+), 38 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/page.py b/pywikibot/page.py index bb120c6..b03edaa 100644 --- a/pywikibot/page.py +++ b/pywikibot/page.py @@ -2765,12 +2765,53 @@ self.repo.mergeItems(fromItem=self, toItem=item, **kwargs)
-class PropertyPage(WikibasePage): +class Property(): + types = {'wikibase-item': ItemPage, + 'string': basestring, + 'commonsMedia': ImagePage, + 'globe-coordinate': pywikibot.Coordinate, + 'url': basestring, + 'time': pywikibot.WbTime, + 'quantity': pywikibot.WbQuantity, + } + + def __init__(self, site, id=None): + self.repo = site + self.id = id.upper() + + @property + def type(self): + """ + Return the type of this property + """ + if not hasattr(self, '_type'): + self._type = self.repo.getPropertyType(self) + return self._type + + @deprecated("Property.type") + def getType(self): + """ + Return the type of this property + It returns 'globecoordinate' for type 'globe-coordinate' + in order to be backwards compatible. See + https://gerrit.wikimedia.org/r/#/c/135405/ for background. + """ + if self.type == 'globe-coordinate': + return 'globecoordinate' + else: + return self._type + + def getID(self): + return self.id + + +class PropertyPage(WikibasePage, Property): """ Any page in the property namespace Should be created as: PropertyPage(DataSite, 'Property:P21') """ + def __init__(self, source, title=u""): """ @param source: data repository property is on @@ -2778,6 +2819,7 @@ @param title: page name of property, like "Property:P##" """ WikibasePage.__init__(self, source, title, ns=120) + Property.__init__(self, source, title) self.id = self.title(withNamespace=False).upper() if not self.id.startswith(u'P'): raise ValueError(u"'%s' is not a property page!" % self.title()) @@ -2786,15 +2828,6 @@ if force or not hasattr(self, '_content'): WikibasePage.get(self, force=force, *args) self.type = self._content['datatype'] - - def getType(self): - """ - Returns the type that this item uses - Examples: item, commons media file, StringValue, NumericalValue - """ - if not hasattr(self, 'type'): - self.type = self.repo.getPropertyType(self) - return self.type
def newClaim(self, *args, **kwargs): """ @@ -2816,7 +2849,7 @@ raise ValueError(u"'%s' is not a query page!" % self.title())
-class Claim(PropertyPage): +class Claim(Property): """ Claims are standard claims as well as references. """ @@ -2833,7 +2866,7 @@ @param isReference: whether specified claim is a reference @param isQualifier: whether specified claim is a qualifier """ - PropertyPage.__init__(self, site, 'Property:' + pid) + Property.__init__(self, site, pid) self.snak = snak self.hash = hash self.isReference = isReference @@ -2864,15 +2897,15 @@ claim.snaktype = data['mainsnak']['snaktype'] if claim.getSnakType() == 'value': value = data['mainsnak']['datavalue']['value'] - if claim.getType() == 'wikibase-item': + if claim.type == 'wikibase-item': claim.target = ItemPage(site, 'Q' + str(value['numeric-id'])) - elif claim.getType() == 'commonsMedia': + elif claim.type == 'commonsMedia': claim.target = ImagePage(site.image_repository(), value) - elif claim.getType() == 'globecoordinate': + elif claim.type == 'globe-coordinate': claim.target = pywikibot.Coordinate.fromWikibase(value, site) - elif claim.getType() == 'time': + elif claim.type == 'time': claim.target = pywikibot.WbTime.fromWikibase(value) - elif claim.getType() == 'quantity': + elif claim.type == 'quantity': claim.target = pywikibot.WbQuantity.fromWikibase(value) else: # This covers string, url types @@ -2919,18 +2952,10 @@ Sets the target to the passed value. There should be checks to ensure type compliance """ - types = {'wikibase-item': ItemPage, - 'string': basestring, - 'commonsMedia': ImagePage, - 'globecoordinate': pywikibot.Coordinate, - 'url': basestring, - 'time': pywikibot.WbTime, - 'quantity': pywikibot.WbQuantity, - } - if self.getType() in types: - if not isinstance(value, types[self.getType()]): - raise ValueError("%s is not type %s." - % (value, str(types[self.getType()]))) + value_class = self.types[self.type] + if not isinstance(value, value_class): + raise ValueError("%s is not type %s." + % (value, value_class)) self.target = value
def changeTarget(self, value=None, snaktype='value', **kwargs): @@ -3047,18 +3072,18 @@ """ Format the target into the proper JSON datavalue that Wikibase wants """ - if self.getType() == 'wikibase-item': + if self.type == 'wikibase-item': value = {'entity-type': 'item', 'numeric-id': self.getTarget().getID(numeric=True)} - elif self.getType() in ('string', 'url'): + elif self.type in ('string', 'url'): value = self.getTarget() - elif self.getType() == 'commonsMedia': + elif self.type == 'commonsMedia': value = self.getTarget().title(withNamespace=False) - elif self.getType() in ('globecoordinate', 'time', 'quantity'): + elif self.type in ('globe-coordinate', 'time', 'quantity'): value = self.getTarget().toWikibase() else: raise NotImplementedError('%s datatype is not supported yet.' - % self.getType()) + % self.type) return value
diff --git a/pywikibot/site.py b/pywikibot/site.py index 2d2d243..ef57dc1 100644 --- a/pywikibot/site.py +++ b/pywikibot/site.py @@ -3728,9 +3728,6 @@ except KeyError: dtype = data['entities'][prop.getID().lower()]['datatype']
- if dtype == 'globe-coordinate': - dtype = 'globecoordinate' - # TODO Fix this return dtype
@must_be(group='user') diff --git a/tests/wikibase_tests.py b/tests/wikibase_tests.py index e84760b..a8b52e1 100644 --- a/tests/wikibase_tests.py +++ b/tests/wikibase_tests.py @@ -49,7 +49,7 @@ self.assertEqual(item2.getID(), 'Q5296') self.assertEqual(item.labels['en'], 'Main Page') prop = pywikibot.PropertyPage(repo, 'Property:P21') - self.assertEqual(prop.getType(), 'wikibase-item') + self.assertEqual(prop.type, 'wikibase-item') self.assertEqual(prop.namespace(), 120) claim = pywikibot.Claim(repo, 'p21') self.assertRaises(ValueError, claim.setTarget, value="test") @@ -234,6 +234,44 @@ self._test_fromPage_noitem(link)
+class TestPropertyPage(PywikibotTestCase): + + def test_property_empty_property(self): + self.assertRaises(pywikibot.Error, pywikibot.PropertyPage, wikidata) + + def test_globe_coordinate(self): + property_page = pywikibot.PropertyPage(wikidata, 'P625') + self.assertEquals(property_page.type, 'globe-coordinate') + self.assertEquals(property_page.getType(), 'globecoordinate') + + claim = pywikibot.Claim(wikidata, 'P625') + self.assertEquals(claim.type, 'globe-coordinate') + self.assertEquals(claim.getType(), 'globecoordinate') + + +class TestClaimSetValue(PywikibotTestCase): + + def test_set_website(self): + claim = pywikibot.Claim(wikidata, 'P856') + self.assertEquals(claim.type, 'url') + claim.setTarget('http://en.wikipedia.org/') + self.assertEquals(claim.target, 'http://en.wikipedia.org/') + + def test_set_date(self): + claim = pywikibot.Claim(wikidata, 'P569') + self.assertEquals(claim.type, 'time') + claim.setTarget(pywikibot.WbTime(year=2001, month=01, day=01)) + self.assertEquals(claim.target.year, 2001) + self.assertEquals(claim.target.month, 1) + self.assertEquals(claim.target.day, 1) + + def test_set_incorrect_target_value(self): + claim = pywikibot.Claim(wikidata, 'P569') + self.assertRaises(ValueError, claim.setTarget, 'foo') + claim = pywikibot.Claim(wikidata, 'P856') + self.assertRaises(ValueError, claim.setTarget, pywikibot.WbTime(2001)) + + class TestLinks(PywikibotTestCase): """Test cases to test links stored in Wikidata""" def setUp(self):
pywikibot-commits@lists.wikimedia.org