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

Change subject: [IMPR] replace FrozenDict with frozenmap
......................................................................

[IMPR] replace FrozenDict with frozenmap

- Add a new frozenmap Mapping. See PEP 603 for naming.
  frozenmap does not support methods like pop(), popitem()
  or setdefault() like FrozenDict does which leads to changed content.
- replace FrozenDict with frozenmap in family.py and archivebot.py
- update family_tests.py
- deprecate tools.FrozenDict

Change-Id: Iec722ce846a0d43d8d939c081ec36fa4e5619c81
---
M pywikibot/family.py
M pywikibot/tools/__init__.py
M scripts/archivebot.py
M tests/family_tests.py
4 files changed, 58 insertions(+), 34 deletions(-)

Approvals:
  Mpaa: Looks good to me, but someone else must approve
  Xqt: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/pywikibot/family.py b/pywikibot/family.py
index d509e77..c90d622 100644
--- a/pywikibot/family.py
+++ b/pywikibot/family.py
@@ -22,7 +22,7 @@
 from pywikibot import config
 from pywikibot.exceptions import UnknownFamily, FamilyMaintenanceWarning
 from pywikibot.tools import (
-    classproperty, deprecated, deprecated_args, FrozenDict,
+    classproperty, deprecated, deprecated_args, frozenmap,
     issue_deprecation_warning, ModuleDeprecationWrapper, PYTHON_VERSION,
     remove_last_args,
 )
@@ -1118,10 +1118,7 @@
         """
         data = {code: None for code in self.interwiki_removals}
         data.update(self.interwiki_replacements)
-        return FrozenDict(data,
-                          'Family.obsolete not updatable; '
-                          'use Family.interwiki_removals '
-                          'and Family.interwiki_replacements')
+        return frozenmap(data)

     @obsolete.setter
     def obsolete(self, data):
@@ -1357,8 +1354,7 @@
     @classproperty
     def interwiki_replacements(cls):
         """Return an interwiki code replacement mapping."""
-        rv = cls.code_aliases.copy()
-        return FrozenDict(rv)
+        return frozenmap(cls.code_aliases)

     def shared_image_repository(self, code):
         """Return Wikimedia Commons as the shared image repository."""
diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py
index 06514d7..49e4451 100644
--- a/pywikibot/tools/__init__.py
+++ b/pywikibot/tools/__init__.py
@@ -244,7 +244,7 @@
         return repr(self.__dict__)


-class FrozenDict(dict):
+class _FrozenDict(dict):

     """
     Frozen dict, preventing write after initialisation.
@@ -274,6 +274,38 @@
     __setitem__ = update


+class frozenmap(Mapping):  # noqa:  N801
+
+    """Frozen mapping, preventing write after initialisation."""
+
+    def __init__(self, data=(), **kwargs):
+        """Initialize data in same ways like a dict."""
+        self.__data = {}
+        if isinstance(data, Mapping):
+            for key in data:
+                self.__data[key] = data[key]
+        elif hasattr(data, 'keys'):
+            for key in data.keys():
+                self.__data[key] = data[key]
+        else:
+            for key, value in data:
+                self.__data[key] = value
+        for key, value in kwargs.items():
+            self.__data[key] = value
+
+    def __getitem__(self, key):
+        return self.__data[key]
+
+    def __iter__(self):
+        return iter(self.__data)
+
+    def __len__(self):
+        return len(self.__data)
+
+    def __repr__(self):
+        return '{}({!r})'.format(self.__class__.__name__, self.__data)
+
+
 class LazyRegex:

     """
@@ -1790,3 +1822,9 @@
             option_msg += '\n' + ' ' * indent
         option_msg += option_line
     return '{} ({}):'.format(message, option_msg)
+
+
+wrapper = ModuleDeprecationWrapper(__name__)
+wrapper._add_deprecated_attr('FrozenDict', _FrozenDict,
+                             replacement_name='tools.frozenmap',
+                             since='20201109', future_warning=True)
diff --git a/scripts/archivebot.py b/scripts/archivebot.py
index 04cca3f..bb9783b 100755
--- a/scripts/archivebot.py
+++ b/scripts/archivebot.py
@@ -112,7 +112,7 @@
 from pywikibot.textlib import (extract_sections, findmarker, TimeStripper,
                                to_local_digits)
 from pywikibot.tools import (
-    deprecated, FrozenDict, issue_deprecation_warning, PYTHON_VERSION,
+    deprecated, frozenmap, issue_deprecation_warning, PYTHON_VERSION,
 )

 if PYTHON_VERSION >= (3, 9):
@@ -127,14 +127,14 @@

 ZERO = datetime.timedelta(0)

-MW_KEYS = FrozenDict({
+MW_KEYS = frozenmap({
     's': 'seconds',
     'h': 'hours',
     'd': 'days',
     'w': 'weeks',
     'y': 'years',
     # 'months' and 'minutes' were removed because confusion outweighs merit
-}, 'MW_KEYS is a dict constant')
+})


 class ArchiveBotSiteConfigError(pywikibot.Error):
diff --git a/tests/family_tests.py b/tests/family_tests.py
index 8655a4f..626f9e2 100644
--- a/tests/family_tests.py
+++ b/tests/family_tests.py
@@ -5,6 +5,7 @@
 #
 # Distributed under the terms of the MIT license.
 #
+from collections.abc import Mapping
 from contextlib import suppress

 import pywikibot.site
@@ -22,11 +23,8 @@
     """Test cases for Family methods."""

     UNKNOWNFAMILY_RE = 'Family unknown does not exist'
-    FAMILY_TYPEERROR_RE = (
-        'Family.obsolete not updatable; '
-        'use Family.interwiki_removals and Family.interwiki_replacements')
-    FROZENSET_TYPEERROR_RE = ("'frozenset' object does not support item "
-                              'assignment')
+    FROZEN_TYPEERROR_RE = r"'frozen\w+' object does not support item " \
+                          'assignment'
     net = False

     def test_family_load_valid(self):
@@ -110,7 +108,7 @@
     def test_get_obsolete_wp(self):
         """Test three types of obsolete codes."""
         family = Family.load('wikipedia')
-        self.assertIsInstance(family.obsolete, dict)
+        self.assertIsInstance(family.obsolete, Mapping)
         # redirected code (see site tests test_alias_code_site)
         self.assertEqual(family.obsolete['dk'], 'da')
         # closed/locked site (see site tests test_locked_site)
@@ -136,27 +134,19 @@
     def test_obsolete_readonly(self):
         """Test obsolete result not updatable."""
         family = Family.load('wikipedia')
-        self.assertRaisesRegex(
-            TypeError,
-            self.FAMILY_TYPEERROR_RE,
-            family.obsolete.update,
-            {})
-        self.assertRaisesRegex(
-            TypeError,
-            self.FAMILY_TYPEERROR_RE,
-            family.obsolete.__setitem__,
-            'a',
-            'b')
+        with self.assertRaisesRegex(
+            AttributeError,
+                "'frozenmap' object has no attribute 'update'"):
+            family.obsolete.update({})
+
+        with self.assertRaisesRegex(TypeError, self.FROZEN_TYPEERROR_RE):
+            family.obsolete['a'] = 'b'

     def test_WikimediaFamily_obsolete_readonly(self):
         """Test WikimediaFamily obsolete is readonly."""
         family = Family.load('wikipedia')
-        self.assertRaisesRegex(
-            TypeError,
-            self.FROZENSET_TYPEERROR_RE,
-            family.__setattr__,
-            'obsolete',
-            {'a': 'b', 'c': None})
+        with self.assertRaisesRegex(TypeError, self.FROZEN_TYPEERROR_RE):
+            family.obsolete = {'a': 'b', 'c': None}


 class TestFamilyUrlRegex(PatchingTestCase):

--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/640103
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: Iec722ce846a0d43d8d939c081ec36fa4e5619c81
Gerrit-Change-Number: 640103
Gerrit-PatchSet: 4
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: D3r1ck01 <[email protected]>
Gerrit-Reviewer: Mpaa <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikibot-commits

Reply via email to