jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/832739 )

Change subject: [IMPR] raise TypeError in AliasesDict.normalizeData if data 
value is not a list
......................................................................

[IMPR] raise TypeError in AliasesDict.normalizeData if data value is not a list

Also update wikibase documentation

Bug: T318034
Change-Id: Iec54152b97efe2987f67c8274ba3f8fb7ebffc53
---
M pywikibot/page/_collections.py
M pywikibot/page/_wikibase.py
2 files changed, 116 insertions(+), 55 deletions(-)

Approvals:
  Xqt: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/pywikibot/page/_collections.py b/pywikibot/page/_collections.py
index cbf9c6c..cd8af8e 100644
--- a/pywikibot/page/_collections.py
+++ b/pywikibot/page/_collections.py
@@ -149,8 +149,12 @@
     def normalizeData(cls, data: dict) -> dict:
         """Helper function to expand data into the Wikibase API structure.

+        .. versionchanged:: 7.7
+           raises TypeError *data* value is not a list.
+
         :param data: Data to normalize
         :return: The dict with normalized data
+        :raises TypeError: data values must be a list
         """
         norm_data = {}
         for key, values in data.items():
@@ -162,6 +166,11 @@
                     else:
                         strings.append(value)
                 norm_data[key] = strings
+            else:
+                raise TypeError(
+                    "Unsupported value type {!r} for '{}'; list expected."
+                    .format(type(values).__name__, values))
+
         return norm_data

     def toJSON(self, diffto: Optional[dict] = None) -> dict:
diff --git a/pywikibot/page/_wikibase.py b/pywikibot/page/_wikibase.py
index 4193764..a01ac8e 100644
--- a/pywikibot/page/_wikibase.py
+++ b/pywikibot/page/_wikibase.py
@@ -18,10 +18,10 @@
 from collections import OrderedDict, defaultdict
 from contextlib import suppress
 from itertools import chain
-from typing import Any, Optional
+from typing import Any, Optional, Union

 import pywikibot
-from pywikibot.backports import Dict
+from pywikibot.backports import Dict, List
 from pywikibot.exceptions import (
     APIError,
     EntityTypeUnknownError,
@@ -63,6 +63,12 @@
 )


+ALIASES_TYPE = Dict[Union[str, pywikibot.APISite], List[str]]
+LANGUAGE_TYPE = Dict[Union[str, pywikibot.APISite], str]
+SITELINK_TYPE = Union['pywikibot.page.BasePage', 'pywikibot.page.BaseLink',
+                      Dict[str, str]]
+
+
 class WikibaseEntity:

     """
@@ -272,12 +278,22 @@
             data[key] = value
         return data

-    def editEntity(self, data=None, **kwargs) -> None:
-        """
-        Edit an entity using Wikibase wbeditentity API.
+    def editEntity(
+        self,
+        data: Union[LANGUAGE_TYPE, ALIASES_TYPE, SITELINK_TYPE, None] = None,
+        **kwargs
+    ) -> None:
+        """Edit an entity using Wikibase ``wbeditentity`` API.
+
+        This function is wrapped around by:
+         - :meth:`editLabels`
+         - :meth:`editDescriptions`
+         - :meth:`editAliases`
+         - :meth:`ItemPage.setSitelinks`
+
+         .. seealso:: :meth:`WikibasePage.editEntity`

         :param data: Data to be saved
-        :type data: dict, or None to save the current content of the entity.
         """
         if data is None:
             data = self.toJSON(diffto=getattr(self, '_content', None))
@@ -589,62 +605,96 @@
         self.clear_cache()

     @allow_asynchronous
-    def editEntity(self, data=None, **kwargs) -> None:
-        """
-        Edit an entity using Wikibase wbeditentity API.
+    def editEntity(
+        self,
+        data: Union[LANGUAGE_TYPE, ALIASES_TYPE, SITELINK_TYPE, None] = None,
+        **kwargs: Any
+    ) -> None:
+        """Edit an entity using Wikibase ``wbeditentity`` API.

         This function is wrapped around by:
-         - editLabels
-         - editDescriptions
-         - editAliases
-         - ItemPage.setSitelinks
+         - :meth:`editLabels`
+         - :meth:`editDescriptions`
+         - :meth:`editAliases`
+         - :meth:`ItemPage.setSitelinks`
+
+        It supports *asynchronous* and *callback* keyword arguments. The
+        callback function is intended for use by bots that need to keep
+        track of which saves were successful. The minimal callback
+        function signature is::
+
+          def my_callback(page: WikibasePage, err: Optional[Exception]) -> Any:
+
+        The arguments are:
+
+        ``page``
+            a :class:`WikibasePage` object
+
+        ``err``
+            an Exception instance, which will be None if the page was
+            saved successfully
+
+        .. seealso:: :meth:`WikibaseEntity.editEntity`

         :param data: Data to be saved
-        :type data: dict, or None to save the current content of the entity.
-        :keyword asynchronous: if True, launch a separate thread to edit
-            asynchronously
-        :type asynchronous: bool
-        :keyword callback: a callable object that will be called after the
-            entity has been updated. It must take two arguments: (1) a
-            WikibasePage object, and (2) an exception instance, which will be
-            None if the page was saved successfully. This is intended for use
-            by bots that need to keep track of which saves were successful.
-        :type callback: callable
+        :keyword bool asynchronous: if True, launch a separate thread to
+            edit asynchronously
+        :keyword Callable[[WikibasePage, Optional[Exception]], Any] callback:
+            a callable object that will be called after the entity has
+            been updated. It must take two arguments, see above.
         """
-        # kept for the decorator
+        # kept for the decorator which provides the keyword arguments
         super().editEntity(data, **kwargs)

-    def editLabels(self, labels, **kwargs) -> None:
-        """
-        Edit entity labels.
+    def editLabels(self, labels: LANGUAGE_TYPE, **kwargs) -> None:
+        """Edit entity labels.

-        Labels should be a dict, with the key
-        as a language or a site object. The
-        value should be the string to set it to.
-        You can set it to '' to remove the label.
+        *labels* should be a dict, with the key as a language or a site
+        object. The value should be the string to set it to. You can set
+        it to ``''`` to remove the label.
+
+        Refer :meth:`editEntity` for *asynchronous* and *callback* usage.
+
+        Usage:
+
+        >>> repo = pywikibot.Site('wikidata:test')
+        >>> item = pywikibot.ItemPage(repo, 'Q68')
+        >>> item.editLabels({'en': 'Test123'})  # doctest: +SKIP
         """
         data = {'labels': labels}
         self.editEntity(data, **kwargs)

-    def editDescriptions(self, descriptions, **kwargs) -> None:
-        """
-        Edit entity descriptions.
+    def editDescriptions(self, descriptions: LANGUAGE_TYPE, **kwargs) -> None:
+        """Edit entity descriptions.

-        Descriptions should be a dict, with the key
-        as a language or a site object. The
-        value should be the string to set it to.
-        You can set it to '' to remove the description.
+        *descriptions* should be a dict, with the key as a language or a
+        site object. The value should be the string to set it to. You
+        can set it to ``''`` to remove the description.
+
+        Refer :meth:`editEntity` for *asynchronous* and *callback* usage.
+
+        Usage:
+
+        >>> repo = pywikibot.Site('wikidata:test')
+        >>> item = pywikibot.ItemPage(repo, 'Q68')
+        >>> item.editDescriptions({'en': 'Pywikibot test'})  # doctest: +SKIP
         """
         data = {'descriptions': descriptions}
         self.editEntity(data, **kwargs)

-    def editAliases(self, aliases, **kwargs) -> None:
-        """
-        Edit entity aliases.
+    def editAliases(self, aliases: ALIASES_TYPE, **kwargs) -> None:
+        """Edit entity aliases.

-        Aliases should be a dict, with the key
-        as a language or a site object. The
-        value should be a list of strings.
+        *aliases* should be a dict, with the key as a language or a site
+        object. The value should be a list of strings.
+
+        Refer :meth:`editEntity` for *asynchronous* and *callback* usage.
+
+        Usage:
+
+        >>> repo = pywikibot.Site('wikidata:test')
+        >>> item = pywikibot.ItemPage(repo, 'Q68')
+        >>> item.editAliases({'en': ['pwb test item']})  # doctest: +SKIP
         """
         data = {'aliases': aliases}
         self.editEntity(data, **kwargs)
@@ -1004,12 +1054,13 @@

         return self.sitelinks[site].canonical_title()

-    def setSitelink(self, sitelink, **kwargs) -> None:
-        """
-        Set sitelinks. Calls setSitelinks().
+    def setSitelink(self, sitelink: SITELINK_TYPE, **kwargs) -> None:
+        """Set sitelinks. Calls :meth:`setSitelinks`.

-        A sitelink can be a Page object, a BaseLink object
-        or a {'site':dbname,'title':title} dictionary.
+        A *sitelink* can be a Page object, a BaseLink object or a
+        ``{'site': dbname, 'title': title}`` dictionary.
+
+        Refer :meth:`editEntity` for *asynchronous* and *callback* usage.
         """
         self.setSitelinks([sitelink], **kwargs)

@@ -1034,13 +1085,14 @@
             data.append({'site': site, 'title': ''})
         self.setSitelinks(data, **kwargs)

-    def setSitelinks(self, sitelinks, **kwargs) -> None:
-        """
-        Set sitelinks.
+    def setSitelinks(self, sitelinks: List[SITELINK_TYPE], **kwargs) -> None:
+        """Set sitelinks.

-        Sitelinks should be a list. Each item in the
-        list can either be a Page object, a BaseLink object, or a dict
-        with a value for 'site' and 'title'.
+        *sitelinks* should be a list. Each item in the list can either
+        be a Page object, a BaseLink object, or a dict with key for
+        'site' and a value for 'title'.
+
+        Refer :meth:`editEntity` for *asynchronous* and *callback* usage.
         """
         data = {'sitelinks': sitelinks}
         self.editEntity(data, **kwargs)

--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/832739
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Iec54152b97efe2987f67c8274ba3f8fb7ebffc53
Gerrit-Change-Number: 832739
Gerrit-PatchSet: 3
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: JJMC89 <[email protected]>
Gerrit-Reviewer: Matěj Suchánek <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to