jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/938812 )
Change subject: [bugfix] Add 'yue' code_aliases to wikipedia_family.py ......................................................................
[bugfix] Add 'yue' code_aliases to wikipedia_family.py
- call a __post_init__() class method in Family.__new__ class if present - raise a RuntimeError if the __post_init__() method is not a class method - update deprecation message when using Family.__init__() - add a __post_init__() class method to wikipedia_family.py and wiktionary_family.py to add the 'yue'/'zh-yue' alias to cls.code_aliases - add __init__() and __post_init__ descriptions to documentation
Bug: T341960 Change-Id: Ie8dbb0b5f3c9a40cd1f3bf61e64f7e8f1bbf1076 --- M docs/api_ref/family.rst M pywikibot/family.py M pywikibot/families/wiktionary_family.py M pywikibot/families/wikipedia_family.py 4 files changed, 97 insertions(+), 4 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/docs/api_ref/family.rst b/docs/api_ref/family.rst index 042b337..3a61f22 100644 --- a/docs/api_ref/family.rst +++ b/docs/api_ref/family.rst @@ -4,3 +4,48 @@
.. automodule:: family :synopsis: Objects representing MediaWiki families + + .. autoclass:: Family + + .. method:: __init__() + + Initializer + + .. deprecated:: 3.0.20180710 + Use :meth:`__post_init__` instead. + .. versionchanged:: 8.3 + A FutureWarning is printed instead of a ``NotImplementedWarning``. + The deprecation may be removed in a future release and a + ``RuntimeError`` will be thrown instead. + + .. method:: __post_init__() + :classmethod: + + Post-init processing for Family class. + + The allocator will call this class method after the Family class was + created and no :meth:`__init__()` method is used and ``__post_init__()`` + is defined in your Family subclass. This can be used for example to + expand Family attribute lists. + + .. warning:: The ``__post_init__()`` classmethod cannot be inherited + from a superclass. The current family file class is considered + only. + + .. caution:: Never modify the current attributes directly; always use + a copy. Otherwise the base class is modified which leads to + unwanted side-effects. + + **Example:** + + .. code-block:: Python + + @classmethod + def __post_init__(cls): + """Add 'yue' code alias.""" + aliases = cls.code_aliases.copy() + aliases['yue'] = 'zh-yue' + cls.code_aliases = aliases + + .. versionadded:: 8.3 + diff --git a/pywikibot/families/wikipedia_family.py b/pywikibot/families/wikipedia_family.py index a972c83..e7a542c 100644 --- a/pywikibot/families/wikipedia_family.py +++ b/pywikibot/families/wikipedia_family.py @@ -216,6 +216,16 @@ 'de': ('Archiv',), }
+ @classmethod + def __post_init__(cls): + """Add 'yue' code alias due to :phab:`T341960`. + + .. versionadded:: 8.3 + """ + aliases = cls.code_aliases.copy() + aliases['yue'] = 'zh-yue' + cls.code_aliases = aliases + def encodings(self, code): """Return a list of historical encodings for a specific site.""" # Historic compatibility diff --git a/pywikibot/families/wiktionary_family.py b/pywikibot/families/wiktionary_family.py index eb92bc2..5478747 100644 --- a/pywikibot/families/wiktionary_family.py +++ b/pywikibot/families/wiktionary_family.py @@ -87,3 +87,13 @@ 'ar': ('/شرح', '/doc'), 'sr': ('/док', ), } + + @classmethod + def __post_init__(cls): + """Add 'zh-yue' code alias due to :phab:`T341960`. + + .. versionadded:: 8.3 + """ + aliases = cls.code_aliases.copy() + aliases['zh-yue'] = 'yue' + cls.code_aliases = aliases diff --git a/pywikibot/family.py b/pywikibot/family.py index 6a1e26e..9660c83 100644 --- a/pywikibot/family.py +++ b/pywikibot/family.py @@ -5,6 +5,7 @@ # Distributed under the terms of the MIT license. # import collections +import inspect import logging import string import sys @@ -13,6 +14,7 @@ import warnings from importlib import import_module from itertools import chain +from textwrap import fill from os.path import basename, dirname, splitext from typing import Optional
@@ -55,9 +57,8 @@ """Allocator.""" # any Family class defined in this file are abstract if cls in globals().values(): - raise TypeError( - 'Abstract Family class {} cannot be instantiated; ' - 'subclass it instead'.format(cls.__name__)) + raise TypeError(f'Abstract Family class {cls.__name__} cannot be' + ' instantiated; subclass it instead')
# Override classproperty cls.instance = super().__new__(cls) @@ -67,13 +68,23 @@ if '__init__' in cls.__dict__: # Initializer deprecated. Families should be immutable and any # instance / class modification should go to allocator (__new__). - cls.__init__ = deprecated(cls.__init__) + cls.__init__ = deprecated(instead='__post_init__() classmethod', + since='3.0.20180710')(cls.__init__)
# Invoke initializer immediately and make initializer no-op. # This is to avoid repeated initializer invocation on repeated # invocations of the metaclass's __call__. cls.instance.__init__() cls.__init__ = lambda self: None # no-op + elif '__post_init__' not in cls.__dict__: + pass + elif inspect.ismethod(cls.__post_init__): # classmethod check + cls.__post_init__() + else: + raise RuntimeError(fill( + f'__post_init__() method of {cls.__module__}.{cls.__name__}' + ' class or its superclass must be a classmethod. Please check' + ' your family file.', width=66))
return cls.instance
pywikibot-commits@lists.wikimedia.org