jenkins-bot has submitted this change. (
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1353442?usp=email )
Change subject: family: Cache obsolete codes and interwiki removals
......................................................................
family: Cache obsolete codes and interwiki removals
Cache the obsolete-code mapping and interwiki removal set on each
concrete family class to avoid rebuilding them on every access.
Expose both as class properties returning immutable values, preserving
obsolete's read-only behavior on instances. Keep cached mapping proxies
out of instance state so families and sites remain pickleable. Check
each class's own namespace to keep inherited family caches separate.
Change-Id: I047db34efb81e2901b4f6e41f3bc0df28ca5dcc4
---
M pywikibot/family.py
M tests/family_tests.py
2 files changed, 21 insertions(+), 6 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/family.py b/pywikibot/family.py
index dc36b36..66afc3d 100644
--- a/pywikibot/family.py
+++ b/pywikibot/family.py
@@ -746,17 +746,22 @@
"""
return putText
- @property
- def obsolete(self) -> types.MappingProxyType[str, str | None]:
+ @classproperty
+ def obsolete(cls) -> types.MappingProxyType[str, str | None]:
"""Old codes that are not part of the family.
Interwiki replacements override removals for the same code.
+ .. version-changed:: 11.9
+ Changed to a cached class property.
+
:return: Mapping of old codes to new codes (or None)
"""
- data = dict.fromkeys(self.interwiki_removals)
- data.update(self.code_aliases)
- return types.MappingProxyType(data)
+ if '_obsolete' not in cls.__dict__:
+ data = dict.fromkeys(cls.interwiki_removals)
+ data.update(cls.code_aliases)
+ cls._obsolete = types.MappingProxyType(data)
+ return cls._obsolete
@classproperty
def domains(cls) -> set[str]:
@@ -798,7 +803,10 @@
.. version-changed:: 8.2
changed from list to invariant frozenset.
"""
- return frozenset(cls.removed_wikis + cls.closed_wikis)
+ if '_interwiki_removals' not in cls.__dict__:
+ cls._interwiki_removals = frozenset(
+ cls.removed_wikis + cls.closed_wikis)
+ return cls._interwiki_removals
class SingleSiteFamily(Family):
diff --git a/tests/family_tests.py b/tests/family_tests.py
index e302d99..dbf476d 100755
--- a/tests/family_tests.py
+++ b/tests/family_tests.py
@@ -7,6 +7,7 @@
"""Tests for the family module."""
from __future__ import annotations
+import pickle
import unittest
import warnings
from collections.abc import Mapping
@@ -132,8 +133,11 @@
with suppress_warnings(msg, FutureWarning):
self.assertIn('dk', family.interwiki_replacements)
+ self.assertIs(pickle.loads(pickle.dumps(family)), family)
+
def test_obsolete_from_attributes(self) -> None:
"""Test obsolete property for given class attributes."""
+ self.assertEqual(Family.interwiki_removals, frozenset())
# Construct a temporary family and instantiate it
family = type('TempFamily', (Family,), {})()
@@ -147,9 +151,12 @@
family = type('TempFamily', (Family,),
{'code_aliases': {'a': 'b'}, 'closed_wikis': ['c']})()
self.assertEqual(family.obsolete, {'a': 'b', 'c': None})
+ self.assertIs(type(family).obsolete, family.obsolete)
with suppress_warnings(msg, FutureWarning):
self.assertEqual(family.interwiki_replacements, {'a': 'b'})
self.assertEqual(family.interwiki_removals, frozenset('c'))
+ self.assertIs(type(family).interwiki_removals,
+ family.interwiki_removals)
def test_obsolete_readonly(self) -> None:
"""Test obsolete result not updatable."""
--
To view, visit
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1353442?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.wikimedia.org/r/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I047db34efb81e2901b4f6e41f3bc0df28ca5dcc4
Gerrit-Change-Number: 1353442
Gerrit-PatchSet: 5
Gerrit-Owner: Mahveotm <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]