jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/525079 )
Change subject: [FEAT] Refactor Wikibase entity namespace handling ......................................................................
[FEAT] Refactor Wikibase entity namespace handling
Bug: T160395 Change-Id: I39fb245a92e34788ae05ee46c4963c409455379a --- M pywikibot/page.py M pywikibot/pagegenerators.py M pywikibot/site.py 3 files changed, 52 insertions(+), 35 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/page.py b/pywikibot/page.py index e96b27b..db5402a 100644 --- a/pywikibot/page.py +++ b/pywikibot/page.py @@ -3897,11 +3897,10 @@
if 'entity_type' in kwargs: entity_type = kwargs.pop('entity_type') - if entity_type == 'item': - entity_type_ns = site.item_namespace - elif entity_type == 'property': - entity_type_ns = site.property_namespace - else: + try: + entity_type_ns = site.get_namespace_for_entity_type( + entity_type) + except pywikibot.EntityTypeUnknownException: raise ValueError('Wikibase entity type "%s" unknown' % entity_type)
diff --git a/pywikibot/pagegenerators.py b/pywikibot/pagegenerators.py index 5d142a5..d524fe0 100644 --- a/pywikibot/pagegenerators.py +++ b/pywikibot/pagegenerators.py @@ -2976,12 +2976,11 @@ data = query_object.get_items(query, item_name=item_name, result_type=result_type) - items_pages = (pywikibot.ItemPage(repo, item) for item in data - if pywikibot.ItemPage.is_valid_id(item)) + entities = (repo.get_entity_for_entity_id(entity) for entity in data) if isinstance(site, pywikibot.site.DataSite): - return items_pages + return entities
- return WikidataPageFromItemGenerator(items_pages, site) + return WikidataPageFromItemGenerator(entities, site)
def WikibaseSearchItemPageGenerator( diff --git a/pywikibot/site.py b/pywikibot/site.py index eb5c1ac..97b15bc 100644 --- a/pywikibot/site.py +++ b/pywikibot/site.py @@ -58,6 +58,7 @@ NoCreateError, NoPage, NoUsername, + NoWikibaseEntity, PageCreatedConflict, PageDeletedConflict, PageRelatedError, @@ -7679,18 +7680,31 @@
def _cache_entity_namespaces(self): """Find namespaces for each known wikibase entity type.""" - self._item_namespace = False - self._property_namespace = False + self._entity_namespaces = {} + for entity_type in self._type_to_class.keys(): + for namespace in self.namespaces.values(): + if not hasattr(namespace, 'defaultcontentmodel'): + continue
- for namespace in self.namespaces.values(): - if not hasattr(namespace, 'defaultcontentmodel'): - continue + content_model = namespace.defaultcontentmodel + if content_model == ('wikibase-' + entity_type): + self._entity_namespaces[entity_type] = namespace + break
- content_model = namespace.defaultcontentmodel - if content_model == 'wikibase-item': - self._item_namespace = namespace - elif content_model == 'wikibase-property': - self._property_namespace = namespace + def get_namespace_for_entity_type(self, entity_type): + """ + Return namespace for given entity type. + + @return: corresponding namespace + @rtype: Namespace + """ + if not hasattr(self, '_entity_namespaces'): + self._cache_entity_namespaces() + if entity_type in self._entity_namespaces: + return self._entity_namespaces[entity_type] + raise EntityTypeUnknownException( + '{0!r} does not support entity type "{1}"' + .format(self, entity_type))
@property def item_namespace(self): @@ -7701,14 +7715,8 @@ @rtype: Namespace """ if self._item_namespace is None: - self._cache_entity_namespaces() - - if isinstance(self._item_namespace, Namespace): - return self._item_namespace - else: - raise EntityTypeUnknownException( - '%r does not support entity type "item"' - % self) + self._item_namespace = self.get_namespace_for_entity_type('item') + return self._item_namespace
@property def property_namespace(self): @@ -7719,14 +7727,23 @@ @rtype: Namespace """ if self._property_namespace is None: - self._cache_entity_namespaces() + self._property_namespace = self.get_namespace_for_entity_type( + 'property') + return self._property_namespace
- if isinstance(self._property_namespace, Namespace): - return self._property_namespace - else: - raise EntityTypeUnknownException( - '%r does not support entity type "property"' - % self) + def get_entity_for_entity_id(self, entity_id): + """ + Return a new instance for given entity id. + + @raises NoWikibaseEntity: there is no entity with the id + @return: a WikibaseEntity subclass + @rtype: WikibaseEntity + """ + for cls in self._type_to_class.values(): + if cls.is_valid_id(entity_id): + return cls(self, entity_id) + + raise NoWikibaseEntity(pywikibot.page.WikibaseEntity(self, entity_id))
@property @need_version('1.28-wmf.3') @@ -7926,6 +7943,8 @@ @param groupsize: how many pages to query at a time @type groupsize: int """ + if not hasattr(self, '_entity_namespaces'): + self._cache_entity_namespaces() for sublist in itergroup(pagelist, groupsize): req = {'ids': [], 'titles': [], 'sites': []} for p in sublist: @@ -7935,7 +7954,7 @@ req[key].append(ident[key]) else: if p.site == self and p.namespace() in ( - self.item_namespace, self.property_namespace): + self._entity_namespaces.values()): req['ids'].append(p.title(with_ns=False)) else: assert p.site.has_data_repository, \