jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/423343 )
Change subject: [cleanup] enable C401, C402, C405 checks after py2.6 has been dropped
......................................................................
[cleanup] enable C401, C402, C405 checks after py2.6 has been dropped
Change-Id: I2e0beeba198c004900f70a622985b3f049524fd6
---
M pywikibot/comms/http.py
M pywikibot/config2.py
M pywikibot/data/api.py
M pywikibot/data/wikistats.py
M pywikibot/date.py
M pywikibot/diff.py
M pywikibot/family.py
M pywikibot/interwiki_graph.py
M pywikibot/page.py
M pywikibot/site.py
M pywikibot/tools/__init__.py
M pywikibot/tools/formatter.py
M pywikibot/version.py
M scripts/casechecker.py
M scripts/checkimages.py
M scripts/interwiki.py
M scripts/nowcommons.py
M scripts/patrol.py
M scripts/protect.py
M scripts/redirect.py
M scripts/replicate_wiki.py
M scripts/shell.py
M tests/api_tests.py
M tests/archivebot_tests.py
M tests/aspects.py
M tests/family_tests.py
M tests/interwiki_graph_tests.py
M tests/namespace_tests.py
M tests/page_tests.py
M tests/pagegenerators_tests.py
M tests/paraminfo_tests.py
M tests/proofreadpage_tests.py
M tests/script_tests.py
M tests/site_tests.py
M tests/sparql_tests.py
M tests/textlib_tests.py
M tests/tools_tests.py
M tests/utils.py
M tox.ini
39 files changed, 236 insertions(+), 243 deletions(-)
Approvals:
Dalba: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/comms/http.py b/pywikibot/comms/http.py
index d98ab8a..0ac5187 100644
--- a/pywikibot/comms/http.py
+++ b/pywikibot/comms/http.py
@@ -364,7 +364,7 @@
body = http_request.body
headers = http_request.headers
if PY2 and headers:
- headers = dict((key, str(value)) for key, value in headers.items())
+ headers = {key: str(value) for key, value in headers.items()}
auth = get_authentication(uri)
if auth is not None and len(auth) == 4:
if isinstance(requests_oauthlib, ImportError):
diff --git a/pywikibot/config2.py b/pywikibot/config2.py
index 7e5436b..35ede44 100644
--- a/pywikibot/config2.py
+++ b/pywikibot/config2.py
@@ -983,8 +983,8 @@
# System-level and User-level changes.
# Store current variables and their types.
-_glv = dict((_key, _val) for _key, _val in globals().items()
- if _key[0] != '_' and _key not in _imports)
+_glv = {_key: _val for _key, _val in globals().items()
+ if _key[0] != '_' and _key not in _imports}
_gl = list(_glv.keys())
_tp = {}
for _key in _gl:
diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index e1c41ae..278ff81 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -264,8 +264,9 @@
# v1.18 and earlier paraminfo doesnt include modules; must use 'query'
# Assume that by v1.26, it will be desirable to prefetch 'query'
- if _mw_ver > MediaWikiVersion('1.26') or _mw_ver < MediaWikiVersion('1.19'):
- self.preloaded_modules |= set(['query'])
+ if _mw_ver > MediaWikiVersion('1.26') \
+ or _mw_ver < MediaWikiVersion('1.19'):
+ self.preloaded_modules |= {'query'}
self._fetch(self.preloaded_modules)
@@ -294,7 +295,7 @@
if 'query' not in self._modules:
assert 'query' not in self._paraminfo
- self._fetch(set(['query']))
+ self._fetch({'query'})
assert 'query' in self._modules
def _emulate_pageset(self):
@@ -621,7 +622,7 @@
if 'query' not in self._paraminfo:
pywikibot.debug('paraminfo batch: added query', _logger)
module_batch.append('query')
- self.preloaded_modules |= set(['query'])
+ self.preloaded_modules |= {'query'}
params = {
'action': 'paraminfo',
@@ -709,9 +710,9 @@
# Boolean submodule info added to MW API in afa153ae
if self.site.version() < MediaWikiVersion('1.24wmf18'):
if module == 'main':
- params = set(['action'])
+ params = {'action'}
elif module == 'query':
- params = set(['prop', 'list', 'meta'])
+ params = {'prop', 'list', 'meta'}
else:
params = set()
for param in parameters:
@@ -745,11 +746,11 @@
assert(self._action_modules)
- return set('query+' + mod if '+' not in mod and
- mod in self.query_modules and
- mod not in self._action_modules
- else mod
- for mod in modules)
+ return {'query+' + mod
+ if '+' not in mod and mod in self.query_modules
+ and mod not in self._action_modules
+ else mod
+ for mod in modules}
def normalize_modules(self, modules):
"""
@@ -833,7 +834,7 @@
If the key does not include a '+' and is not present in the top level
of the API, it will fallback to looking for the key 'query+x'.
"""
- self.fetch(set([key]))
+ self.fetch({key})
if key in self._paraminfo:
return self._paraminfo[key]
elif '+' not in key:
@@ -959,7 +960,7 @@
@staticmethod
def _prefix_submodules(modules, prefix):
"""Prefix submodules with path."""
- return set('{0}+{1}'.format(prefix, mod) for mod in modules)
+ return {'{0}+{1}'.format(prefix, mod) for mod in modules}
@property
@deprecated('prefix_map')
@@ -981,9 +982,10 @@
This loads paraminfo for all modules.
"""
if not self._prefix_map:
- self._prefix_map = dict((module, prefix) for module, prefix in
- self.attributes('prefix').items()
- if prefix)
+ self._prefix_map = {module: prefix
+ for module, prefix
+ in self.attributes('prefix').items()
+ if prefix}
return self._prefix_map.copy()
def attributes(self, attribute, modules=None):
@@ -1004,9 +1006,8 @@
modules = self.module_paths
self.fetch(modules)
- return dict((mod, self[mod][attribute])
- for mod in modules
- if attribute in self[mod])
+ return {mod: self[mod][attribute]
+ for mod in modules if attribute in self[mod]}
@deprecated('attributes')
def module_attribute_map(self, attribute, modules=None):
@@ -1027,9 +1028,8 @@
self.fetch(modules)
- return dict((mod, self[mod][attribute])
- for mod in modules
- if self[mod][attribute])
+ return {mod: self[mod][attribute]
+ for mod in modules if self[mod][attribute]}
@property
@deprecated('parameter()')
@@ -1517,21 +1517,21 @@
else:
raise ValueError('Request was not a super class of '
'{0!r}'.format(cls))
- args -= set(['self'])
+ args -= {'self'}
old_kwargs = set(kwargs)
# all kwargs defined above but not in args indicate 'kwargs' mode
if old_kwargs - args:
# Move all kwargs into parameters
- parameters = dict((name, value) for name, value in kwargs.items()
- if name not in args or name == 'parameters')
+ parameters = {name: value for name, value in kwargs.items()
+ if name not in args or name == 'parameters'}
if 'parameters' in parameters:
cls._warn_both()
# Copy only arguments and not the parameters
- kwargs = dict((name, value) for name, value in kwargs.items()
- if name in args or name == 'self')
+ kwargs = {name: value for name, value in kwargs.items()
+ if name in args or name == 'self'}
kwargs['parameters'] = parameters
# Make sure that all arguments have remained
- assert(old_kwargs | set(['parameters']) ==
+ assert(old_kwargs | {'parameters'} ==
set(kwargs) | set(kwargs['parameters']))
assert(('parameters' in old_kwargs) is
('parameters' in kwargs['parameters']))
@@ -1901,7 +1901,7 @@
for mod_type_name in ('list', 'prop', 'generator'):
modules.update(self._params.get(mod_type_name, []))
else:
- modules = set([self.action])
+ modules = {self.action}
if modules:
self.site._paraminfo.fetch(modules)
use_get = all('mustbeposted' not in self.site._paraminfo[mod]
@@ -2138,8 +2138,8 @@
if code == 'badtoken':
user_tokens = self.site.tokens._tokens[self.site.user()]
# all token values mapped to their type
- tokens = dict((token, t_type)
- for t_type, token in user_tokens.items())
+ tokens = {token: t_type
+ for t_type, token in user_tokens.items()}
# determine which tokens are bad
invalid_param = {}
for name, param in self._params.items():
@@ -2552,9 +2552,9 @@
self.site._paraminfo.fetch('query+' + mod for mod in self.modules)
- limited_modules = set(
- mod for mod in self.modules
- if self.site._paraminfo.parameter('query+' + mod, 'limit'))
+ limited_modules = {mod for mod in self.modules
+ if self.site._paraminfo.parameter('query+' + mod,
+ 'limit')}
if not limited_modules:
self.limited_module = None
@@ -2810,9 +2810,9 @@
self.limit),
_logger)
if "normalized" in self.data["query"]:
- self.normalized = dict((item['to'], item['from'])
- for item in
- self.data["query"]["normalized"])
+ self.normalized = {
+ item['to']: item['from']
+ for item in self.data['query']['normalized']}
else:
self.normalized = {}
for item in resultdata:
diff --git a/pywikibot/data/wikistats.py b/pywikibot/data/wikistats.py
index 44cc297..adeef39 100644
--- a/pywikibot/data/wikistats.py
+++ b/pywikibot/data/wikistats.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Objects representing WikiStats API."""
#
-# (C) Pywikibot team, 2014-2017
+# (C) Pywikibot team, 2014-2018
#
# Distributed under the terms of the MIT license.
from __future__ import absolute_import, unicode_literals
@@ -45,12 +45,12 @@
MISC_SITES_TABLE = 'mediawikis'
- WMF_MULTILANG_TABLES = set([
+ WMF_MULTILANG_TABLES = {
'wikipedias', 'wiktionaries', 'wikisources', 'wikinews',
'wikibooks', 'wikiquotes', 'wikivoyage', 'wikiversity',
- ])
+ }
- OTHER_MULTILANG_TABLES = set([
+ OTHER_MULTILANG_TABLES = {
'uncyclomedia',
'rodovid',
'wikifur',
@@ -61,9 +61,9 @@
'lxde',
'pardus',
'gentoo',
- ])
+ }
- OTHER_TABLES = set([
+ OTHER_TABLES = {
# Farms
'wikia',
'wikkii',
@@ -79,9 +79,9 @@
'w3cwikis',
'neoseeker',
'sourceforge',
- ])
+ }
- ALL_TABLES = (set([MISC_SITES_TABLE]) | WMF_MULTILANG_TABLES |
+ ALL_TABLES = ({MISC_SITES_TABLE} | WMF_MULTILANG_TABLES |
OTHER_MULTILANG_TABLES | OTHER_TABLES)
ALL_KEYS = set(FAMILY_MAPPING.keys()) | ALL_TABLES
@@ -222,8 +222,7 @@
@type format: 'xml' or 'csv', or None to autoselect.
@rtype: dict
"""
- return dict((data['prefix'], data)
- for data in self.get(table, format))
+ return {data['prefix']: data for data in self.get(table, format)}
def sorted(self, table, key):
"""
diff --git a/pywikibot/date.py b/pywikibot/date.py
index b6c45ab..a9db80a 100644
--- a/pywikibot/date.py
+++ b/pywikibot/date.py
@@ -7,7 +7,7 @@
# (C) Andre Engels, 2004-2005
# (C) Yuri Astrakhan, 2005-2006 (<Firstname><Lastname>@gmail.com)
# (years/decades/centuries/millenniums str <=> int conversions)
-# (C) Pywikibot team, 2004-2017
+# (C) Pywikibot team, 2004-2018
#
# Distributed under the terms of the MIT license.
#
@@ -261,28 +261,28 @@
# Helper for KN: digits representation
_knDigits = u'೦೧೨೩೪೫೬೭೮೯'
-_knDigitsToLocal = dict((ord(unicode(i)), _knDigits[i]) for i in range(10))
-_knLocalToDigits = dict((ord(_knDigits[i]), unicode(i)) for i in range(10))
+_knDigitsToLocal = {ord(unicode(i)): _knDigits[i] for i in range(10)}
+_knLocalToDigits = {ord(_knDigits[i]): unicode(i) for i in range(10)}
# Helper for Urdu/Persian languages
_faDigits = u'۰۱۲۳۴۵۶۷۸۹'
-_faDigitsToLocal = dict((ord(unicode(i)), _faDigits[i]) for i in range(10))
-_faLocalToDigits = dict((ord(_faDigits[i]), unicode(i)) for i in range(10))
+_faDigitsToLocal = {ord(unicode(i)): _faDigits[i] for i in range(10)}
+_faLocalToDigits = {ord(_faDigits[i]): unicode(i) for i in range(10)}
# Helper for HI:, MR:
_hiDigits = u'०१२३४५६७८९'
-_hiDigitsToLocal = dict((ord(unicode(i)), _hiDigits[i]) for i in range(10))
-_hiLocalToDigits = dict((ord(_hiDigits[i]), unicode(i)) for i in range(10))
+_hiDigitsToLocal = {ord(unicode(i)): _hiDigits[i] for i in range(10)}
+_hiLocalToDigits = {ord(_hiDigits[i]): unicode(i) for i in range(10)}
# Helper for BN:
_bnDigits = u'০১২৩৪৫৬৭৮৯'
-_bnDigitsToLocal = dict((ord(unicode(i)), _bnDigits[i]) for i in range(10))
-_bnLocalToDigits = dict((ord(_bnDigits[i]), unicode(i)) for i in range(10))
+_bnDigitsToLocal = {ord(unicode(i)): _bnDigits[i] for i in range(10)}
+_bnLocalToDigits = {ord(_bnDigits[i]): unicode(i) for i in range(10)}
# Helper for GU:
_guDigits = u'૦૧૨૩૪૫૬૭૮૯'
-_guDigitsToLocal = dict((ord(unicode(i)), _guDigits[i]) for i in range(10))
-_guLocalToDigits = dict((ord(_guDigits[i]), unicode(i)) for i in range(10))
+_guDigitsToLocal = {ord(unicode(i)): _guDigits[i] for i in range(10)}
+_guLocalToDigits = {ord(_guDigits[i]): unicode(i) for i in range(10)}
def intToLocalDigitsStr(value, digitsToLocalDict):
diff --git a/pywikibot/diff.py b/pywikibot/diff.py
index 95669e9..4556c1f 100644
--- a/pywikibot/diff.py
+++ b/pywikibot/diff.py
@@ -234,7 +234,7 @@
@property
def reviewed(self):
- assert len(set(hunk.reviewed for hunk in self._hunks)) == 1, \
+ assert len({hunk.reviewed for hunk in self._hunks}) == 1, \
'All hunks should have the same review status'
return self._hunks[0].reviewed
diff --git a/pywikibot/family.py b/pywikibot/family.py
index 632aff5..ff18c20 100644
--- a/pywikibot/family.py
+++ b/pywikibot/family.py
@@ -1430,8 +1430,7 @@
@return: mapping of old codes to new codes (or None)
@rtype: dict
"""
- data = dict((code, None)
- for code in self.interwiki_removals)
+ data = {code: None for code in self.interwiki_removals}
data.update(self.interwiki_replacements)
return FrozenDict(data,
'Family.obsolete not updatable; '
@@ -1506,8 +1505,8 @@
if hasattr(self, 'test_codes'):
codes = codes + self.test_codes
- self.langs = dict(
- (code, '%s.%s' % (code, self.domain)) for code in codes)
+ self.langs = {code: '{0}.{1}'.format(code, self.domain)
+ for code in codes}
super(SubdomainFamily, self).__init__()
diff --git a/pywikibot/interwiki_graph.py b/pywikibot/interwiki_graph.py
index e14797b..00166ed 100644
--- a/pywikibot/interwiki_graph.py
+++ b/pywikibot/interwiki_graph.py
@@ -157,9 +157,9 @@
each_site = [page.site for page in page_list
if page.exists() and not page.isRedirectPage()]
- return set(x[0] for x in itertools.takewhile(
+ return {x[0] for x in itertools.takewhile(
lambda x: x[1] > 1,
- Counter(each_site).most_common()))
+ Counter(each_site).most_common())}
def addNode(self, page):
"""Add a node for page."""
diff --git a/pywikibot/page.py b/pywikibot/page.py
index fa29cf4..6b4d8cf 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -970,7 +970,7 @@
try:
default = set(self.site.family.disambig('_default'))
except KeyError:
- default = set([u'Disambig'])
+ default = {'Disambig'}
try:
distl = self.site.family.disambig(self.site.code,
fallback=False)
@@ -980,25 +980,22 @@
disambigpages = Page(self.site,
"MediaWiki:Disambiguationspage")
if disambigpages.exists():
- disambigs = set(link.title(withNamespace=False)
- for link in disambigpages.linkedPages()
- if link.namespace() == 10)
+ disambigs = {link.title(withNamespace=False)
+ for link in disambigpages.linkedPages()
+ if link.namespace() == 10}
elif self.site.has_mediawiki_message('disambiguationspage'):
message = self.site.mediawiki_message(
'disambiguationspage').split(':', 1)[1]
# add the default template(s) for default mw message
# only
- disambigs = set([first_upper(message)]) | default
+ disambigs = {first_upper(message)} | default
else:
disambigs = default
self.site._disambigtemplates = disambigs
else:
# Normalize template capitalization
- self.site._disambigtemplates = set(
- first_upper(t) for t in distl
- )
- templates = set(tl.title(withNamespace=False)
- for tl in self.templates())
+ self.site._disambigtemplates = {first_upper(t) for t in distl}
+ templates = {tl.title(withNamespace=False) for tl in self.templates()}
disambigs = set()
# always use cached disambig templates
disambigs.update(self.site._disambigtemplates)
@@ -1118,7 +1115,7 @@
p_types = set(self.site.protection_types())
if not self.exists():
- return set(['create']) if 'create' in p_types else set()
+ return {'create'} if 'create' in p_types else set()
else:
p_types.remove('create') # no existing page allows that
if not self.is_filepage(): # only file pages allow upload
@@ -2059,8 +2056,8 @@
if unprotect:
warn(u'"unprotect" argument of protect() is deprecated',
DeprecationWarning, 2)
- protections = dict(
- (p_type, "") for p_type in self.applicable_protections())
+ protections = {p_type: ''
+ for p_type in self.applicable_protections()}
answer = 'y'
if called_using_deprecated_arg and prompt is None:
prompt = True
@@ -2219,7 +2216,7 @@
def getRestrictions(self):
"""DEPRECATED. Use self.protection() instead."""
restrictions = self.protection()
- return dict((k, list(restrictions[k])) for k in restrictions)
+ return {k: list(restrictions[k]) for k in restrictions}
def __getattr__(self, name):
"""Generic disabled method warnings."""
@@ -5944,10 +5941,10 @@
158: 382, # ž
159: 376 # Ÿ
}
- # ensuring that illegal   and , which have no known values,
- # don't get converted to chr(129), chr(141) or chr(157)
- ignore = (set(map(lambda x: convertIllegalHtmlEntities.get(x, x), ignore)) |
- set([129, 141, 157]))
+ # ensuring that illegal   and , which have no known
+ # values, don't get converted to chr(129), chr(141) or chr(157)
+ ignore = (set(map(lambda x: convertIllegalHtmlEntities.get(x, x),
+ ignore)) | {129, 141, 157})
def handle_entity(match):
if match.group('decimal'):
diff --git a/pywikibot/site.py b/pywikibot/site.py
index e952892..050d8be 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -419,9 +419,8 @@
@classmethod
def builtin_namespaces(cls, use_image_name=False, case='first-letter'):
"""Return a dict of the builtin namespaces."""
- return dict((i, cls(i, use_image_name=use_image_name,
- case=cls.default_case(i, case)))
- for i in range(-2, 16))
+ return {i: cls(i, use_image_name=use_image_name,
+ case=cls.default_case(i, case)) for i in range(-2, 16)}
@staticmethod
def normalize_name(name):
@@ -692,8 +691,8 @@
# _iw_sites is a local cache to return a APISite instance depending
# on the interwiki prefix of that site
if self._map is None:
- self._map = dict((iw['prefix'], _IWEntry('local' in iw, iw['url']))
- for iw in self._site.siteinfo['interwikimap'])
+ self._map = {iw['prefix']: _IWEntry('local' in iw, iw['url'])
+ for iw in self._site.siteinfo['interwikimap']}
return self._map
def __getitem__(self, prefix):
@@ -710,8 +709,8 @@
def get_by_url(self, url):
"""Return a set of prefixes applying to the URL."""
- return set(prefix for prefix, iw_entry in self._iw_sites
- if iw_entry.url == url)
+ return {prefix for prefix, iw_entry in self._iw_sites
+ if iw_entry.url == url}
class BaseSite(ComparableMixin):
@@ -2252,9 +2251,9 @@
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
- self._useroptions['searchNs{0}'.format(ns.id)]
- in ['1', True])
+ return {ns for ns in self.namespaces.values() if ns.id >= 0
+ and self._useroptions['searchNs{0}'.format(ns.id)]
+ in ['1', True]}
@property
def article_path(self):
@@ -2385,7 +2384,7 @@
raise KeyError("Site %s has no message '%s'"
% (self, key))
- return dict((_key, self._msgcache[_key]) for _key in keys)
+ return {_key: self._msgcache[_key] for _key in keys}
@deprecated_args(forceReload=None)
def mediawiki_message(self, key):
@@ -2565,8 +2564,8 @@
"""Return list of localized "word" magic words for the site."""
if not hasattr(self, "_magicwords"):
magicwords = self.siteinfo.get("magicwords", cache=False)
- self._magicwords = dict((item["name"], item["aliases"])
- for item in magicwords)
+ self._magicwords = {item['name']: item['aliases']
+ for item in magicwords}
if word in self._magicwords:
return self._magicwords[word]
@@ -2596,8 +2595,7 @@
"""
# NOTE: this is needed, since the API can give false positives!
try:
- keywords = set(s.lstrip("#")
- for s in self.getmagicwords("redirect"))
+ keywords = {s.lstrip('#') for s in self.getmagicwords('redirect')}
keywords.add("REDIRECT") # just in case
pattern = "(?:" + "|".join(keywords) + ")"
except KeyError:
@@ -3181,12 +3179,13 @@
"getredirtarget: No 'redirects' found for page %s."
% title.encode(self.encoding()))
- redirmap = dict((item['from'],
- {'title': item['to'],
- 'section': u'#' + item['tofragment']
- if 'tofragment' in item and item['tofragment']
- else ''})
- for item in result['query']['redirects'])
+ redirmap = {item['from']: {'title': item['to'],
+ 'section': '#'
+ + item['tofragment']
+ if 'tofragment' in item
+ and item['tofragment']
+ else ''}
+ for item in result['query']['redirects']}
# Normalize title
for item in result['query'].get('normalized', []):
@@ -3491,7 +3490,7 @@
query = api.PropertyGenerator(
'info',
titles='Dummy page',
- intoken=valid_tokens - set(['patrol']),
+ intoken=valid_tokens - {'patrol'},
site=self)
query.request._warning_handler = warn_handler
@@ -3547,9 +3546,9 @@
data = data['query']
if 'tokens' in data and data['tokens']:
- user_tokens = dict((key[:-5], val)
- for key, val in data['tokens'].items()
- if val != '+\\')
+ user_tokens = {key[:-5]: val
+ for key, val in data['tokens'].items()
+ if val != '+\\'}
return user_tokens
@@ -3873,7 +3872,7 @@
"categorymembers: startsort must be less than endsort")
if isinstance(member_type, basestring):
- member_type = set([member_type])
+ member_type = {member_type}
if (member_type and
(sortby == 'timestamp' or
@@ -5029,7 +5028,7 @@
"cascadeprotected": CascadeLockedPage,
'titleblacklist-forbidden': TitleblacklistError,
}
- _ep_text_overrides = set(['appendtext', 'prependtext', 'undo'])
+ _ep_text_overrides = {'appendtext', 'prependtext', 'undo'}
@must_be(group='user')
def editpage(self, page, summary=None, minor=True, notminor=False,
@@ -5120,7 +5119,7 @@
if basetimestamp and 'basetimestamp' not in kwargs:
params['basetimestamp'] = basetimestamp
- watch_items = set(["watch", "unwatch", "preferences", "nochange"])
+ watch_items = {'watch', 'unwatch', 'preferences', 'nochange'}
if watch in watch_items:
if MediaWikiVersion(self.version()) < MediaWikiVersion("1.16"):
if watch in ['preferences', 'nochange']:
@@ -5739,11 +5738,11 @@
raise Error('No rcid, revid or revision provided.')
if isinstance(rcid, int) or isinstance(rcid, basestring):
- rcid = set([rcid])
+ rcid = {rcid}
if isinstance(revid, int) or isinstance(revid, basestring):
- revid = set([revid])
+ revid = {revid}
if isinstance(revision, pywikibot.page.Revision):
- revision = set([revision])
+ revision = {revision}
# Handle param=None.
rcid = rcid or set()
@@ -5757,7 +5756,7 @@
u'Support of "revid" parameter\n'
u'is not implemented in MediaWiki version < "1.22"')
else:
- combined_revid = set(revid) | set(r.revid for r in revision)
+ combined_revid = set(revid) | {r.revid for r in revision}
gen = itertools.chain(
zip_longest(rcid, [], fillvalue='rcid'),
@@ -7507,9 +7506,9 @@
# Only separated from get_item to avoid the deprecation message via
# _get_propertyitem
def _get_item(self, source, **params):
- assert set(params) <= set(['props']), \
+ assert set(params) <= {'props'}, \
'Only "props" is a valid kwarg, not {0}'.format(set(params) -
- set(['props']))
+ {'props'})
if isinstance(source, int) or \
isinstance(source, basestring) and source.isdigit():
ids = 'q' + str(source)
@@ -7902,7 +7901,7 @@
for claim in claims:
baserevid = self._get_baserevid(claim, baserevid)
- items = set(claim.on_item for claim in claims if claim.on_item)
+ items = {claim.on_item for claim in claims if claim.on_item}
assert len(items) == 1
params = {
diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py
index 7438303..95eae41 100644
--- a/pywikibot/tools/__init__.py
+++ b/pywikibot/tools/__init__.py
@@ -1545,8 +1545,8 @@
deprecated.update(arg_names[:len(__args) - len(args)])
# remove at most |arg_names| entries from the back
new_args = tuple(__args[:max(len(args), len(__args) - len(arg_names))])
- new_kwargs = dict((arg, val) for arg, val in __kw.items()
- if arg not in arg_names)
+ new_kwargs = {arg: val for arg, val in __kw.items()
+ if arg not in arg_names}
if deprecated:
# sort them according to arg_names
diff --git a/pywikibot/tools/formatter.py b/pywikibot/tools/formatter.py
index b2b942b..8050725 100644
--- a/pywikibot/tools/formatter.py
+++ b/pywikibot/tools/formatter.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Module containing various formatting related utilities."""
#
-# (C) Pywikibot team, 2015-2017
+# (C) Pywikibot team, 2015-2018
#
# Distributed under the terms of the MIT license.
#
@@ -67,7 +67,7 @@
colors = set(colors)
# Dot.product of colors to create all possible combinations of foreground
# and background colors.
- colors |= set('%s;%s' % (c1, c2) for c1 in colors for c2 in colors)
+ colors |= {'{0};{1}'.format(c1, c2) for c1 in colors for c2 in colors}
def get_value(self, key, args, kwargs):
"""Get value, filling in 'color' when it is a valid color."""
diff --git a/pywikibot/version.py b/pywikibot/version.py
index 77f4c34..9621679 100644
--- a/pywikibot/version.py
+++ b/pywikibot/version.py
@@ -495,11 +495,11 @@
std_lib_dir = get_python_lib(standard_lib=True)
- root_packages = set(key.split('.')[0] for key in modules)
+ root_packages = {key.split('.')[0] for key in modules}
- builtin_packages = set(name.split('.')[0] for name in root_packages
- if name in sys.builtin_module_names or
- '_' + name in sys.builtin_module_names)
+ builtin_packages = {name.split('.')[0] for name in root_packages
+ if name in sys.builtin_module_names
+ or '_' + name in sys.builtin_module_names}
# Improve performance by removing builtins from the list if possible.
if builtins is False:
diff --git a/scripts/casechecker.py b/scripts/casechecker.py
index 0ed8f82..92aa7a6 100755
--- a/scripts/casechecker.py
+++ b/scripts/casechecker.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""Bot to find all pages on the wiki with mixed latin and cyrilic alphabets."""
#
-# (C) Pywikibot team, 2006-2017
+# (C) Pywikibot team, 2006-2018
#
# Distributed under the terms of the MIT license.
#
@@ -171,20 +171,20 @@
self.titleList = [self.Page(t) for t in f]
self.failedTitles += '.failed'
- self.lclToLatDict = dict(
- (ord(self.localSuspects[i]), self.latinSuspects[i])
- for i in xrange(len(self.localSuspects)))
- self.latToLclDict = dict(
- (ord(self.latinSuspects[i]), self.localSuspects[i])
- for i in xrange(len(self.localSuspects)))
+ self.lclToLatDict = {
+ ord(self.localSuspects[i]): self.latinSuspects[i]
+ for i in xrange(len(self.localSuspects))}
+ self.latToLclDict = {
+ ord(self.latinSuspects[i]): self.localSuspects[i]
+ for i in xrange(len(self.localSuspects))}
if self.localKeyboard is not None:
- self.lclToLatKeybDict = dict(
- (ord(self.localKeyboard[i]), self.latinKeyboard[i])
- for i in xrange(len(self.localKeyboard)))
- self.latToLclKeybDict = dict(
- (ord(self.latinKeyboard[i]), self.localKeyboard[i])
- for i in xrange(len(self.localKeyboard)))
+ self.lclToLatKeybDict = {
+ ord(self.localKeyboard[i]): self.latinKeyboard[i]
+ for i in xrange(len(self.localKeyboard))}
+ self.latToLclKeybDict = {
+ ord(self.latinKeyboard[i]): self.localKeyboard[i]
+ for i in xrange(len(self.localKeyboard))}
else:
self.lclToLatKeybDict = {}
self.latToLclKeybDict = {}
@@ -464,9 +464,9 @@
badWords = list(self.FindBadWords(title))
if len(badWords) > 0:
# Allow known words, allow any roman numerals with local suffixes
- badWords = set(i for i in badWords
- if i not in self.knownWords and
- self.romanNumSfxPtrn.match(i) is not None)
+ badWords = {i for i in badWords
+ if i not in self.knownWords
+ and self.romanNumSfxPtrn.match(i) is not None}
if len(badWords) == 0 or self.Page(title).is_filepage():
return
diff --git a/scripts/checkimages.py b/scripts/checkimages.py
index 02b340e..3beb321 100755
--- a/scripts/checkimages.py
+++ b/scripts/checkimages.py
@@ -558,9 +558,9 @@
self.list_entry = '\n* [[:{0}%s]] '.format(self.image_namespace)
self.com = i18n.translate(self.site, msg_comm10, fallback=True)
hiddentemplatesRaw = i18n.translate(self.site, HiddenTemplate)
- self.hiddentemplates = set(
+ self.hiddentemplates = {
pywikibot.Page(self.site, tmp, ns=self.site.namespaces.TEMPLATE)
- for tmp in hiddentemplatesRaw)
+ for tmp in hiddentemplatesRaw}
self.pageHidden = i18n.translate(self.site, PageWithHiddenTemplates)
self.pageAllowed = i18n.translate(self.site, PageWithAllowedTemplates)
self.comment = i18n.twtranslate(self.site.lang,
diff --git a/scripts/interwiki.py b/scripts/interwiki.py
index 6b9f336..5e03fd2 100755
--- a/scripts/interwiki.py
+++ b/scripts/interwiki.py
@@ -1983,8 +1983,8 @@
page = new[site]
if not page.section():
try:
- linkedPages = set(pywikibot.Page(l)
- for l in page.iterlanglinks())
+ linkedPages = {pywikibot.Page(l)
+ for l in page.iterlanglinks()}
except pywikibot.NoPage:
pywikibot.warning(
'Page %s does no longer exist?!' % page)
diff --git a/scripts/nowcommons.py b/scripts/nowcommons.py
index d3f0b40..538a515 100755
--- a/scripts/nowcommons.py
+++ b/scripts/nowcommons.py
@@ -45,8 +45,8 @@
#
# (C) Wikipedian, 2006-2007
# (C) Siebrand Mazeland, 2007-2008
-# (C) xqt, 2010-2017
-# (C) Pywikibot team, 2006-2017
+# (C) xqt, 2010-2018
+# (C) Pywikibot team, 2006-2018
#
# Distributed under the terms of the MIT license.
#
@@ -206,8 +206,8 @@
def nc_templates(self):
"""A set of now commons template Page instances."""
if not hasattr(self, '_nc_templates'):
- self._nc_templates = set(pywikibot.Page(self.site, title, ns=10)
- for title in self.ncTemplates())
+ self._nc_templates = {pywikibot.Page(self.site, title, ns=10)
+ for title in self.ncTemplates()}
return self._nc_templates
@property
diff --git a/scripts/patrol.py b/scripts/patrol.py
index 4fc9e60..659b76a 100755
--- a/scripts/patrol.py
+++ b/scripts/patrol.py
@@ -124,8 +124,8 @@
self.patrol_counter = 0 # and how many times an action was taken
for entry in self.site.siteinfo['specialpagealiases']:
if entry['realname'] == 'Prefixindex':
- self._prefixindex_aliases = set(alias.lower()
- for alias in entry['aliases'])
+ self._prefixindex_aliases = {alias.lower()
+ for alias in entry['aliases']}
break
else:
raise RuntimeError('No alias for "prefixindex"')
diff --git a/scripts/protect.py b/scripts/protect.py
index 47f7551..8791124 100755
--- a/scripts/protect.py
+++ b/scripts/protect.py
@@ -51,7 +51,7 @@
# Written by https://it.wikisource.org/wiki/Utente:Qualc1
# Created by modifying delete.py
#
-# (C) Pywikibot team, 2008-2017
+# (C) Pywikibot team, 2008-2018
#
# Distributed under the terms of the MIT license.
#
@@ -245,8 +245,8 @@
protection_levels)
# set the default value for all
# None (not the string 'none') will be ignored by Site.protect()
- combined_protections = dict(
- (p_type, default_level) for p_type in protection_types)
+ combined_protections = {p_type: default_level
+ for p_type in protection_types}
for p_type, level in protections.items():
level = check_protection_level(p_type, level, protection_levels,
default_level)
diff --git a/scripts/redirect.py b/scripts/redirect.py
index 4fd4448..2511f46 100755
--- a/scripts/redirect.py
+++ b/scripts/redirect.py
@@ -73,8 +73,8 @@
#
# (C) Daniel Herding, 2004
# (C) Purodha Blissenbach, 2009
-# (C) xqt, 2009-2017
-# (C) Pywikibot team, 2004-2017
+# (C) xqt, 2009-2018
+# (C) Pywikibot team, 2004-2018
#
# Distributed under the terms of the MIT license.
#
@@ -267,8 +267,8 @@
raise RuntimeError("No results given.")
redirects = {}
pages = {}
- redirects = dict((x['from'], x['to'])
- for x in data['query']['redirects'])
+ redirects = {x['from']: x['to']
+ for x in data['query']['redirects']}
for pagetitle in data['query']['pages'].values():
if 'missing' in pagetitle and 'pageid' not in pagetitle:
diff --git a/scripts/replicate_wiki.py b/scripts/replicate_wiki.py
index 7009737..187a009 100755
--- a/scripts/replicate_wiki.py
+++ b/scripts/replicate_wiki.py
@@ -42,7 +42,7 @@
"""
#
# (C) Kasper Souren, 2012-2013
-# (C) Pywikibot team, 2013-2017
+# (C) Pywikibot team, 2013-2018
#
# Distributed under the terms of the MIT license.
#
@@ -61,7 +61,7 @@
@deprecated('BaseSite.namespaces')
def namespaces(site):
"""Return a dictionary from namespace number to prefix."""
- return dict((n.id, n.custom_name) for n in site.namespaces)
+ return {n.id: n.custom_name for n in site.namespaces}
def multiple_replace(text, word_dict):
diff --git a/scripts/shell.py b/scripts/shell.py
index 50cff05..07b16af 100755
--- a/scripts/shell.py
+++ b/scripts/shell.py
@@ -9,7 +9,7 @@
If no arguments are given, the pywikibot library will not be loaded.
"""
-# (C) Pywikibot team, 2014-2017
+# (C) Pywikibot team, 2014-2018
#
# Distributed under the terms of the MIT license.
#
@@ -31,7 +31,7 @@
if __name__ == "__main__":
import sys
args = []
- if set(sys.argv) - set(['shell', 'shell.py']):
+ if set(sys.argv) - {'shell', 'shell.py'}:
args = sys.argv
del sys
main(*args)
diff --git a/tests/api_tests.py b/tests/api_tests.py
index 38015fe..aabfcb8 100644
--- a/tests/api_tests.py
+++ b/tests/api_tests.py
@@ -190,7 +190,7 @@
else:
assert 'query' not in modules
original_generate_submodules(modules)
- pi = api.ParamInfo(self.site, set(['query', 'main']))
+ pi = api.ParamInfo(self.site, {'query', 'main'})
self.assertEqual(len(pi), 0)
original_generate_submodules = pi._generate_submodules
pi._generate_submodules = patched_generate_submodules
@@ -202,7 +202,7 @@
"""Test initializing with only the pageset."""
site = self.get_site()
self.assertNotIn('query', api.ParamInfo.init_modules)
- pi = api.ParamInfo(site, set(['pageset']))
+ pi = api.ParamInfo(site, {'pageset'})
self.assertNotIn('query', api.ParamInfo.init_modules)
self.assertEqual(len(pi), 0)
pi._init()
@@ -232,7 +232,7 @@
def test_generators(self):
"""Test requesting the generator parameter."""
site = self.get_site()
- pi = api.ParamInfo(site, set(['pageset', 'query']))
+ pi = api.ParamInfo(site, {'pageset', 'query'})
self.assertEqual(len(pi), 0)
pi._init()
@@ -548,7 +548,7 @@
options['c'] = None
self.assertCountEqual(['a', 'b'], list(options.keys()))
self.assertCountEqual([True, False], list(options.values()))
- self.assertEqual(set(), set(options.values()) - set([True, False]))
+ self.assertEqual(set(), set(options.values()) - {True, False})
self.assertCountEqual([('a', True), ('b', False)], list(options.items()))
@@ -808,7 +808,7 @@
'limit': {'max': 10},
'namespace': {'multi': True}
}
- mysite._paraminfo.query_modules_with_limits = set(['allpages'])
+ mysite._paraminfo.query_modules_with_limits = {'allpages'}
self.gen = api.ListGenerator(listaction="allpages", site=mysite)
def test_namespace_none(self):
diff --git a/tests/archivebot_tests.py b/tests/archivebot_tests.py
index 7270059..f79cd4b 100644
--- a/tests/archivebot_tests.py
+++ b/tests/archivebot_tests.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Tests for archivebot scripts."""
#
-# (C) Pywikibot team, 2016-2017
+# (C) Pywikibot team, 2016-2018
#
# Distributed under the terms of the MIT license.
#
@@ -121,8 +121,7 @@
"""Test archivebot script on 40+ Wikipedia sites."""
family = 'wikipedia'
- sites = dict((code, {'family': 'wikipedia', 'code': code})
- for code in THREADS)
+ sites = {code: {'family': 'wikipedia', 'code': code} for code in THREADS}
cached = True
@@ -188,8 +187,8 @@
"""
family = 'wikipedia'
- sites = dict((code, {'family': 'wikipedia', 'code': code})
- for code in THREADS_WITH_UPDATED_FORMAT)
+ sites = {code: {'family': 'wikipedia', 'code': code}
+ for code in THREADS_WITH_UPDATED_FORMAT}
cached = True
diff --git a/tests/aspects.py b/tests/aspects.py
index 041e51b..f51a627 100644
--- a/tests/aspects.py
+++ b/tests/aspects.py
@@ -7,7 +7,7 @@
mixin to show cache usage is included.
"""
#
-# (C) Pywikibot team, 2014-2017
+# (C) Pywikibot team, 2014-2018
#
# Distributed under the terms of the MIT license.
#
@@ -157,7 +157,7 @@
@type namespaces: int or set of int
"""
if isinstance(namespaces, int):
- namespaces = set([namespaces])
+ namespaces = {namespaces}
self.assertIn(page.namespace(), namespaces,
"%s not in namespace %r" % (page, namespaces))
@@ -222,7 +222,7 @@
@type namespaces: int or set of int
"""
if isinstance(namespaces, int):
- namespaces = set([namespaces])
+ namespaces = {namespaces}
for page in gen:
self.assertPageInNamespaces(page, namespaces)
@@ -241,7 +241,7 @@
@param skip: bool
"""
if isinstance(namespaces, int):
- namespaces = set([namespaces])
+ namespaces = {namespaces}
else:
assert isinstance(namespaces, set)
@@ -511,14 +511,16 @@
if issubclass(cls, HttpbinTestCase):
# If test uses httpbin, then check is pytest test runner is used
# and pytest_httpbin module is installed.
- httpbin_used = hasattr(sys, '_test_runner_pytest') and pytest_httpbin
+ httpbin_used = hasattr(sys,
+ '_test_runner_pytest') and pytest_httpbin
else:
httpbin_used = False
- # If pytest_httpbin will be used during tests, then remove httpbin.org from sites.
+ # If pytest_httpbin will be used during tests, then remove httpbin.org
+ # from sites.
if httpbin_used:
- cls.sites = dict((k, v) for k, v in cls.sites.items()
- if 'httpbin.org' not in v['hostname'])
+ cls.sites = {k: v for k, v in cls.sites.items()
+ if 'httpbin.org' not in v['hostname']}
for key, data in cls.sites.items():
if 'hostname' not in data:
diff --git a/tests/family_tests.py b/tests/family_tests.py
index 19a841d..36fc96e 100644
--- a/tests/family_tests.py
+++ b/tests/family_tests.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Tests for the family module."""
#
-# (C) Pywikibot team, 2014-2017
+# (C) Pywikibot team, 2014-2018
#
# Distributed under the terms of the MIT license.
#
@@ -56,8 +56,8 @@
if isinstance(f, SingleSiteFamily):
self.assertIsNotNone(f.code)
self.assertIsNotNone(f.domain)
- self.assertEqual(set(f.langs), set([f.code]))
- self.assertEqual(set(f.codes), set([f.code]))
+ self.assertEqual(set(f.langs), {f.code})
+ self.assertEqual(set(f.codes), {f.code})
def test_family_load_invalid(self):
"""Test that an invalid family raised UnknownFamily exception."""
diff --git a/tests/interwiki_graph_tests.py b/tests/interwiki_graph_tests.py
index c2fd0b7..cb42311 100644
--- a/tests/interwiki_graph_tests.py
+++ b/tests/interwiki_graph_tests.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""Test Interwiki Graph functionality."""
#
-# (C) Pywikibot team, 2015-2016
+# (C) Pywikibot team, 2015-2018
#
# Distributed under the terms of the MIT license.
#
@@ -70,7 +70,7 @@
drawer = interwiki_graph.GraphDrawer(data)
- self.assertEqual(set([self.pages['en'].site]), drawer._octagon_site_set())
+ self.assertEqual({self.pages['en'].site}, drawer._octagon_site_set())
drawer.createGraph()
diff --git a/tests/namespace_tests.py b/tests/namespace_tests.py
index 0e658e6..48aac4f 100644
--- a/tests/namespace_tests.py
+++ b/tests/namespace_tests.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Tests for the Namespace class."""
#
-# (C) Pywikibot team, 2014
+# (C) Pywikibot team, 2014-2018
#
# Distributed under the terms of the MIT license.
#
@@ -348,7 +348,7 @@
"""Test performing set minus operation on set of Namespace objects."""
namespaces = Namespace.builtin_namespaces(use_image_name=False)
- excluded_namespaces = set([-1, -2])
+ excluded_namespaces = {-1, -2}
positive_namespaces = set(namespaces) - excluded_namespaces
diff --git a/tests/page_tests.py b/tests/page_tests.py
index 2563b54..cdc29af 100644
--- a/tests/page_tests.py
+++ b/tests/page_tests.py
@@ -471,7 +471,7 @@
if not site.has_extension('Disambiguator'):
raise unittest.SkipTest('Disambiguator extension not loaded on test site')
pg = pywikibot.Page(site, 'Random')
- pg._pageprops = set(['disambiguation', ''])
+ pg._pageprops = {'disambiguation', ''}
self.assertTrue(pg.isDisambig())
pg._pageprops = set()
self.assertFalse(pg.isDisambig())
@@ -878,7 +878,7 @@
self.assertIsInstance(top_two[0], tuple)
self.assertIsInstance(top_two[0][0], basestring)
self.assertIsInstance(top_two[0][1], int)
- top_two_usernames = set([top_two[0][0], top_two[1][0]])
+ top_two_usernames = {top_two[0][0], top_two[1][0]}
self.assertEqual(len(top_two_usernames), 2)
top_two_counts = ([top_two[0][1], top_two[1][1]])
top_two_edit_count = mp.revision_count(top_two_usernames)
@@ -1022,7 +1022,7 @@
pp2 = p2.applicable_protections()
pp3 = p3.applicable_protections()
- self.assertEqual(pp1, set(['create']))
+ self.assertEqual(pp1, {'create'})
self.assertIn('edit', pp2)
self.assertNotIn('create', pp2)
self.assertNotIn('upload', pp2)
diff --git a/tests/pagegenerators_tests.py b/tests/pagegenerators_tests.py
index f2e6c4a..7b2b9ff 100755
--- a/tests/pagegenerators_tests.py
+++ b/tests/pagegenerators_tests.py
@@ -398,7 +398,7 @@
for item in items]
self.assertEqual(sorted(timestamps), timestamps)
self.assertTrue(all(item['ns'] == 0 for item in items))
- self.assertEqual(len(set(item['revid'] for item in items)), self.length)
+ self.assertEqual(len({item['revid'] for item in items}), self.length)
class TestTextfilePageGenerator(DefaultSiteTestCase):
@@ -626,35 +626,35 @@
"""Test one namespace."""
gf = pagegenerators.GeneratorFactory(site=self.get_site())
gf.handleArg('-ns:2')
- self.assertEqual(gf.namespaces, set([2]))
+ self.assertEqual(gf.namespaces, {2})
def test_two_namespaces(self):
"""Test two namespaces."""
gf = pagegenerators.GeneratorFactory(site=self.get_site())
gf.handleArg('-ns:2')
gf.handleArg('-ns:Talk')
- self.assertEqual(gf.namespaces, set([2, 1]))
+ self.assertEqual(gf.namespaces, {2, 1})
def test_two_named_namespaces(self):
"""Test two named namespaces."""
gf = pagegenerators.GeneratorFactory(site=self.get_site())
gf.handleArg('-ns:Talk,File')
- self.assertEqual(gf.namespaces, set([1, 6]))
+ self.assertEqual(gf.namespaces, {1, 6})
def test_two_numeric_namespaces(self):
"""Test two namespaces delimited by colon."""
gf = pagegenerators.GeneratorFactory(site=self.get_site())
gf.handleArg('-ns:1,6')
- self.assertEqual(gf.namespaces, set([1, 6]))
+ self.assertEqual(gf.namespaces, {1, 6})
def test_immutable_namespaces_on_read(self):
"""Test immutable namespaces on read."""
gf = pagegenerators.GeneratorFactory(site=self.get_site())
gf.handleArg('-ns:1,6')
- self.assertEqual(gf.namespaces, set([1, 6]))
+ self.assertEqual(gf.namespaces, {1, 6})
self.assertIsInstance(gf.namespaces, frozenset)
gf.handleArg('-ns:0')
- self.assertEqual(gf.namespaces, set([1, 6]))
+ self.assertEqual(gf.namespaces, {1, 6})
def test_unsupported_quality_level_filter(self):
"""Test unsupported option."""
@@ -713,7 +713,7 @@
gf = pagegenerators.GeneratorFactory(site=self.get_site())
gf.handleArg('-ns:1,2,3,4,5')
gf.handleArg('-ns:not:User')
- self.assertEqual(gf.namespaces, set([1, 3, 4, 5]))
+ self.assertEqual(gf.namespaces, {1, 3, 4, 5})
class TestItemClaimFilterPageGenerator(WikidataTestCase):
@@ -998,7 +998,7 @@
gf.handleArg('-recentchanges:60')
gen = gf.getCombinedGenerator()
self.assertIsNotNone(gen)
- self.assertPagesInNamespacesAll(gen, set([0, 1, 2]), skip=True)
+ self.assertPagesInNamespacesAll(gen, {0, 1, 2}, skip=True)
def test_recentchanges_rctag(self):
"""Test recentchanges generator with recent changes tag."""
@@ -1006,7 +1006,7 @@
gf.handleArg('-recentchanges:visualeditor')
gen = gf.getCombinedGenerator()
self.assertIsNotNone(gen)
- self.assertPagesInNamespacesAll(gen, set([0, 1, 2]), skip=True)
+ self.assertPagesInNamespacesAll(gen, {0, 1, 2}, skip=True)
def test_recentchanges_ns_default(self):
"""Test recentchanges generator."""
@@ -1014,7 +1014,7 @@
gf.handleArg('-recentchanges:50')
gen = gf.getCombinedGenerator()
self.assertIsNotNone(gen)
- self.assertPagesInNamespacesAll(gen, set([0, 1, 2]), skip=True)
+ self.assertPagesInNamespacesAll(gen, {0, 1, 2}, skip=True)
def test_recentchanges_ns(self):
"""Test recentchanges generator with namespace."""
@@ -1033,7 +1033,7 @@
gf.handleArg('-recentchanges:10')
gen = gf.getCombinedGenerator()
self.assertIsNotNone(gen)
- self.assertPagesInNamespaces(gen, set([1, 3]))
+ self.assertPagesInNamespaces(gen, {1, 3})
def test_pageid(self):
"""Test pageid parameter."""
@@ -1092,7 +1092,7 @@
gf.handleArg('-random:10')
gen = gf.getCombinedGenerator()
self.assertIsNotNone(gen)
- self.assertPagesInNamespaces(gen, set([1, 3]))
+ self.assertPagesInNamespaces(gen, {1, 3})
def test_randomredirect_generator_default(self):
"""Test random generator."""
@@ -1120,7 +1120,7 @@
gf.handleArg('-randomredirect:10')
gen = gf.getCombinedGenerator()
self.assertIsNotNone(gen)
- self.assertPagesInNamespaces(gen, set([1, 3]))
+ self.assertPagesInNamespaces(gen, {1, 3})
def test_pages_with_property_generator(self):
"""Test the pages_with_property_generator method."""
@@ -1193,7 +1193,7 @@
for page in pages:
self.assertIsInstance(page, pywikibot.Page)
self.assertEqual(page._lintinfo['category'], 'obsolete-tag')
- self.assertPagesInNamespaces(pages, set([1, ]))
+ self.assertPagesInNamespaces(pages, {1})
def test_linter_generator_invalid_cat(self):
"""Test generator of pages with lint errors."""
diff --git a/tests/paraminfo_tests.py b/tests/paraminfo_tests.py
index ffe7e56..6a0fc60 100644
--- a/tests/paraminfo_tests.py
+++ b/tests/paraminfo_tests.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Test confirming paraminfo contains expected values."""
#
-# (C) Pywikibot team, 2015-2016
+# (C) Pywikibot team, 2015-2018
#
# Distributed under the terms of the MIT license.
#
@@ -129,7 +129,7 @@
if isinstance(self.site, DataSite):
# It is not clear when this format has been added, see T129281.
base.append('application/vnd.php.serialized')
- extensions = set(e['name'] for e in self.site.siteinfo['extensions'])
+ extensions = {e['name'] for e in self.site.siteinfo['extensions']}
if 'CollaborationKit' in extensions:
base.append('text/x-collabkit')
diff --git a/tests/proofreadpage_tests.py b/tests/proofreadpage_tests.py
index 2f8492f..02fae23 100644
--- a/tests/proofreadpage_tests.py
+++ b/tests/proofreadpage_tests.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Tests for the proofreadpage module."""
#
-# (C) Pywikibot team, 2015-2017
+# (C) Pywikibot team, 2015-2018
#
# Distributed under the terms of the MIT license.
#
@@ -491,8 +491,8 @@
'num_pages': 804,
'page': 'Page:Popular Science Monthly Volume 1.djvu/{0}',
'get_label': [11, 11, '1'],
- 'get_number': [[1, set([11])],
- ['Cvr', set([1, 9, 10, 804])],
+ 'get_number': [[1, {11}],
+ ['Cvr', {1, 9, 10, 804}],
],
# 'get_page' is filled in setUpClass.
},
@@ -503,7 +503,7 @@
'num_pages': 272,
'page': 'Seite:Schiller_Musenalmanach_1799_{0:3d}.jpg',
'get_label': [120, 120, '120'], # page no, title no, label
- 'get_number': [[120, set([120])],
+ 'get_number': [[120, {120}],
],
# 'get_page' is filled in setUpClass.
},
@@ -514,7 +514,7 @@
'num_pages': 107,
'page': 'Page:Segard - Hymnes profanes, 1894.djvu/{0}',
'get_label': [11, 11, '8'],
- 'get_number': [[8, set([11])],
+ 'get_number': [[8, {11}],
['-', set(range(1, 4)) | set(range(101, 108))],
],
# 'get_page' is filled in setUpClass.
@@ -534,8 +534,8 @@
# 'get_page' has same structure as 'get_number'.
site_def['get_page'] = []
for label, page_numbers in site_def['get_number']:
- page_set = set(ProofreadPage(site, base_title.format(i))
- for i in page_numbers)
+ page_set = {ProofreadPage(site, base_title.format(i))
+ for i in page_numbers}
site_def['get_page'].append([label, page_set])
def test_check_if_cached(self, key):
diff --git a/tests/script_tests.py b/tests/script_tests.py
index d542f92..7a70d5e 100644
--- a/tests/script_tests.py
+++ b/tests/script_tests.py
@@ -80,10 +80,9 @@
list_scripts(scripts_path, 'login.py') +
list_scripts(archive_path))
-runnable_script_list = (['login'] +
- sorted(set(script_list) -
- set(['login']) -
- set(unrunnable_script_list)))
+runnable_script_list = (
+ ['login'] + sorted(set(script_list)
+ - {'login'} - set(unrunnable_script_list)))
script_input = {
'catall': 'q\n', # q for quit
diff --git a/tests/site_tests.py b/tests/site_tests.py
index 1c5353e..e42c3eb 100644
--- a/tests/site_tests.py
+++ b/tests/site_tests.py
@@ -505,8 +505,8 @@
for bl in backlinks_ns_0:
self.assertIsInstance(bl, pywikibot.Page)
- self.assertEqual(filtered & redirs, set([]))
- self.assertEqual(indirect & redirs, set([]))
+ self.assertEqual(filtered & redirs, set())
+ self.assertEqual(indirect & redirs, set())
self.assertLessEqual(filtered, indirect)
self.assertLessEqual(filtered, backlinks_ns_0)
self.assertLessEqual(redirs, backlinks_ns_0)
@@ -600,7 +600,7 @@
gen_params = links_gen.request._params.copy()
expected_params['gplnamespace'] = [0, 1]
self.assertEqual(gen_params, expected_params)
- self.assertPagesInNamespaces(links_gen, set([0, 1]))
+ self.assertPagesInNamespaces(links_gen, {0, 1})
for target in self.site.preloadpages(
self.site.pagelinks(self.mainpage, follow_redirects=True, total=5)):
@@ -1377,7 +1377,7 @@
pagelist = [mainpage]
if imagepage:
pagelist += [imagepage]
- titlelist = set(page.title() for page in pagelist)
+ titlelist = {page.title() for page in pagelist}
for change in mysite.recentchanges(pagelist=pagelist,
total=5):
self.assertIsInstance(change, dict)
diff --git a/tests/sparql_tests.py b/tests/sparql_tests.py
index 838e567..44b346b 100644
--- a/tests/sparql_tests.py
+++ b/tests/sparql_tests.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Test cases for the SPARQL API."""
#
-# (C) Pywikibot team, 2016
+# (C) Pywikibot team, 2016-2018
#
# Distributed under the terms of the MIT license.
#
@@ -144,7 +144,7 @@
ITEM_Q677525)))
q = sparql.SparqlQuery()
res = q.get_items('SELECT * WHERE { ?x ?y ?z }', 'cat')
- self.assertSetEqual(res, set(['Q498787', 'Q677525']))
+ self.assertSetEqual(res, {'Q498787', 'Q677525'})
res = q.get_items('SELECT * WHERE { ?x ?y ?z }', 'cat',
result_type=list)
self.assertEqual(res, ['Q498787', 'Q677525', 'Q677525'])
diff --git a/tests/textlib_tests.py b/tests/textlib_tests.py
index 49855fd..073373c 100644
--- a/tests/textlib_tests.py
+++ b/tests/textlib_tests.py
@@ -1480,7 +1480,7 @@
def setUpClass(cls):
"""Define set of valid targets for the example text."""
super(TestGetLanguageLinks, cls).setUpClass()
- cls.sites_set = set([cls.enwp, cls.dewp])
+ cls.sites_set = {cls.enwp, cls.dewp}
def test_getLanguageLinks(self, key):
"""Test if the function returns the correct titles and sites."""
@@ -1489,9 +1489,9 @@
m.assert_called_once_with(
'[getLanguageLinks] Text contains invalid interwiki link '
'[[fr:{{PAGENAME}}]].')
- self.assertEqual(set(page.title() for page in lang_links.values()),
- set(['Site']))
- self.assertEqual(set(lang_links), self.sites_set - set([self.site]))
+ self.assertEqual({page.title() for page in lang_links.values()},
+ {'Site'})
+ self.assertEqual(set(lang_links), self.sites_set - {self.site})
class TestUnescape(TestCase):
diff --git a/tests/tools_tests.py b/tests/tools_tests.py
index 0e1aa04..ab58205 100644
--- a/tests/tools_tests.py
+++ b/tests/tools_tests.py
@@ -457,7 +457,7 @@
elif isinstance(deduped, collections.Mapping):
self.assertCountEqual(list(deduped.keys()), [1, 3])
else:
- self.assertEqual(deduped, set([1, 3]))
+ self.assertEqual(deduped, {1, 3})
self.assertEqual(next(deduper), 2)
self.assertEqual(next(deduper), 4)
@@ -468,7 +468,7 @@
elif isinstance(deduped, collections.Mapping):
self.assertCountEqual(list(deduped.keys()), [1, 2, 3, 4])
else:
- self.assertEqual(deduped, set([1, 2, 3, 4]))
+ self.assertEqual(deduped, {1, 2, 3, 4})
self.assertRaises(StopIteration, next, deduper)
@@ -486,7 +486,7 @@
if isinstance(deduped, collections.Mapping):
self.assertEqual(deduped.keys(), [key('1'), key('3')])
else:
- self.assertEqual(deduped, set([key('1'), key('3')]))
+ self.assertEqual(deduped, {key('1'), key('3')})
self.assertEqual(next(deduper), '2')
self.assertEqual(next(deduper), '4')
@@ -495,7 +495,7 @@
if isinstance(deduped, collections.Mapping):
self.assertEqual(deduped.keys(), [key(i) for i in self.strs])
else:
- self.assertEqual(deduped, set(key(i) for i in self.strs))
+ self.assertEqual(deduped, {key(i) for i in self.strs})
self.assertRaises(StopIteration, next, deduper)
@@ -593,7 +593,7 @@
deduper = tools.filter_unique(self.ints, container=deduped)
deduped_out = list(deduper)
self.assertCountEqual(deduped, deduped_out)
- self.assertEqual(deduped, set([2, 4]))
+ self.assertEqual(deduped, {2, 4})
def test_process_again(self):
"""Test filter_unique with an ignoring container."""
@@ -601,7 +601,7 @@
deduper = tools.filter_unique(self.ints, container=deduped)
deduped_out = list(deduper)
self.assertEqual(deduped_out, [1, 3, 2, 1, 1, 4])
- self.assertEqual(deduped, set([2, 4]))
+ self.assertEqual(deduped, {2, 4})
def test_stop(self):
"""Test filter_unique with an ignoring container."""
@@ -610,7 +610,7 @@
deduper = tools.filter_unique(self.ints, container=deduped)
deduped_out = list(deduper)
self.assertCountEqual(deduped, deduped_out)
- self.assertEqual(deduped, set([1, 3]))
+ self.assertEqual(deduped, {1, 3})
# And it should not resume
self.assertRaises(StopIteration, next, deduper)
@@ -620,7 +620,7 @@
deduper = tools.filter_unique(self.ints, container=deduped)
deduped_out = list(deduper)
self.assertCountEqual(deduped, deduped_out)
- self.assertEqual(deduped, set([1, 2, 3]))
+ self.assertEqual(deduped, {1, 2, 3})
# And it should not resume
self.assertRaises(StopIteration, next, deduper)
diff --git a/tests/utils.py b/tests/utils.py
index 4fe6414..2f7837a 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -329,7 +329,7 @@
def __init__(self, cache):
"""Constructor."""
- self._cache = dict((key, (item, False)) for key, item in cache.items())
+ self._cache = {key: (item, False) for key, item in cache.items()}
def __getitem__(self, key):
"""Get item."""
diff --git a/tox.ini b/tox.ini
index c53553a..700e857 100644
--- a/tox.ini
+++ b/tox.ini
@@ -152,7 +152,6 @@
# W503: line break before binary operator; against current PEP 8 recommendation
# The following are to be fixed
-# C401, C402, C405: does not work with py 2.6
# D102: Missing docstring in public method
# D103: Missing docstring in public function
# E402: module level import not at top of file; see T87409
@@ -164,7 +163,7 @@
# D413: Missing blank line after last section
# D412: No blank lines allowed between a section header and its content
-ignore = C401,C402,C405,E402,D105,D211,FI10,FI12,FI13,FI15,FI16,FI17,FI5,H101,H236,H301,H404,H405,H903,I100,I101,I202,N802,N803,N806,D401,D413,D103,D412,W503
+ignore = E402,D105,D211,FI10,FI12,FI13,FI15,FI16,FI17,FI5,H101,H236,H301,H404,H405,H903,I100,I101,I202,N802,N803,N806,D401,D413,D103,D412,W503
exclude = .tox,.git,./*.egg,ez_setup.py,build,externals,user-config.py,./scripts/i18n/*,scripts/userscripts/*
min-version = 2.7
max_line_length = 100
--
To view, visit https://gerrit.wikimedia.org/r/423343
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I2e0beeba198c004900f70a622985b3f049524fd6
Gerrit-Change-Number: 423343
Gerrit-PatchSet: 5
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/263372 )
Change subject: Abandon support for python 2.6
......................................................................
Abandon support for python 2.6
- remove 2.6 tests from appreyor and travis
- update HISTORY.rst and docs
- update requirements
- update docs
- remove backports from doc
- cleanup backports.py (to be deleted later)
- cleanup tools
- update library parts and tests
Bug: T154771
Change-Id: Ied97711c81adebe9c260c8e7c2647b6cc71846fa
---
M .appveyor.yml
M .travis.yml
M HISTORY.rst
M dev-requirements.txt
M docs/api_ref/pywikibot.rst
M docs/index.rst
M pwb.py
M pywikibot/CONTENT.rst
M pywikibot/README.rst
M pywikibot/__init__.py
M pywikibot/backports.py
M pywikibot/bot.py
M pywikibot/diff.py
M pywikibot/family.py
M pywikibot/interwiki_graph.py
M pywikibot/page.py
M pywikibot/site_detect.py
M pywikibot/textlib.py
M pywikibot/tools/__init__.py
M pywikibot/tools/djvu.py
M requests-requirements.txt
M requirements.txt
M setup.py
M tests/__init__.py
M tests/link_tests.py
M tests/python_tests.py
M tests/script_tests.py
M tests/textlib_tests.py
M tests/tools_tests.py
M tests/utils.py
M tox.ini
31 files changed, 89 insertions(+), 413 deletions(-)
Approvals:
Dalba: Looks good to me, approved
jenkins-bot: Verified
diff --git a/.appveyor.yml b/.appveyor.yml
index 87a3ef6..85ccee8 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -17,15 +17,6 @@
# Test the lowest supported release of each major Python version.
- # Pywikibot support matrix suggests 'should run' on Python 2.6.5+
- # Only Python 2.6.6 is able to be set up on Appveyor.
- # https://github.com/ogrisel/python-appveyor-demo/issues/10
- # fwiw, Redhat Enterprise Linux ships with 2.6.6.
-
- - PYTHON: "C:\\Python266-x64"
- PYTHON_VERSION: "2.6.6"
- PYTHON_ARCH: "64"
-
- PYTHON: "C:\\Python272"
PYTHON_VERSION: "2.7.2"
PYTHON_ARCH: "32"
@@ -92,10 +83,6 @@
- pip install virtualenv
- virtualenv env
- env\Scripts\activate.bat
- # wheel version 0.29.0 is enforced because version 0.30.0 doesn't support
- # Python 2.6 and 3.3 anymore. Once we drop support for those versions we
- # can use the latest version of wheel.
- - pip install wheel==0.29.0
- pip install -r dev-requirements.txt
- pip install -r requests-requirements.txt
diff --git a/.travis.yml b/.travis.yml
index 044670e..cdd20c0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,6 @@
sudo: false
python:
- - '2.6'
- '2.7'
- '3.4'
- '3.5'
@@ -160,7 +159,7 @@
env: LANGUAGE=test FAMILY=wikidata SITE_ONLY=1
- python: '3.4'
env: LANGUAGE=ar FAMILY=wiktionary PYWIKIBOT2_TEST_NO_RC=1
- - python: '2.6'
+ - python: '3.6'
env: LANGUAGE=wikidata FAMILY=wikidata SITE_ONLY=1
notifications:
diff --git a/HISTORY.rst b/HISTORY.rst
index d989c25..3c7d1e2 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -4,6 +4,7 @@
Current release
---------------
+* Dropped support for Python 2.6 (T154771)
* Dropped support for Python 3.3 (T184508)
* Bugfixes and improvements
* Localisation updates
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 5084cdf..d3eb990 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,6 +1,6 @@
# This is a PIP 6+ requirements file for development dependencies
#
-unittest2==0.8.0 ; python_full_version < '2.7.3'
+unittest2==0.8.0 ; python_full_version == '2.7.2'
pytest>=2.8.0
pytest-timeout
@@ -8,7 +8,7 @@
pytest-cov
pytest-attrib
pytest-httpbin
-httpbin<0.6.0 ; os_name != 'posix' or python_version < '2.7'
+httpbin<0.6.0 ; os_name != 'posix'
six
@@ -35,5 +35,3 @@
# are not useful on the Appveyor Win32 builds since the relevant UI tests
# also require accessing the menu of the console window, which doesnt exist
# in the Appveyor environment.
-
-setuptools_scm ; python_version == '2.6'
diff --git a/docs/api_ref/pywikibot.rst b/docs/api_ref/pywikibot.rst
index 21c21b3..d683df6 100644
--- a/docs/api_ref/pywikibot.rst
+++ b/docs/api_ref/pywikibot.rst
@@ -21,14 +21,6 @@
Submodules
----------
-pywikibot.backports module
---------------------------
-
-.. automodule:: pywikibot.backports
- :members:
- :undoc-members:
- :show-inheritance:
-
pywikibot.bot module
--------------------
diff --git a/docs/index.rst b/docs/index.rst
index 91c773c..8a6cea7 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -13,7 +13,7 @@
Pywikibot is a Python library and collection of scripts that automate work on `MediaWiki <https://mediawiki.org>`_ sites.
-Pywikibot supports Python 2.6.5+, 2.7.2+ and 3.4+.
+Pywikibot supports Python 2.7.2+ and 3.4+.
Pywikibot and this documentation are licensed under the :ref:`MIT license <licenses-MIT>`;
manual pages on mediawiki.org are licensed under the `CC-BY-SA 3.0`_ license.
diff --git a/pwb.py b/pwb.py
index aed8514..afd2607 100755
--- a/pwb.py
+++ b/pwb.py
@@ -30,22 +30,19 @@
PYTHON_VERSION = sys.version_info[:3]
PY2 = (PYTHON_VERSION[0] == 2)
-PY26 = (PYTHON_VERSION < (2, 7))
versions_required_message = """
Pywikibot is not available on:
{version}
-This version of Pywikibot only supports Python 2.6.5+, 2.7.2+ or 3.4+.
+This version of Pywikibot only supports Python 2.7.2+ or 3.4+.
"""
def python_is_supported():
"""Check that Python is supported."""
# Any change to this must be copied to setup.py
- return (PYTHON_VERSION >= (3, 4, 0) or
- (PY2 and PYTHON_VERSION >= (2, 7, 2)) or
- (PY26 and PYTHON_VERSION >= (2, 6, 5)))
+ return PYTHON_VERSION >= (3, 4, 0) or PY2 and PYTHON_VERSION >= (2, 7, 2)
if not python_is_supported():
diff --git a/pywikibot/CONTENT.rst b/pywikibot/CONTENT.rst
index 180c4e4..cd486e8 100644
--- a/pywikibot/CONTENT.rst
+++ b/pywikibot/CONTENT.rst
@@ -9,8 +9,8 @@
+---------------------------+-------------------------------------------------------+
| _wbtypes.py | Wikibase data type classes |
+---------------------------+-------------------------------------------------------+
- | backports.py | Module contains backports to support older Python |
- | | versions |
+ | backports.py | Deprecated module that contained backports to support |
+ | | older Python versions (could be dropped soon) |
+---------------------------+-------------------------------------------------------+
| bot.py | User-interface related functions for building bots |
+---------------------------+-------------------------------------------------------+
diff --git a/pywikibot/README.rst b/pywikibot/README.rst
index a9dd281..a817648 100644
--- a/pywikibot/README.rst
+++ b/pywikibot/README.rst
@@ -30,7 +30,7 @@
* python-tkinter (optional, used by some experimental GUI stuff)
-You need to have at least python version `2.6.5 <http://www.python.org/download/>`_
+You need to have at least python version `2.7.2 <http://www.python.org/download/>`_
or newer installed on your computer to be able to run any of the code in this
package, but not 3.0-3.3. It works fine with 3.4+ versions of python installed.
Support for older versions of python is not planned. Some scripts could run with
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 1264b64..cd3e18c 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -135,13 +135,6 @@
deprecate_arg = redirect_func(_deprecate_arg)
-if sys.version_info[:2] == (2, 6):
- warn(
- 'Pywikibot will soon drop support for Python 2.6',
- DeprecationWarning,
- )
-
-
class Timestamp(datetime.datetime):
"""Class for handling MediaWiki timestamps.
diff --git a/pywikibot/backports.py b/pywikibot/backports.py
index 86c8de7..52a711e 100644
--- a/pywikibot/backports.py
+++ b/pywikibot/backports.py
@@ -1,169 +1,48 @@
# -*- coding: utf-8 -*-
"""
-This module contains backports to support older Python versions.
+This module contained backports to support older Python versions.
-They contain the backported code originally developed for Python. It is
-therefore distributed under the PSF license.
+Their usage is deprecated and this module could be dropped soon.
"""
#
-# (C) Python Software Foundation, 2001-2014
-# (C) with modifications from Pywikibot team, 2015
+# (C) Pywikibot team, 2015-2018
#
-# Distributed under the terms of the PSF license.
+# Distributed under the terms of the MIT license.
#
from __future__ import absolute_import, unicode_literals
-__license__ = """
-PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
---------------------------------------------
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using this software ("Python") in source or binary form and
-its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF hereby
-grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
-analyze, test, perform and/or display publicly, prepare derivative works,
-distribute, and otherwise use Python alone or in any derivative version,
-provided, however, that PSF's License Agreement and PSF's notice of copyright,
-i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013, 2014 Python Software Foundation; All Rights Reserved" are
-retained in Python alone or in any derivative version prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python.
-
-4. PSF is making Python available to Licensee on an "AS IS"
-basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee. This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-"""
-
+from difflib import _format_range_unified
import logging
-import warnings
+
+from pywikibot.tools import deprecated
+@deprecated('difflib._format_range_unified')
def format_range_unified(start, stop):
"""
Convert range to the "ed" format.
- Copied from C{difflib._format_range_unified()} which was introduced in
- Python 2.7.2.
-
- @see: https://hg.python.org/cpython/file/8527427914a2/Lib/difflib.py#l1147
+ DEPRECATED (Python 2.6 backport).
+ Use difflib._format_range_unified instead.
"""
- # Per the diff spec at http://www.unix.org/single_unix_specification/
- beginning = start + 1 # lines start numbering with one
- length = stop - start
- if length == 1:
- return '{0}'.format(beginning)
- if not length:
- beginning -= 1 # empty ranges begin at line just before the range
- return '{0},{1}'.format(beginning, length)
+ return _format_range_unified(start, stop)
-# Logging/Warnings integration
+@deprecated('logging.NullHandler')
+class NullHandler(logging.NullHandler):
-_warnings_showwarning = None
+ """This handler does nothing."""
+
+ pass
-class NullHandler(logging.Handler):
-
- """
- This handler does nothing.
-
- It's intended to be used to avoid the "No handlers could be found for
- logger XXX" one-off warning. This is important for library code, which
- may contain code to log events. If a user of the library does not configure
- logging, the one-off warning might be produced; to avoid this, the library
- developer simply needs to instantiate a NullHandler and add it to the
- top-level logger of the library module or package.
-
- Copied from C{logging.NullHandler} which was introduced in Python 2.7.
-
- @see: http://bugs.python.org/issue4384
- """
-
- def handle(self, record):
- """Dummy handling."""
- pass
-
- def emit(self, record):
- """Dummy handling."""
- pass
-
- def createLock(self):
- """Dummy handling."""
- self.lock = None
-
-
-def _showwarning(message, category, filename, lineno, file=None, line=None):
- """
- Implementation of showwarnings which redirects to logging.
-
- It will first check to see if the file parameter is None. If a file is
- specified, it will delegate to the original warnings implementation of
- showwarning. Otherwise, it will call warnings.formatwarning and will log
- the resulting string to a warnings logger named "py.warnings" with level
- logging.WARNING.
-
- Copied from C{logging._showwarning} which was introduced in Python 2.7.
-
- @see: http://bugs.python.org/issue4384
- """
- if file is not None:
- if _warnings_showwarning is not None:
- _warnings_showwarning(message, category, filename, lineno, file, line)
- else:
- s = warnings.formatwarning(message, category, filename, lineno, line)
- logger = logging.getLogger("py.warnings")
- if not logger.handlers:
- logger.addHandler(NullHandler())
- logger.warning("%s", s)
-
-
+@deprecated('logging.captureWarnings')
def captureWarnings(capture):
"""
Capture warnings into logging.
- If capture is true, redirect all warnings to the logging package.
- If capture is False, ensure that warnings are not redirected to logging
- but to their original destinations.
-
- Copied from C{logging.captureWarnings} which was introduced in Python 2.7.
-
- @see: http://bugs.python.org/issue4384
+ DEPRECATED (Python 2.6 backport).
+ Use logging.captureWarnings instead.
"""
- global _warnings_showwarning
- if capture:
- if _warnings_showwarning is None:
- _warnings_showwarning = warnings.showwarning
- warnings.showwarning = _showwarning
- else:
- if _warnings_showwarning is not None:
- warnings.showwarning = _warnings_showwarning
- _warnings_showwarning = None
+ logging.captureWarnings(capture)
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index 2c8f041..ceb9459 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -77,7 +77,6 @@
import pywikibot
-from pywikibot import backports
from pywikibot import config
from pywikibot import daemonize
from pywikibot import i18n
@@ -250,10 +249,7 @@
# If there are command line warnings options, do not override them
if not sys.warnoptions:
- if hasattr(logging, 'captureWarnings'):
- logging.captureWarnings(True) # introduced in Python >= 2.7
- else:
- backports.captureWarnings(True)
+ logging.captureWarnings(True)
if config.debug_log or 'deprecation' in config.log:
warnings.filterwarnings("always")
diff --git a/pywikibot/diff.py b/pywikibot/diff.py
index 636be64..95669e9 100644
--- a/pywikibot/diff.py
+++ b/pywikibot/diff.py
@@ -12,6 +12,7 @@
import sys
from collections import Sequence
+from difflib import _format_range_unified as format_range_unified
if sys.version_info[0] > 2:
from itertools import zip_longest
else:
@@ -20,7 +21,6 @@
import pywikibot
from pywikibot.tools import chars
-from pywikibot.backports import format_range_unified # introduced in 2.7.2
from pywikibot.tools import deprecated_args
from pywikibot.tools.formatter import color_format
diff --git a/pywikibot/family.py b/pywikibot/family.py
index d6524c7..632aff5 100644
--- a/pywikibot/family.py
+++ b/pywikibot/family.py
@@ -16,13 +16,12 @@
PY3 = sys.version_info[0] > 2
if PY3:
- from os.path import basename, dirname, splitext
- from importlib import import_module
import urllib.parse as urlparse
else:
- import imp
import urlparse
+from os.path import basename, dirname, splitext
+from importlib import import_module
from warnings import warn
import pywikibot
@@ -959,12 +958,8 @@
# RuntimeWarning's while loading.
with warnings.catch_warnings():
warnings.simplefilter("ignore", RuntimeWarning)
- if PY3:
- sys.path.append(dirname(family_file))
- mod = import_module(splitext(basename(family_file))[0])
- else:
- # Python 2.6 has no importlib.import_module
- mod = imp.load_source(fam, family_file)
+ sys.path.append(dirname(family_file))
+ mod = import_module(splitext(basename(family_file))[0])
except ImportError:
raise UnknownFamily(u'Family %s does not exist' % fam)
cls = mod.Family()
diff --git a/pywikibot/interwiki_graph.py b/pywikibot/interwiki_graph.py
index bdad631..e14797b 100644
--- a/pywikibot/interwiki_graph.py
+++ b/pywikibot/interwiki_graph.py
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
"""Module with the Graphviz drawing calls."""
#
-# (C) Pywikibot team, 2006-2016
+# (C) Pywikibot team, 2006-2018
#
# Distributed under the terms of the MIT license.
#
from __future__ import absolute_import, unicode_literals
+from collections import Counter
import itertools
import threading
@@ -18,7 +19,6 @@
import pywikibot
from pywikibot import config2 as config
-from pywikibot.tools import Counter
# deprecated value
pydotfound = not isinstance(pydot, ImportError)
diff --git a/pywikibot/page.py b/pywikibot/page.py
index bf836c2..fa29cf4 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -29,7 +29,7 @@
except ImportError:
import unicodedata
-from collections import defaultdict, namedtuple
+from collections import Counter, defaultdict, namedtuple, OrderedDict
from warnings import warn
from pywikibot.tools import PY2
@@ -65,13 +65,11 @@
from pywikibot.site import DataSite, Namespace, need_version
from pywikibot.tools import (
compute_file_hash,
- PYTHON_VERSION,
MediaWikiVersion, UnicodeMixin, ComparableMixin, DotReadableDict,
deprecated, deprecate_arg, deprecated_args, issue_deprecation_warning,
add_full_name, manage_wrapping,
ModuleDeprecationWrapper as _ModuleDeprecationWrapper,
first_upper, redirect_func, remove_last_args, _NotImplementedWarning,
- OrderedDict, Counter,
)
from pywikibot.tools.ip import ip_regexp
from pywikibot.tools.ip import is_IP
@@ -5421,9 +5419,6 @@
@type defaultNamespace: int
@raises UnicodeError: text could not be converted to unicode.
- On Python 2.6.6 without unicodedata2, this could also be raised
- if the text contains combining characters.
- See https://phabricator.wikimedia.org/T102461
"""
source_is_page = isinstance(source, BasePage)
@@ -5460,16 +5455,6 @@
# Normalize unicode string to a NFC (composed) format to allow
# proper string comparisons to strings output from MediaWiki API.
- # Due to Python issue 10254, this is not possible on Python 2.6.6
- # if the string contains combining characters. See T102461.
- if (PYTHON_VERSION == (2, 6, 6) and
- unicodedata.__name__ != 'unicodedata2' and
- any(unicodedata.combining(c) for c in t)):
- raise UnicodeError(
- 'Link(%r, %s): combining characters detected, which are '
- 'not supported by Pywikibot on Python 2.6.6. See '
- 'https://phabricator.wikimedia.org/T102461'
- % (t, self._source))
t = unicodedata.normalize('NFC', t)
# This code was adapted from Title.php : secureAndSplit()
diff --git a/pywikibot/site_detect.py b/pywikibot/site_detect.py
index 56c9b62..534c813 100644
--- a/pywikibot/site_detect.py
+++ b/pywikibot/site_detect.py
@@ -23,9 +23,9 @@
from html.parser import HTMLParser
from urllib.parse import urljoin, urlparse
else:
- try:
- from future.backports.html.parser import HTMLParser
- except ImportError:
+ if PYTHON_VERSION == (2, 7, 2):
+ from future.backports.html.parser import HTMLParser # T175873
+ else:
from HTMLParser import HTMLParser
from urlparse import urljoin, urlparse
diff --git a/pywikibot/textlib.py b/pywikibot/textlib.py
index 2c2b26c..f959673 100644
--- a/pywikibot/textlib.py
+++ b/pywikibot/textlib.py
@@ -13,7 +13,7 @@
#
from __future__ import absolute_import, unicode_literals
-import collections
+from collections import OrderedDict, Sequence
import datetime
import re
import sys
@@ -39,7 +39,6 @@
deprecate_arg,
deprecated,
DeprecatedRegex,
- OrderedDict,
StringTypes,
UnicodeType,
issue_deprecation_warning
@@ -645,7 +644,7 @@
title += '#' + l.section
return title
- if isinstance(replace, collections.Sequence):
+ if isinstance(replace, Sequence):
if len(replace) != 2:
raise ValueError('When used as a sequence, the "replace" '
'argument must contain exactly 2 items.')
diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py
index 611a957..7438303 100644
--- a/pywikibot/tools/__init__.py
+++ b/pywikibot/tools/__init__.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Miscellaneous helper functions (not wiki-dependent)."""
#
-# (C) Pywikibot team, 2008-2017
+# (C) Pywikibot team, 2008-2018
#
# Distributed under the terms of the MIT license.
#
@@ -100,59 +100,6 @@
"""Constructor."""
raise NotImplementedError(
'%s: %s' % (self.__class__.__name__, self.__doc__))
-
-
-if PYTHON_VERSION < (2, 7):
- try:
- import future.backports.misc
- except ImportError:
- warn("""
-pywikibot support of Python 2.6 relies on package future for many features.
-Please upgrade to Python 2.7+ or Python 3.4+, or run:
- "pip install future>=0.15.0"
-""", RuntimeWarning)
- try:
- from ordereddict import OrderedDict
- except ImportError:
- class OrderedDict(NotImplementedClass):
-
- """OrderedDict not found."""
-
- pass
-
- try:
- from counter import Counter
- except ImportError:
- class Counter(NotImplementedClass):
-
- """Counter not found."""
-
- pass
- count = None
- else:
- Counter = future.backports.misc.Counter
- OrderedDict = future.backports.misc.OrderedDict
-
- try:
- count = future.backports.misc.count
- except AttributeError:
- warn('Please update the "future" package to at least version '
- '0.15.0 to use its count.', RuntimeWarning, 2)
- count = None
- del future
-
- if count is None:
- def count(start=0, step=1):
- """Backported C{count} to support keyword arguments and step."""
- while True:
- yield start
- start += step
-
-
-else:
- Counter = collections.Counter
- OrderedDict = collections.OrderedDict
- count = itertools.count
def has_module(module):
@@ -1536,7 +1483,7 @@
if wrapper.__signature__:
# Build a new signature with deprecated args added.
# __signature__ is only available in Python 3 which has OrderedDict
- params = OrderedDict()
+ params = collections.OrderedDict()
for param in wrapper.__signature__.parameters.values():
params[param.name] = param.replace()
for old_arg, new_arg in arg_pairs.items():
@@ -1837,3 +1784,9 @@
bytes_to_read -= len(read_bytes)
sha.update(read_bytes)
return sha.hexdigest()
+
+
+wrapper = ModuleDeprecationWrapper(__name__)
+wrapper._add_deprecated_attr('Counter', collections.Counter)
+wrapper._add_deprecated_attr('OrderedDict', collections.OrderedDict)
+wrapper._add_deprecated_attr('count', itertools.count)
diff --git a/pywikibot/tools/djvu.py b/pywikibot/tools/djvu.py
index 4e919fe..c386410 100644
--- a/pywikibot/tools/djvu.py
+++ b/pywikibot/tools/djvu.py
@@ -2,12 +2,13 @@
# -*- coding: utf-8 -*-
"""Wrapper around djvulibre to access djvu files properties and content."""
#
-# (C) Pywikibot team, 2015-2017
+# (C) Pywikibot team, 2015-2018
#
# Distributed under the terms of the MIT license.
#
from __future__ import absolute_import, unicode_literals
+from collections import Counter
import os
import re
import subprocess
@@ -15,7 +16,6 @@
import pywikibot
from pywikibot.tools import (
- Counter,
deprecated, deprecated_args,
StringTypes,
UnicodeType,
diff --git a/requests-requirements.txt b/requests-requirements.txt
index 651eabf..cf986cd 100644
--- a/requests-requirements.txt
+++ b/requests-requirements.txt
@@ -2,11 +2,8 @@
# requests security extra
# Bug T105767 on Python 2.7 release 9+
-cryptography>=1.3.4 ; python_version != '2.6' and (python_full_version < '2.7.9' or python_version > '3.3')
-cryptography>=1.3.4,<=2.0.3 ; python_version == '2.6' and platform_system == 'Windows'
-cryptography>=1.3.4,<2.2 ; python_version == '2.6' and platform_system != 'Windows'
-pyOpenSSL>=0.14,!=17.2.0 ; python_full_version < '2.7.9' and python_version != '2.6'
-PyOpenSSL<17.5.0 ; python_version == '2.6'
+cryptography>=1.3.4 ; python_full_version < '2.7.9' or python_version > '3.3'
+pyOpenSSL>=0.14,!=17.2.0 ; python_full_version < '2.7.9'
idna>=2.0.0 ; python_full_version < '2.7.9' or python_version >= '3'
# https://github.com/eliben/pycparser/issues/147
pycparser != 2.14
diff --git a/requirements.txt b/requirements.txt
index f3c051f..ffd1dba 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -22,11 +22,9 @@
requests>=2.9,!=2.18.2
# requests security extra
-cryptography>=1.3.4 ; python_version != '2.6' and python_full_version < '2.7.9'
-cryptography>=1.3.4,<=2.0.3 ; python_version == '2.6' and platform_system == 'Windows'
-cryptography>=1.3.4,<2.2 ; python_version == '2.6' and platform_system != 'Windows'
-pyOpenSSL>=0.14,!=17.2.0 ; python_full_version < '2.7.9' and python_version != '2.6'
-PyOpenSSL<17.5.0 ; python_version == '2.6'
+cryptography>=1.3.4 ; python_full_version < '2.7.9'
+pyOpenSSL>=0.14,!=17.2.0 ; python_full_version < '2.7.9'
+
idna>=2.0.0 ; python_full_version < '2.7.9'
# https://github.com/eliben/pycparser/issues/147
pycparser != 2.14
@@ -46,15 +44,13 @@
git+https://github.com/nlhepler/pydot#egg=pydot-1.0.29
# wikistats.py and scripts
-unicodecsv!=0.14.0 ; python_version < '2.7'
-unicodecsv ; python_version < '3' and python_version >= '2.7'
+unicodecsv ; python_version < '3'
# cosmetic_changes and scripts/isbn
python-stdnum
# GUI
-Pillow<4.0.0 ; python_version == '2.6'
-Pillow ; python_version == '2.7' or python_version >= '3.4'
+Pillow
# core pagegenerators
google >= 1.7
@@ -63,21 +59,11 @@
# scripts/script_wui.py:
crontab
-# scipts/replicate_wiki.py and scripts/editarticle.py
-argparse ; python_version < '2.7'
-
# scripts/flickrripper.py
-# On Python 2, flickrapi 1.4.x or 2.x may be used. Only 2.x works on Python 3.
-# The following automatically selects 2.x on all Python versions, which depends
-# on requests 2.x, which may cause pip to report an error like the following:
-# pkg_resources.VersionConflict: (requests 1.2.3 (/usr/lib/python2.7/site-packages), Requirement.parse('requests>=2.2.1'))
-# If you see that on Python 2, change this to flickrapi==1.4.5
-# On Python 3, force pip to install requests 2.2.1, or remove flickrapi below.
-flickrapi>=1.4.5,<2 ; python_version < '2.7'
-flickrapi ; python_version >= '2.7'
+flickrapi
# incomplete core component botirc
-irc ; python_version > '2.6'
+irc
# textlib.py and patrol.py
mwparserfromhell>=0.3.3
diff --git a/setup.py b/setup.py
index 1b2ccce..90d1649 100644
--- a/setup.py
+++ b/setup.py
@@ -23,22 +23,19 @@
PYTHON_VERSION = sys.version_info[:3]
PY2 = (PYTHON_VERSION[0] == 2)
-PY26 = (PYTHON_VERSION < (2, 7))
versions_required_message = """
Pywikibot is not available on:
{version}
-This version of Pywikibot only supports Python 2.6.5+, 2.7.2+ or 3.4+.
+This version of Pywikibot only supports Python 2.7.2+ or 3.4+.
"""
def python_is_supported():
"""Check that Python is supported."""
# Any change to this must be copied to pwb.py
- return (PYTHON_VERSION >= (3, 4, 0) or
- (PY2 and PYTHON_VERSION >= (2, 7, 2)) or
- (PY26 and PYTHON_VERSION >= (2, 6, 5)))
+ return PYTHON_VERSION >= (3, 4, 0) or PY2 and PYTHON_VERSION >= (2, 7, 2)
if not python_is_supported():
@@ -48,25 +45,15 @@
dependencies = ['requests>=2.9,!=2.18.2']
-# the irc module has no Python 2.6 support since 10.0
-irc_dep = 'irc==8.9' if sys.version_info < (2, 7) else 'irc'
-csv_dep = 'unicodecsv!=0.14.0' if PYTHON_VERSION < (2, 7) else 'unicodecsv'
-
-# According to https://pillow.readthedocs.io/en/latest/installation.html#notes
-if PY26:
- pillow = 'Pillow<4.0.0'
-else:
- pillow = 'Pillow'
-
extra_deps = {
# Core library dependencies
'eventstreams': ['sseclient>=0.0.18'],
'isbn': ['python-stdnum'],
'Graphviz': ['pydot>=1.0.28'],
'Google': ['google>=1.7'],
- 'IRC': [irc_dep],
+ 'IRC': ['irc'],
'mwparserfromhell': ['mwparserfromhell>=0.3.3'],
- 'Tkinter': [pillow],
+ 'Tkinter': ['Pillow'],
'security': ['requests[security]', 'pycparser!=2.14'],
'mwoauth': ['mwoauth>=0.2.4,!=0.3.1'],
'html': ['BeautifulSoup4'],
@@ -75,31 +62,21 @@
if PY2:
# Additional core library dependencies which are only available on Python 2
extra_deps.update({
- 'csv': [csv_dep],
+ 'csv': ['unicodecsv'],
'MySQL': ['oursql'],
'unicode7': ['unicodedata2>=7.0.0-2'],
})
script_deps = {
- 'flickrripper.py': [pillow],
+ 'flickrripper.py': ['flickrapi', 'Pillow'],
'states_redirect.py': ['pycountry'],
'weblinkchecker.py': ['memento_client>=0.5.1,!=0.6.0'],
'patrol.py': ['mwparserfromhell>=0.3.3'],
}
-# flickrapi 1.4.4 installs a root logger in verbose mode; 1.4.5 fixes this.
-# The problem doesnt exist in flickrapi 2.x.
-# pywikibot accepts flickrapi 1.4.5+ on Python 2, as it has been stable for a
-# long time, and only depends on python-requests 1.x, whereas flickrapi 2.x
-# depends on python-requests 2.x, which is first packaged in Ubuntu 14.04
-# and will be first packaged for Fedora Core 21.
-# flickrapi 1.4.x does not run on Python 3, and setuptools can only
-# select flickrapi 2.x for Python 3 installs.
-script_deps['flickrripper.py'].append(
- 'flickrapi>=1.4.5,<2' if PY26 else 'flickrapi')
# lunatic-python is only available for Linux
if sys.platform.startswith('linux'):
- script_deps['script_wui.py'] = [irc_dep, 'lunatic-python', 'crontab']
+ script_deps['script_wui.py'] = ['irc', 'lunatic-python', 'crontab']
# The main pywin32 repository contains a Python 2 only setup.py with a small
# wrapper setup3.py for Python 3.
@@ -113,7 +90,7 @@
'git+https://github.com/nlhepler/pydot#egg=pydot-1.0.29',
]
-if PYTHON_VERSION < (2, 7, 3):
+if PYTHON_VERSION == (2, 7, 2):
# work around distutils hardcoded unittest dependency
# work around T106512
import unittest
@@ -123,12 +100,6 @@
sys.modules['unittest'] = unittest2
if sys.version_info[0] == 2:
- if PY26:
- script_deps['replicate_wiki.py'] = ['argparse']
- dependencies.append('future>=0.15.0') # provides collections backports
-
- dependencies += extra_deps['unicode7'] # T102461 workaround
-
# tools.ip does not have a hard dependency on an IP address module,
# as it falls back to using regexes if one is not available.
# The functional backport of py3 ipaddress is acceptable:
@@ -139,7 +110,7 @@
# ipaddr 2.1.10+ is distributed with Debian and Fedora. See T105443.
dependencies.append('ipaddr>=2.1.10')
- if sys.version_info < (2, 7, 3):
+ if sys.version_info == (2, 7, 2):
dependencies.append('future>=0.15.0') # Bug fixes for HTMLParser
if sys.version_info < (2, 7, 9):
@@ -257,7 +228,6 @@
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Operating System :: OS Independent',
- 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
diff --git a/tests/__init__.py b/tests/__init__.py
index f548ec6..75404a3 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Package tests."""
#
-# (C) Pywikibot team, 2007-2015
+# (C) Pywikibot team, 2007-2018
#
# Distributed under the terms of the MIT license.
#
@@ -16,7 +16,6 @@
# Verify that the unit tests have a base working environment:
# - requests is mandatory
-# - future is needed as a fallback for python 2.6,
# however if unavailable this will fail on use; see pywikibot/tools.py
# - unittest2; see below
# - mwparserfromhell is optional, so is only imported in textlib_tests
@@ -24,9 +23,8 @@
from pywikibot.tools import PYTHON_VERSION
-if PYTHON_VERSION < (2, 7, 3):
- # unittest2 is a backport of python 2.7s unittest module to python 2.6
- # Also use unittest2 for python 2.7.2 (T106512)
+if PYTHON_VERSION == (2, 7, 2):
+ # Use unittest2 for python 2.7.2 (T106512)
import unittest2 as unittest
else:
import unittest
diff --git a/tests/link_tests.py b/tests/link_tests.py
index 5b661b5..0fcfcc3 100644
--- a/tests/link_tests.py
+++ b/tests/link_tests.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Test Link functionality."""
#
-# (C) Pywikibot team, 2014-2017
+# (C) Pywikibot team, 2014-2018
#
# Distributed under the terms of the MIT license.
#
@@ -14,7 +14,6 @@
from pywikibot import config2 as config
from pywikibot.page import Link, Page
from pywikibot.exceptions import Error, InvalidTitle
-from pywikibot.tools import PYTHON_VERSION
from tests.aspects import (
unittest,
@@ -240,19 +239,6 @@
title = 'Li̍t-sṳ́'
link = Link(title, self.site)
self.assertEqual(link.title, 'Li̍t-sṳ́')
-
- @unittest.skipIf(PYTHON_VERSION != (2, 6, 6), 'Python 2.6.6-only test')
- def test_py266_bug_exception(self):
- """Test Python issue 10254 causes an exception."""
- pywikibot.page.unicodedata = __import__('unicodedata')
- title = 'Li̍t-sṳ́'
- with self.assertRaisesRegex(
- UnicodeError,
- re.escape('Link(%r, %s): combining characters detected, which '
- 'are not supported by Pywikibot on Python 2.6.6. '
- 'See https://phabricator.wikimedia.org/T102461'
- % (title, self.site))):
- Link(title, self.site)
# ---- The first set of tests are explicit links, starting with a ':'.
diff --git a/tests/python_tests.py b/tests/python_tests.py
index 0320f8e..6dcbd9f 100755
--- a/tests/python_tests.py
+++ b/tests/python_tests.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""Tests Python features."""
#
-# (C) Pywikibot team, 2015
+# (C) Pywikibot team, 2015-2018
#
# Distributed under the terms of the MIT license.
from __future__ import absolute_import, unicode_literals
@@ -13,15 +13,9 @@
except ImportError:
unicodedata2 = None
-from pywikibot.tools import PYTHON_VERSION
-
from tests.aspects import TestCase, unittest
-from tests.utils import expected_failure_if
# TODO:
-# very old
-# http://bugs.python.org/issue2517
-#
# unicode
# http://sourceforge.net/p/pywikipediabot/bugs/1246/
# http://bugs.python.org/issue10254
@@ -37,7 +31,6 @@
# http://sourceforge.net/p/pywikipediabot/bugs/509/
# https://phabricator.wikimedia.org/T57329
# http://bugs.python.org/issue1528074
-# http://bugs.python.org/issue1678345
class PythonTestCase(TestCase):
@@ -46,11 +39,9 @@
net = False
- @expected_failure_if((2, 7, 0) <= PYTHON_VERSION < (2, 7, 2) or
- PYTHON_VERSION == (2, 6, 6))
def test_issue_10254(self):
"""Test Python issue #10254."""
- # Python 2.6.6, 2.7.0 and 2.7.1 have a bug in this routine.
+ # Python 2.7.0 and 2.7.1 have a bug in this routine.
# See T102461 and http://bugs.python.org/issue10254
text = 'Li̍t-sṳ́'
self.assertEqual(text, unicodedata.normalize('NFC', text))
diff --git a/tests/script_tests.py b/tests/script_tests.py
index 647d31e..d542f92 100644
--- a/tests/script_tests.py
+++ b/tests/script_tests.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Test that each script can be compiled and executed."""
#
-# (C) Pywikibot team, 2014-2017
+# (C) Pywikibot team, 2014-2018
#
# Distributed under the terms of the MIT license.
#
@@ -12,7 +12,6 @@
from pywikibot.tools import (
PY2,
- PYTHON_VERSION,
StringTypes,
)
@@ -39,10 +38,6 @@
'states_redirect': ['pycountry'],
'patrol': ['mwparserfromhell'],
}
-
-if PYTHON_VERSION < (2, 7):
- script_deps['replicate_wiki'] = ['argparse']
- script_deps['editarticle'] = ['argparse']
if PY2:
script_deps['data_ingestion'] = ['unicodecsv']
diff --git a/tests/textlib_tests.py b/tests/textlib_tests.py
index ca49ada..49855fd 100644
--- a/tests/textlib_tests.py
+++ b/tests/textlib_tests.py
@@ -8,6 +8,7 @@
from __future__ import absolute_import, unicode_literals
import codecs
+from collections import OrderedDict
import functools
import os
import re
@@ -18,7 +19,7 @@
from pywikibot import config, UnknownSite
from pywikibot.site import _IWEntry
-from pywikibot.tools import OrderedDict, suppress_warnings
+from pywikibot.tools import suppress_warnings
from tests.aspects import (
unittest, require_modules, TestCase, DefaultDrySiteTestCase,
diff --git a/tests/tools_tests.py b/tests/tools_tests.py
index 16d8430..0e1aa04 100644
--- a/tests/tools_tests.py
+++ b/tests/tools_tests.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""Test tools package alone which don't fit into other tests."""
#
-# (C) Pywikibot team, 2016-2017
+# (C) Pywikibot team, 2016-2018
#
# Distributed under the terms of the MIT license.
from __future__ import absolute_import, unicode_literals
@@ -452,7 +452,7 @@
self.assertEqual(next(deduper), 3)
if key in (hash, passthrough):
- if isinstance(deduped, tools.OrderedDict):
+ if isinstance(deduped, collections.OrderedDict):
self.assertEqual(list(deduped.keys()), [1, 3])
elif isinstance(deduped, collections.Mapping):
self.assertCountEqual(list(deduped.keys()), [1, 3])
@@ -463,7 +463,7 @@
self.assertEqual(next(deduper), 4)
if key in (hash, passthrough):
- if isinstance(deduped, tools.OrderedDict):
+ if isinstance(deduped, collections.OrderedDict):
self.assertEqual(list(deduped.keys()), [1, 3, 2, 4])
elif isinstance(deduped, collections.Mapping):
self.assertCountEqual(list(deduped.keys()), [1, 2, 3, 4])
@@ -513,7 +513,7 @@
def test_OrderedDict(self):
"""Test filter_unique with a OrderedDict."""
- deduped = tools.OrderedDict()
+ deduped = collections.OrderedDict()
deduper = tools.filter_unique(self.ints, container=deduped)
self._test_dedup_int(deduped, deduper)
diff --git a/tests/utils.py b/tests/utils.py
index 43d883e..4fe6414 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -45,9 +45,6 @@
OSWIN32 = (sys.platform == 'win32')
-PYTHON_26_CRYPTO_WARN = ('Python 2.6 is no longer supported by the Python core '
- 'team, please upgrade your Python.')
-
class DrySiteNote(RuntimeWarning):
@@ -638,27 +635,12 @@
"""
Execute a command and capture outputs.
- On Python 2.6 it adds an option to ignore the deprecation warning from
- the cryptography package after the first entry of the command parameter.
-
@param command: executable to run and arguments to use
@type command: list of unicode
"""
- if PYTHON_VERSION < (2, 7):
- command.insert(
- 1, '-W ignore:{0}:DeprecationWarning'.format(PYTHON_26_CRYPTO_WARN))
- if PYTHON_VERSION[:2] == (2, 6):
- command.insert(1, '-W ignore:{0}:DeprecationWarning'.format(
- 'Pywikibot will soon drop support for Python 2.6'))
# Any environment variables added on Windows must be of type
# str() on Python 2.
env = os.environ.copy()
-
- # Python issue 6906
- if PYTHON_VERSION < (2, 6, 6):
- for var in ('TK_LIBRARY', 'TCL_LIBRARY', 'TIX_LIBRARY'):
- if var in env:
- env[var] = env[var].encode('mbcs')
# Prevent output by test package; e.g. 'max_retries reduced from x to y'
env[str('PYWIKIBOT_TEST_QUIET')] = str('1')
diff --git a/tox.ini b/tox.ini
index c42d245..c53553a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -3,12 +3,11 @@
minversion = 1.7.2
skipsdist = True
skip_missing_interpreters = True
-envlist = diff-checker,commit-message,flake8,pyflakes-{py26,py3,pypy},doctest-{py27,py34},py26,py27,py34
+envlist = diff-checker,commit-message,flake8,pyflakes-{py27,py3,pypy},doctest-{py27,py34},py27,py34
[tox:jenkins]
# Override default for WM Jenkins
# Others are run in their own individual jobs on WM Jenkins
-# Wikimedia Jenkins does not have Python 2.6
envlist = diff-checker,commit-message,flake8,pyflakes-{py3,pypy}
[params]
@@ -29,12 +28,9 @@
deps = commit-message-validator
commands = commit-message-validator
-[testenv:py26]
-deps = unittest2
-
-[testenv:pyflakes-py26]
+[testenv:pyflakes-py27]
commands = findx . -name '*.py' -a '!' -path '*/.*' -a '!' -name 'user-config.py' : pyflakes
-basepython = python2.6
+basepython = python2.7
deps =
pyflakes
findx >= 0.9.9
@@ -170,7 +166,7 @@
ignore = C401,C402,C405,E402,D105,D211,FI10,FI12,FI13,FI15,FI16,FI17,FI5,H101,H236,H301,H404,H405,H903,I100,I101,I202,N802,N803,N806,D401,D413,D103,D412,W503
exclude = .tox,.git,./*.egg,ez_setup.py,build,externals,user-config.py,./scripts/i18n/*,scripts/userscripts/*
-min-version = 2.6
+min-version = 2.7
max_line_length = 100
accept-encodings = utf-8
require-code = true
--
To view, visit https://gerrit.wikimedia.org/r/263372
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Ied97711c81adebe9c260c8e7c2647b6cc71846fa
Gerrit-Change-Number: 263372
Gerrit-PatchSet: 26
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: Framawiki <framawiki(a)tools.wmflabs.org>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Magul <tomasz.magulski(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Multichill <maarten(a)mdammers.nl>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/423255 )
Change subject: [tests] skip ns() and pageid() tests when 'title' key is missing
......................................................................
[tests] skip ns() and pageid() tests when 'title' key is missing
We can assume that 'ns' and 'pageid' key is missing
when the 'title' is hidden
Bug: T191145
Change-Id: Ib9bd2e7f99c614b278c6a8b0cc6367127a73edcf
---
M tests/logentry_tests.py
1 file changed, 2 insertions(+), 2 deletions(-)
Approvals:
Dalba: Looks good to me, approved
jenkins-bot: Verified
diff --git a/tests/logentry_tests.py b/tests/logentry_tests.py
index 50f900a..51d6cc3 100644
--- a/tests/logentry_tests.py
+++ b/tests/logentry_tests.py
@@ -80,10 +80,10 @@
except KeyError as e:
self.assertRegex(str(e), "Log entry ([^)]+) has no 'comment' key")
self.assertIsInstance(logentry.logid(), int)
- self.assertIsInstance(logentry.ns(), int)
- self.assertIsInstance(logentry.pageid(), int)
self.assertIsInstance(logentry.timestamp(), pywikibot.Timestamp)
if 'title' in logentry.data: # title may be missing
+ self.assertIsInstance(logentry.ns(), int)
+ self.assertIsInstance(logentry.pageid(), int)
if logtype == 'block' and logentry.isAutoblockRemoval:
self.assertIsInstance(logentry.page(), int)
elif isinstance(logentry, UserTargetLogEntry):
--
To view, visit https://gerrit.wikimedia.org/r/423255
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib9bd2e7f99c614b278c6a8b0cc6367127a73edcf
Gerrit-Change-Number: 423255
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/403140 )
Change subject: Drop support for Python 3.3
......................................................................
Drop support for Python 3.3
Bug: T184508
Change-Id: I61c94c4324b717e6b6b9ed95278714752e4d6888
---
M .appveyor.yml
M .travis.yml
M HISTORY.rst
M dev-requirements.txt
M docs/index.rst
M pwb.py
M pywikibot/README.rst
M pywikibot/__init__.py
M pywikibot/tools/__init__.py
M requests-requirements.txt
M requirements.txt
M setup.py
M tests/utils.py
13 files changed, 20 insertions(+), 59 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/.appveyor.yml b/.appveyor.yml
index 2224a15..87a3ef6 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -30,20 +30,12 @@
PYTHON_VERSION: "2.7.2"
PYTHON_ARCH: "32"
- - PYTHON: "C:\\Python330"
- PYTHON_VERSION: "3.3.0"
- PYTHON_ARCH: "32"
-
- PYTHON: "C:\\Python340"
PYTHON_VERSION: "3.4.0"
PYTHON_ARCH: "32"
- PYTHON: "C:\\Python272-x64"
PYTHON_VERSION: "2.7.2"
- PYTHON_ARCH: "64"
-
- - PYTHON: "C:\\Python330-x64"
- PYTHON_VERSION: "3.3.0"
PYTHON_ARCH: "64"
- PYTHON: "C:\\Python340-x64"
@@ -54,10 +46,6 @@
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x"
- PYTHON_ARCH: "32"
-
- - PYTHON: "C:\\Python33"
- PYTHON_VERSION: "3.3.x"
PYTHON_ARCH: "32"
- PYTHON: "C:\\Python34"
@@ -74,10 +62,6 @@
- PYTHON: "C:\\Python27-x64"
PYTHON_VERSION: "2.7.x"
- PYTHON_ARCH: "64"
-
- - PYTHON: "C:\\Python33-x64"
- PYTHON_VERSION: "3.3.x"
PYTHON_ARCH: "64"
- PYTHON: "C:\\Python34-x64"
diff --git a/.travis.yml b/.travis.yml
index 89d281a..044670e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,7 +7,6 @@
python:
- '2.6'
- '2.7'
- - '3.3'
- '3.4'
- '3.5'
- '3.6'
@@ -146,13 +145,13 @@
# Disabled due to T173498
#- python: '2.7'
# env: LANGUAGE=en FAMILY=wpbeta SITE_ONLY=1 OAUTH_DOMAIN="en.wikipedia.beta.wmflabs.org"
- #- python: '3.3'
+ #- python: '3.6'
# env: LANGUAGE=zh FAMILY=wpbeta SITE_ONLY=1 OAUTH_DOMAIN="zh.wikipedia.beta.wmflabs.org"
- python: '3.4'
env: LANGUAGE=en FAMILY=wsbeta SITE_ONLY=1
- python: '2.7'
env: LANGUAGE=wikia FAMILY=wikia PYWIKIBOT2_TEST_NO_RC=1
- - python: '3.3'
+ - python: '3.5'
env: LANGUAGE=en FAMILY=musicbrainz SITE_ONLY=1
# Disabled due to T173498
#- python: '3.4'
diff --git a/HISTORY.rst b/HISTORY.rst
index d03abac..d989c25 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -4,6 +4,7 @@
Current release
---------------
+* Dropped support for Python 3.3 (T184508)
* Bugfixes and improvements
* Localisation updates
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 7bc6482..5084cdf 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -4,8 +4,7 @@
pytest>=2.8.0
pytest-timeout
-pytest-runner<=3.0 ; python_version == '3.3'
-pytest-runner ; python_version != '3.3'
+pytest-runner
pytest-cov
pytest-attrib
pytest-httpbin
diff --git a/docs/index.rst b/docs/index.rst
index 4e60261..91c773c 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -13,7 +13,7 @@
Pywikibot is a Python library and collection of scripts that automate work on `MediaWiki <https://mediawiki.org>`_ sites.
-Pywikibot supports Python 2.6.5+, 2.7.2+ and 3.3+.
+Pywikibot supports Python 2.6.5+, 2.7.2+ and 3.4+.
Pywikibot and this documentation are licensed under the :ref:`MIT license <licenses-MIT>`;
manual pages on mediawiki.org are licensed under the `CC-BY-SA 3.0`_ license.
diff --git a/pwb.py b/pwb.py
index 082e353..aed8514 100755
--- a/pwb.py
+++ b/pwb.py
@@ -36,14 +36,14 @@
Pywikibot is not available on:
{version}
-This version of Pywikibot only supports Python 2.6.5+, 2.7.2+ or 3.3+.
+This version of Pywikibot only supports Python 2.6.5+, 2.7.2+ or 3.4+.
"""
def python_is_supported():
"""Check that Python is supported."""
# Any change to this must be copied to setup.py
- return (PYTHON_VERSION >= (3, 3, 0) or
+ return (PYTHON_VERSION >= (3, 4, 0) or
(PY2 and PYTHON_VERSION >= (2, 7, 2)) or
(PY26 and PYTHON_VERSION >= (2, 6, 5)))
diff --git a/pywikibot/README.rst b/pywikibot/README.rst
index 225eca8..a9dd281 100644
--- a/pywikibot/README.rst
+++ b/pywikibot/README.rst
@@ -32,7 +32,7 @@
You need to have at least python version `2.6.5 <http://www.python.org/download/>`_
or newer installed on your computer to be able to run any of the code in this
-package, but not 3.0-3.2. It works fine with 3.3-3.4 versions of python installed.
+package, but not 3.0-3.3. It works fine with 3.4+ versions of python installed.
Support for older versions of python is not planned. Some scripts could run with
older python releases. Please refer the manual at mediawiki for further details
and restrictions.
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 938cf59..1264b64 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -135,9 +135,9 @@
deprecate_arg = redirect_func(_deprecate_arg)
-if sys.version_info[:2] in ((2, 6), (3, 3)):
+if sys.version_info[:2] == (2, 6):
warn(
- 'Pywikibot will soon drop support for Python 2.6 and 3.3',
+ 'Pywikibot will soon drop support for Python 2.6',
DeprecationWarning,
)
diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py
index ba0d3c7..611a957 100644
--- a/pywikibot/tools/__init__.py
+++ b/pywikibot/tools/__init__.py
@@ -108,7 +108,7 @@
except ImportError:
warn("""
pywikibot support of Python 2.6 relies on package future for many features.
-Please upgrade to Python 2.7+ or Python 3.3+, or run:
+Please upgrade to Python 2.7+ or Python 3.4+, or run:
"pip install future>=0.15.0"
""", RuntimeWarning)
try:
@@ -1221,8 +1221,6 @@
Safely return function Signature object (PEP 362).
inspect.signature was introduced in 3.3, however backports are available.
- In Python 3.3, it does not support all types of callables, and should
- not be relied upon. Python 3.4 works correctly.
Any exception calling inspect.signature is ignored and None is returned.
diff --git a/requests-requirements.txt b/requests-requirements.txt
index 6b4eed5..651eabf 100644
--- a/requests-requirements.txt
+++ b/requests-requirements.txt
@@ -3,11 +3,10 @@
# requests security extra
# Bug T105767 on Python 2.7 release 9+
cryptography>=1.3.4 ; python_version != '2.6' and (python_full_version < '2.7.9' or python_version > '3.3')
-cryptography>=1.3.4,<2.0 ; python_version == '3.3'
cryptography>=1.3.4,<=2.0.3 ; python_version == '2.6' and platform_system == 'Windows'
cryptography>=1.3.4,<2.2 ; python_version == '2.6' and platform_system != 'Windows'
pyOpenSSL>=0.14,!=17.2.0 ; python_full_version < '2.7.9' and python_version != '2.6'
-PyOpenSSL<17.5.0 ; python_version == '3.3' or python_version == '2.6'
+PyOpenSSL<17.5.0 ; python_version == '2.6'
idna>=2.0.0 ; python_full_version < '2.7.9' or python_version >= '3'
# https://github.com/eliben/pycparser/issues/147
pycparser != 2.14
diff --git a/requirements.txt b/requirements.txt
index 11bac63..f3c051f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -23,11 +23,10 @@
# requests security extra
cryptography>=1.3.4 ; python_version != '2.6' and python_full_version < '2.7.9'
-cryptography>=1.3.4,<2.0 ; python_version == '3.3'
cryptography>=1.3.4,<=2.0.3 ; python_version == '2.6' and platform_system == 'Windows'
cryptography>=1.3.4,<2.2 ; python_version == '2.6' and platform_system != 'Windows'
pyOpenSSL>=0.14,!=17.2.0 ; python_full_version < '2.7.9' and python_version != '2.6'
-PyOpenSSL<17.5.0 ; python_version == '3.3' or python_version == '2.6'
+PyOpenSSL<17.5.0 ; python_version == '2.6'
idna>=2.0.0 ; python_full_version < '2.7.9'
# https://github.com/eliben/pycparser/issues/147
pycparser != 2.14
@@ -55,7 +54,6 @@
# GUI
Pillow<4.0.0 ; python_version == '2.6'
-Pillow>=2.0.0,<5.0.0 ; python_version == '3.3'
Pillow ; python_version == '2.7' or python_version >= '3.4'
# core pagegenerators
@@ -76,8 +74,7 @@
# If you see that on Python 2, change this to flickrapi==1.4.5
# On Python 3, force pip to install requests 2.2.1, or remove flickrapi below.
flickrapi>=1.4.5,<2 ; python_version < '2.7'
-flickrapi<2.3.1 ; python_version == '3.3'
-flickrapi ; python_version >= '2.7' and python_version != '3.3'
+flickrapi ; python_version >= '2.7'
# incomplete core component botirc
irc ; python_version > '2.6'
diff --git a/setup.py b/setup.py
index 25bb902..1b2ccce 100644
--- a/setup.py
+++ b/setup.py
@@ -29,14 +29,14 @@
Pywikibot is not available on:
{version}
-This version of Pywikibot only supports Python 2.6.5+, 2.7.2+ or 3.3+.
+This version of Pywikibot only supports Python 2.6.5+, 2.7.2+ or 3.4+.
"""
def python_is_supported():
"""Check that Python is supported."""
# Any change to this must be copied to pwb.py
- return (PYTHON_VERSION >= (3, 3, 0) or
+ return (PYTHON_VERSION >= (3, 4, 0) or
(PY2 and PYTHON_VERSION >= (2, 7, 2)) or
(PY26 and PYTHON_VERSION >= (2, 6, 5)))
@@ -55,8 +55,6 @@
# According to https://pillow.readthedocs.io/en/latest/installation.html#notes
if PY26:
pillow = 'Pillow<4.0.0'
-elif PYTHON_VERSION[:2] == (3, 3):
- pillow = 'Pillow>=2.0.0,<5.0.0'
else:
pillow = 'Pillow'
@@ -81,13 +79,6 @@
'MySQL': ['oursql'],
'unicode7': ['unicodedata2>=7.0.0-2'],
})
-elif PYTHON_VERSION[:2] == (3, 3):
- # requests[security] requires cryptography, but cryptography 2.0+ does not
- # support Python 3.3; T178241
- extra_deps['security'].append('cryptography<2.0')
- # PyOpenSSL is required by requests[security] but has dropped support for
- # Python 3.3 since version 17.5.0 (2017-11-30); T181912
- extra_deps['security'].append('PyOpenSSL<17.5.0')
script_deps = {
'flickrripper.py': [pillow],
@@ -103,12 +94,8 @@
# and will be first packaged for Fedora Core 21.
# flickrapi 1.4.x does not run on Python 3, and setuptools can only
# select flickrapi 2.x for Python 3 installs.
-# flickrapi 2.3.1 dropped support for Python 3.3.
-if PYTHON_VERSION[:2] == (3, 3):
- script_deps['flickrripper.py'].append('flickrapi<2.3.1')
-else:
- script_deps['flickrripper.py'].append(
- 'flickrapi>=1.4.5,<2' if PY26 else 'flickrapi')
+script_deps['flickrripper.py'].append(
+ 'flickrapi>=1.4.5,<2' if PY26 else 'flickrapi')
# lunatic-python is only available for Linux
if sys.platform.startswith('linux'):
@@ -181,8 +168,6 @@
# builds.
# Microsoft makes available a compiler for Python 2.7
# http://www.microsoft.com/en-au/download/details.aspx?id=44266
-# If you set up your own compiler for Python 3, on 3.3 two demo files
-# packaged with pywin32 may fail. Remove com/win32com/demos/ie*.py
if os.name == 'nt' and os.environ.get('PYSETUP_TEST_NO_UI', '0') != '1':
# FIXME: tests/ui_tests.py suggests pywinauto 0.4.2
# which isnt provided on pypi.
@@ -274,7 +259,6 @@
'Operating System :: OS Independent',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
diff --git a/tests/utils.py b/tests/utils.py
index 129f0eb..43d883e 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -647,9 +647,9 @@
if PYTHON_VERSION < (2, 7):
command.insert(
1, '-W ignore:{0}:DeprecationWarning'.format(PYTHON_26_CRYPTO_WARN))
- if PYTHON_VERSION[:2] in ((3, 3), (2, 6)):
+ if PYTHON_VERSION[:2] == (2, 6):
command.insert(1, '-W ignore:{0}:DeprecationWarning'.format(
- 'Pywikibot will soon drop support for Python 2.6 and 3.3'))
+ 'Pywikibot will soon drop support for Python 2.6'))
# Any environment variables added on Windows must be of type
# str() on Python 2.
env = os.environ.copy()
--
To view, visit https://gerrit.wikimedia.org/r/403140
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I61c94c4324b717e6b6b9ed95278714752e4d6888
Gerrit-Change-Number: 403140
Gerrit-PatchSet: 6
Gerrit-Owner: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot <>