jenkins-bot has submitted this change and it was merged.
Change subject: [IMPROV] site: Deprecate self callable namespaces
......................................................................
[IMPROV] site: Deprecate self callable namespaces
This makes calling site.namespaces deprecated. It also removes all
usages of this method and they use now the property directly.
Change-Id: I9c4f73e2d1b6b97eb64797115aeb130f3ecc5c9d
---
M pywikibot/botirc.py
M pywikibot/cosmetic_changes.py
M pywikibot/page.py
M pywikibot/site.py
M pywikibot/tools/__init__.py
M scripts/replicate_wiki.py
M scripts/solve_disambiguation.py
M tests/site_tests.py
M tests/utils.py
9 files changed, 92 insertions(+), 74 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/botirc.py b/pywikibot/botirc.py
index c63f4d0..903b89c 100644
--- a/pywikibot/botirc.py
+++ b/pywikibot/botirc.py
@@ -53,7 +53,7 @@
self.site = site
self.other_ns = re.compile(
u'\x0314\\[\\[\x0307(%s)'
- % u'|'.join(item.custom_name for item in site.namespaces().values()
+ % u'|'.join(item.custom_name for item in site.namespaces.values()
if item != 0))
self.api_url = self.site.apipath()
self.api_url +=
'?action=query&meta=siteinfo&siprop=statistics&format=xml'
diff --git a/pywikibot/cosmetic_changes.py b/pywikibot/cosmetic_changes.py
index 9c471fe..bced95d 100755
--- a/pywikibot/cosmetic_changes.py
+++ b/pywikibot/cosmetic_changes.py
@@ -420,15 +420,15 @@
# wiki links aren't parsed here.
exceptions = ['nowiki', 'comment', 'math',
'pre']
- for nsNumber in self.site.namespaces():
- if nsNumber in (0, 2, 3):
+ for namespace in self.site.namespaces.values():
+ if namespace.id in (0, 2, 3):
# skip main (article) namespace
# skip user namespace, maybe gender is used
continue
# a clone is needed. Won't change the namespace dict
- namespaces = list(self.site.namespace(nsNumber, all=True))
+ namespaces = list(namespace)
thisNs = namespaces.pop(0)
- if nsNumber == 6 and family.name == 'wikipedia':
+ if namespace.id == 6 and family.name == 'wikipedia':
if self.site.code in ('en', 'fr') and \
MediaWikiVersion(self.site.version()) >=
MediaWikiVersion('1.14'):
# do not change "Image" on en-wiki and fr-wiki
diff --git a/pywikibot/page.py b/pywikibot/page.py
index db5a1ef..6542a67 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -672,7 +672,7 @@
# Get target (first template argument)
try:
p = pywikibot.Page(self.site, args[0].strip(), ns=14)
- if p.namespace() == 14:
+ if p.namespace == 14:
self._catredirect = p.title()
else:
pywikibot.warning(
@@ -4722,21 +4722,21 @@
"""
ns_id = self.namespace
ns = self.site.namespaces[ns_id]
- ns_names = list(ns)
if onsite is None:
namespace = ns.canonical_name
else:
# look for corresponding ns in onsite by name comparison
- for name in ns_names:
- onsite_ns = ns.lookup_name(name, namespaces=onsite.namespaces())
- # not found
- if onsite_ns is None:
+ for alias in ns:
+ namespace = Namespace.lookup_name(alias, onsite.namespaces)
+ if namespace:
+ namespace = namespace.custom_name
+ break
+ else:
+ # not found
raise pywikibot.Error(
u'No corresponding namespace found for namespace %s on %s.'
% (self.site.namespaces[ns_id], onsite))
- else:
- namespace = onsite_ns.custom_name
if namespace:
return u'%s:%s' % (namespace, self.title)
diff --git a/pywikibot/site.py b/pywikibot/site.py
index eae3500..ebcd71d 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -491,6 +491,14 @@
return result
+# This class can be removed after self-callability has been removed
+class _NamespacesDict(SelfCallDict):
+
+ """A wrapper to add a deprecation message when
called."""
+
+ _own_desc = 'the namespaces property'
+
+
class BaseSite(ComparableMixin):
"""Site methods that are independent of the communication
interface."""
@@ -694,7 +702,7 @@
def validLanguageLinks(self):
"""Return list of language codes that can be used in interwiki
links."""
- nsnames = [name for name in self.namespaces().values()]
+ nsnames = [name for name in self.namespaces.values()]
return [lang for lang in self.languages()
if first_upper(lang) not in nsnames]
@@ -786,13 +794,16 @@
getNamespaceIndex = redirect_func(ns_index, old_name='getNamespaceIndex',
class_name='BaseSite')
+ def _build_namespaces(self):
+ """Create default namespaces."""
+ use_image_name = MediaWikiVersion(self.version()) <
MediaWikiVersion("1.14")
+ return Namespace.builtin_namespaces(use_image_name)
+
@property
def namespaces(self):
"""Return dict of valid namespaces on this
wiki."""
if not hasattr(self, '_namespaces'):
- use_image_name = MediaWikiVersion(self.version()) <
MediaWikiVersion("1.14")
- self._namespaces = SelfCallDict(
- Namespace.builtin_namespaces(use_image_name))
+ self._namespaces = _NamespacesDict(self._build_namespaces())
return self._namespaces
def ns_normalize(self, value):
@@ -1820,7 +1831,7 @@
self._useroptions['_name'] = (
None if 'anon' in uidata['query']['userinfo']
else
uidata['query']['userinfo']['name'])
- return set(ns for ns in self.namespaces().values() if ns.id >= 0 and
+ return set(ns for ns in self.namespaces.values() if ns.id >= 0 and
self._useroptions['searchNs{0}'.format(ns.id)] in
['1', True])
def assert_valid_iter_params(self, msg_prefix, start, end, reverse):
@@ -2138,7 +2149,7 @@
return self.getmagicwords("pagenamee")
def _build_namespaces(self):
- _namespaces = SelfCallDict()
+ _namespaces = {}
# In MW 1.14, API siprop 'namespaces' added 'canonical',
# and Image became File with Image as an alias.
@@ -2174,7 +2185,7 @@
if item['*'] not in _namespaces[ns]:
_namespaces[ns].aliases.append(item['*'])
- self._namespaces = _namespaces
+ return _namespaces
@need_version("1.14")
@deprecated("has_extension")
@@ -2368,13 +2379,6 @@
if not hasattr(self, '_proofread_levels'):
self._cache_proofreadinfo()
return self._proofread_levels
-
- @property
- def namespaces(self):
- """Return dict of valid namespaces on this
wiki."""
- if not hasattr(self, '_namespaces'):
- self._build_namespaces()
- return self._namespaces
def namespace(self, num, all=False):
"""Return string containing local name of namespace
'num'.
@@ -3161,7 +3165,7 @@
# Covert namespaces to a known type
namespaces = set(Namespace.resolve(namespaces or [],
- self.namespaces()))
+ self.namespaces))
if 'page' in member_type:
excluded_namespaces = set()
@@ -3184,7 +3188,7 @@
# namespaces requested is higher than available, and split
# the request into several batches.
excluded_namespaces.add([-1, -2])
- namespaces = set(self.namespaces()) - excluded_namespaces
+ namespaces = set(self.namespaces) - excluded_namespaces
else:
if 'file' in member_type:
namespaces.add(6)
@@ -3912,7 +3916,7 @@
if where not in ("text", "titles"):
raise Error("search: unrecognized 'where' value: %s" %
where)
if namespaces == []:
- namespaces = [ns for ns in list(self.namespaces().keys()) if ns >= 0]
+ namespaces = [ns_id for ns_id in self.namespaces if ns_id >= 0]
if not namespaces:
pywikibot.warning(u"search: namespaces cannot be empty; using
[0].")
namespaces = [0]
@@ -5511,7 +5515,7 @@
self._item_namespace = False
self._property_namespace = False
- for namespace in self.namespaces().values():
+ for namespace in self.namespaces.values():
if not hasattr(namespace, 'defaultcontentmodel'):
continue
diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py
index 692fc89..9636c46 100644
--- a/pywikibot/tools/__init__.py
+++ b/pywikibot/tools/__init__.py
@@ -657,10 +657,18 @@
class SelfCallMixin(object):
- """Return self when called."""
+ """
+ Return self when called.
+
+ When '_own_desc' is defined it'll also issue a deprecation warning using
+ issue_deprecation_warning('Calling ' + _own_desc, 'it directly').
+ """
def __call__(self):
"""Do nothing and just return itself."""
+ if hasattr(self, '_own_desc'):
+ issue_deprecation_warning('Calling {0}'.format(self._own_desc),
+ 'it directly', 2)
return self
diff --git a/scripts/replicate_wiki.py b/scripts/replicate_wiki.py
index c890910..788f993 100755
--- a/scripts/replicate_wiki.py
+++ b/scripts/replicate_wiki.py
@@ -49,14 +49,15 @@
import sys
import pywikibot
+
from pywikibot import config, Page
+from pywikibot.tools import deprecated
+(a)deprecated('BaseSite.namespaces')
def namespaces(site):
"""dict from namespace number to prefix."""
- ns = dict((site.getNamespaceIndex(n), n) for n in site.namespaces())
- ns[0] = ''
- return ns
+ return dict((n.id, n.custom_name) for n in site.namespaces)
def multiple_replace(text, word_dict):
@@ -88,9 +89,8 @@
self.original.login()
if options.namespace and 'help' in options.namespace:
- nsd = namespaces(self.original)
- for k in nsd:
- pywikibot.output('%s %s' % (k, nsd[k]))
+ for namespace in self.original.namespaces.values():
+ pywikibot.output('%s %s' % (namespace.id,
namespace.custom_name))
sys.exit()
self.sites = [pywikibot.Site(s, family) for s in sites]
@@ -191,18 +191,19 @@
page1 = Page(self.original, pagename)
txt1 = page1.text
- for site in self.sites:
- if self.options.dest_namespace:
- prefix = namespaces(site)[int(self.options.dest_namespace)]
- if prefix:
- prefix += ':'
- new_pagename = prefix + page1.titleWithoutNamespace()
- pywikibot.output("\nCross namespace, new title: %s"
- % new_pagename)
- else:
- new_pagename = pagename
+ if self.options.dest_namespace:
+ dest_ns = int(self.options.dest_namespace)
+ else:
+ dest_ns = None
- page2 = Page(site, new_pagename)
+ for site in self.sites:
+ if dest_ns is not None:
+ page2 = Page(site, page1.title(withNamespace=False), dest_ns)
+ pywikibot.output("\nCross namespace, new title: %s"
+ % page2.title())
+ else:
+ page2 = Page(site, pagename)
+
if page2.exists():
txt2 = page2.text
else:
diff --git a/scripts/solve_disambiguation.py b/scripts/solve_disambiguation.py
index 846f1a6..4620a29 100755
--- a/scripts/solve_disambiguation.py
+++ b/scripts/solve_disambiguation.py
@@ -80,8 +80,9 @@
__version__ = '$Id$'
#
-import re
import codecs
+import itertools
+import re
import pywikibot
from pywikibot import editor as editarticle
@@ -996,10 +997,7 @@
ignore_title[self.mysite.family.name][self.mylang] = []
ignore_title[self.mysite.family.name][self.mylang] += [
- u'%s:' % ns
- for namespace in self.mysite.namespaces()
- for ns in self.mysite.namespaces[namespace]
- ]
+ '%s:' % ns for ns in itertools.chain(self.mysite.namespaces)]
for disambPage in self.generator:
self.primaryIgnoreManager = PrimaryIgnoreManager(
diff --git a/tests/site_tests.py b/tests/site_tests.py
index b279c02..0810f95 100644
--- a/tests/site_tests.py
+++ b/tests/site_tests.py
@@ -25,6 +25,7 @@
from tests.aspects import (
unittest, TestCase, DeprecationTestCase,
DefaultSiteTestCase,
+ DefaultDrySiteTestCase,
WikimediaDefaultSiteTestCase,
WikidataTestCase,
DefaultWikidataClientTestCase,
@@ -39,7 +40,7 @@
class TestSiteObjectDeprecatedFunctions(DefaultSiteTestCase, DeprecationTestCase):
- """Test cases for Site deprecated methods."""
+ """Test cases for Site deprecated methods on a live
wiki."""
cached = True
user = True
@@ -67,6 +68,18 @@
self.assertEqual(token, mysite.token(mainpage, ttype))
self.assertDeprecation("pywikibot.site.APISite.token is
deprecated"
", use the 'tokens' property
instead.")
+
+
+class TestSiteDryDeprecatedFunctions(DefaultDrySiteTestCase, DeprecationTestCase):
+
+ """Test cases for Site deprecated methods without a
user."""
+
+ def test_namespaces_callable(self):
+ """Test that namespaces is callable and returns
itself."""
+ site = self.get_site()
+ self.assertIs(site.namespaces(), site.namespaces)
+ self.assertDeprecation('Calling the namespaces property is deprecated, '
+ 'use it directly instead.')
class TestBaseSiteProperties(TestCase):
@@ -212,7 +225,7 @@
}
self.assertTrue(all(mysite.ns_index(b) == builtins[b]
for b in builtins))
- ns = mysite.namespaces()
+ ns = mysite.namespaces
self.assertIsInstance(ns, dict)
self.assertTrue(all(x in ns for x in range(0, 16)))
# built-in namespaces always present
@@ -1807,7 +1820,7 @@
def testNamespaceAliases(self):
site = self.get_site()
- namespaces = site.namespaces()
+ namespaces = site.namespaces
image_namespace = namespaces[6]
self.assertEqual(image_namespace.custom_name, 'Fil')
self.assertEqual(image_namespace.canonical_name, 'File')
diff --git a/tests/utils.py b/tests/utils.py
index 78645ac..d151253 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -20,7 +20,6 @@
import pywikibot
from pywikibot import config
-from pywikibot.tools import SelfCallDict
from pywikibot.site import Namespace
from pywikibot.data.api import CachedRequest
from pywikibot.data.api import Request as _original_Request
@@ -200,13 +199,13 @@
self._siteinfo._cache['case'] = (
'case-sensitive' if self.family.name == 'wiktionary' else
'first-letter', True)
- self._namespaces = SelfCallDict(
- Namespace.builtin_namespaces(
- case=self.siteinfo['case']))
extensions = []
if self.family.name == 'wikisource':
extensions.append({'name': 'ProofreadPage'})
self._siteinfo._cache['extensions'] = (extensions, True)
+
+ def _build_namespaces(self):
+ return Namespace.builtin_namespaces(case=self.siteinfo['case'])
def __repr__(self):
"""Override default so warnings and errors indicate test is
dry."""
@@ -244,19 +243,14 @@
"""Dummy class to use instead of
L{pywikibot.site.DataSite}."""
- def __init__(self, code, fam, user, sysop):
- """Constructor."""
- super(DryDataSite, self).__init__(code, fam, user, sysop)
-
- self._namespaces[0].defaultcontentmodel = 'wikibase-item'
-
- self._namespaces.update(
- {
- 120: Namespace(id=120,
- case='first-letter',
- canonical_name='Property',
- defaultcontentmodel='wikibase-property')
- })
+ def _build_namespaces(self):
+ namespaces = super(DryDataSite, self)._build_namespaces()
+ namespaces[0].defaultcontentmodel = 'wikibase-item'
+ namespaces[120] = Namespace(id=120,
+ case='first-letter',
+ canonical_name='Property',
+ defaultcontentmodel='wikibase-property')
+ return namespaces
def execute(command, data_in=None, timeout=0, error=None):
--
To view, visit
https://gerrit.wikimedia.org/r/211313
To unsubscribe, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I9c4f73e2d1b6b97eb64797115aeb130f3ecc5c9d
Gerrit-PatchSet: 7
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Ricordisamoa <ricordisamoa(a)openmailbox.org>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: jenkins-bot <>