From b4263141aa5edd2010da5ff19135dc69b034c1fa Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Thu, 6 May 2021 23:08:41 +0200 Subject: [PATCH 01/16] sopel: refactor imports to remove py2 imports --- sopel/config/__init__.py | 13 +++++-------- sopel/irc/__init__.py | 28 +++++----------------------- sopel/irc/backends.py | 14 +------------- sopel/modules/ip.py | 16 ++++------------ sopel/modules/lmgtfy.py | 7 ++----- sopel/modules/reddit.py | 17 ++++------------- sopel/modules/safety.py | 24 ++++++------------------ sopel/modules/tld.py | 9 +++------ sopel/modules/url.py | 6 +----- sopel/modules/wikipedia.py | 5 +---- sopel/plugins/rules.py | 16 ++-------------- sopel/tools/web.py | 14 ++++++-------- 12 files changed, 40 insertions(+), 129 deletions(-) diff --git a/sopel/config/__init__.py b/sopel/config/__init__.py index 8781008e41..561e1cccee 100644 --- a/sopel/config/__init__.py +++ b/sopel/config/__init__.py @@ -50,17 +50,14 @@ class SpamSection(config.types.StaticSection): from __future__ import absolute_import, division, print_function, unicode_literals +import configparser import os -import sys from sopel import tools from . import core_section, types -if sys.version_info.major < 3: - import ConfigParser -else: - basestring = str - import configparser as ConfigParser + +basestring = str __all__ = [ @@ -131,7 +128,7 @@ def __init__(self, filename, validate=True): The config's ``basename`` is useful as a component :ref:`of log file names `, for example. """ - self.parser = ConfigParser.RawConfigParser(allow_no_value=True) + self.parser = configparser.RawConfigParser(allow_no_value=True) """The configuration parser object that does the heavy lifting. .. seealso:: @@ -238,7 +235,7 @@ def add_section(self, name): """ try: return self.parser.add_section(name) - except ConfigParser.DuplicateSectionError: + except configparser.DuplicateSectionError: return False def define_section(self, name, cls_, validate=True): diff --git a/sopel/irc/__init__.py b/sopel/irc/__init__.py index 2e888baca9..ef2c79bb5f 100644 --- a/sopel/irc/__init__.py +++ b/sopel/irc/__init__.py @@ -32,19 +32,6 @@ import threading import time -try: - import ssl - if not hasattr(ssl, 'match_hostname'): - # Attempt to import ssl_match_hostname from python-backports - # TODO: Remove when dropping Python 2 support - import backports.ssl_match_hostname - ssl.match_hostname = backports.ssl_match_hostname.match_hostname - ssl.CertificateError = backports.ssl_match_hostname.CertificateError - has_ssl = True -except ImportError: - # no SSL support - has_ssl = False - from sopel import tools, trigger from .backends import AsynchatBackend, SSLAsynchatBackend from .isupport import ISupport @@ -150,16 +137,11 @@ def get_irc_backend(self): } if self.settings.core.use_ssl: - if has_ssl: - backend_class = SSLAsynchatBackend - backend_kwargs.update({ - 'verify_ssl': self.settings.core.verify_ssl, - 'ca_certs': self.settings.core.ca_certs, - }) - else: - LOGGER.warning( - 'SSL is not available on your system; ' - 'attempting connection without it') + backend_class = SSLAsynchatBackend + backend_kwargs.update({ + 'verify_ssl': self.settings.core.verify_ssl, + 'ca_certs': self.settings.core.ca_certs, + }) return backend_class(*backend_args, **backend_kwargs) diff --git a/sopel/irc/backends.py b/sopel/irc/backends.py index 12d0eb2b0a..59b723a71f 100644 --- a/sopel/irc/backends.py +++ b/sopel/irc/backends.py @@ -13,6 +13,7 @@ import logging import os import socket +import ssl import sys import threading @@ -21,19 +22,6 @@ from .abstract_backends import AbstractIRCBackend from .utils import get_cnames -try: - import ssl - if not hasattr(ssl, 'match_hostname'): - # Attempt to import ssl_match_hostname from python-backports - # TODO: Remove when dropping Python 2 support - import backports.ssl_match_hostname - ssl.match_hostname = backports.ssl_match_hostname.match_hostname - ssl.CertificateError = backports.ssl_match_hostname.CertificateError - has_ssl = True -except ImportError: - # no SSL support - has_ssl = False - if sys.version_info.major >= 3: unicode = str diff --git a/sopel/modules/ip.py b/sopel/modules/ip.py index e6606ac801..39be7a9eca 100644 --- a/sopel/modules/ip.py +++ b/sopel/modules/ip.py @@ -14,6 +14,10 @@ import os import socket import tarfile +# urlretrieve has been put under urllib.request in Python 3. +# It's also deprecated so this should probably be replaced with +# urllib2. +from urllib.request import urlretrieve import geoip2.database @@ -21,18 +25,6 @@ from sopel.config import types from sopel.tools import web -urlretrieve = None -try: - from urllib import urlretrieve -except ImportError: - try: - # urlretrieve has been put under urllib.request in Python 3. - # It's also deprecated so this should probably be replaced with - # urllib2. - from urllib.request import urlretrieve - except ImportError: - pass - LOGGER = logging.getLogger(__name__) diff --git a/sopel/modules/lmgtfy.py b/sopel/modules/lmgtfy.py index ee4cb943e9..f9fe61c1eb 100644 --- a/sopel/modules/lmgtfy.py +++ b/sopel/modules/lmgtfy.py @@ -8,12 +8,9 @@ """ from __future__ import absolute_import, division, print_function, unicode_literals -from sopel import plugin +from urllib.parse import urlencode -try: - from urllib.parse import urlencode -except ImportError: - from urllib import urlencode +from sopel import plugin @plugin.command('lmgtfy', 'lmgify', 'gify', 'gtfy') diff --git a/sopel/modules/reddit.py b/sopel/modules/reddit.py index 5f53908d43..f731ce1f7a 100644 --- a/sopel/modules/reddit.py +++ b/sopel/modules/reddit.py @@ -11,8 +11,8 @@ from __future__ import absolute_import, division, print_function, unicode_literals import datetime as dt +import html import re -import sys import praw import prawcore @@ -23,17 +23,8 @@ from sopel.tools import time from sopel.tools.web import USER_AGENT -# clean up all of this when dropping py2/old py3 versions -if sys.version_info.major >= 3: - unicode = str - if sys.version_info.minor >= 4: - from html import unescape - else: - from html.parser import HTMLParser - unescape = HTMLParser().unescape -else: - from HTMLParser import HTMLParser - unescape = HTMLParser().unescape + +unicode = str PLUGIN_OUTPUT_PREFIX = '[reddit] ' @@ -204,7 +195,7 @@ def say_post_info(bot, trigger, id_, show_link=True, show_comments_link=False): # the value assigned earlier will be used pass - title = unescape(s.title) + title = html.unescape(s.title) message = message.format( title=title, link=link, nsfw=nsfw, points=s.score, points_text=points_text, percent=percent, comments=s.num_comments, comments_text=comments_text, diff --git a/sopel/modules/safety.py b/sopel/modules/safety.py index f6974b79a1..88bd4fb119 100644 --- a/sopel/modules/safety.py +++ b/sopel/modules/safety.py @@ -8,34 +8,22 @@ """ from __future__ import absolute_import, division, print_function, unicode_literals +import json import logging import os.path import re -import sys import threading import time +from urllib.parse import urlparse +from urllib.request import urlretrieve + import requests from sopel import formatting, plugin, tools from sopel.config import types -try: - # This is done separately from the below version if/else because JSONDecodeError - # didn't appear until Python 3.5, but Sopel claims support for 3.3+ - # Redo this whole block of nonsense when dropping py2/old py3 support - from json import JSONDecodeError as InvalidJSONResponse -except ImportError: - InvalidJSONResponse = ValueError - -if sys.version_info.major > 2: - unicode = str - from urllib.request import urlretrieve - from urllib.parse import urlparse -else: - from urllib import urlretrieve - from urlparse import urlparse - +unicode = str LOGGER = logging.getLogger(__name__) PLUGIN_OUTPUT_PREFIX = '[safety] ' @@ -202,7 +190,7 @@ def url_handler(bot, trigger): except requests.exceptions.RequestException: # Ignoring exceptions with VT so domain list will always work LOGGER.debug('[VirusTotal] Error obtaining response.', exc_info=True) - except InvalidJSONResponse: + except json.JSONDecodeError: # Ignoring exceptions with VT so domain list will always work LOGGER.debug('[VirusTotal] Malformed response (invalid JSON).', exc_info=True) diff --git a/sopel/modules/tld.py b/sopel/modules/tld.py index 6ee33567fc..90cd93b09e 100644 --- a/sopel/modules/tld.py +++ b/sopel/modules/tld.py @@ -11,20 +11,17 @@ from datetime import datetime from encodings import idna +from html.parser import HTMLParser import logging import re -import sys import pytz import requests from sopel import formatting, plugin, tools -if sys.version_info.major >= 3: - unicode = str - from html.parser import HTMLParser -else: - from HTMLParser import HTMLParser + +unicode = str LOGGER = logging.getLogger(__name__) diff --git a/sopel/modules/url.py b/sopel/modules/url.py index 9524919b8a..442ff8fd33 100644 --- a/sopel/modules/url.py +++ b/sopel/modules/url.py @@ -14,6 +14,7 @@ import ipaddress import logging import re +from urllib.parse import urlparse import dns.resolver import requests @@ -23,11 +24,6 @@ from sopel.config import types from sopel.tools import web -# Python3 vs Python2 -try: - from urllib.parse import urlparse -except ImportError: - from urlparse import urlparse LOGGER = logging.getLogger(__name__) USER_AGENT = ( diff --git a/sopel/modules/wikipedia.py b/sopel/modules/wikipedia.py index 0f22db3b43..86e7f3b800 100644 --- a/sopel/modules/wikipedia.py +++ b/sopel/modules/wikipedia.py @@ -8,6 +8,7 @@ """ from __future__ import absolute_import, division, print_function, unicode_literals +from html.parser import HTMLParser import re from requests import get @@ -16,10 +17,6 @@ from sopel.config import types from sopel.tools.web import quote, unquote -try: # TODO: Remove fallback when dropping py2 - from html.parser import HTMLParser -except ImportError: - from HTMLParser import HTMLParser REDIRECT = re.compile(r'^REDIRECT (.*)') PLUGIN_OUTPUT_PREFIX = '[wikipedia] ' diff --git a/sopel/plugins/rules.py b/sopel/plugins/rules.py index 6abb1157b9..cc8b04a972 100644 --- a/sopel/plugins/rules.py +++ b/sopel/plugins/rules.py @@ -25,6 +25,7 @@ import logging import re import threading +from urllib.parse import urlparse from sopel import tools @@ -32,19 +33,6 @@ COMMAND_DEFAULT_HELP_PREFIX, COMMAND_DEFAULT_PREFIX, URL_DEFAULT_SCHEMES) -try: - from urllib.parse import urlparse -except ImportError: - # TODO: remove when dropping Python 2.7 - from urlparse import urlparse - -try: - from inspect import getfullargspec as inspect_getargspec -except ImportError: - # TODO: remove when dropping Python 2.7 - from inspect import getargspec as inspect_getargspec - - __all__ = [ 'Manager', 'Rule', @@ -1600,7 +1588,7 @@ def from_callable(cls, settings, handler): # account for the 'self' parameter when the handler is a method match_count = 4 - argspec = inspect_getargspec(handler) + argspec = inspect.getfullargspec(handler) if len(argspec.args) >= match_count: @functools.wraps(handler) diff --git a/sopel/tools/web.py b/sopel/tools/web.py index 70d7b63147..a34e8bb482 100644 --- a/sopel/tools/web.py +++ b/sopel/tools/web.py @@ -19,20 +19,18 @@ from __future__ import absolute_import, division, print_function, unicode_literals +from html.entities import name2codepoint import re import sys import urllib +from urllib.parse import urlparse, urlunparse from sopel import __version__ -if sys.version_info.major < 3: - from htmlentitydefs import name2codepoint - from urlparse import urlparse, urlunparse -else: - from html.entities import name2codepoint - from urllib.parse import urlparse, urlunparse - unichr = chr - unicode = str + +unichr = chr +unicode = str + __all__ = [ 'USER_AGENT', From 27d8c76cb294d3c97e5c9cb5d04d0897e5886915 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Thu, 6 May 2021 23:21:15 +0200 Subject: [PATCH 02/16] test: remove test config for py2.7 --- test/test_config.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/test/test_config.py b/test/test_config.py index a8651e4043..3b1bbdc7a6 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -2,7 +2,6 @@ from __future__ import absolute_import, division, print_function, unicode_literals import os -import sys import pytest @@ -50,23 +49,6 @@ '""ed"', # quoted, but no #: quotes kept ] -if sys.version_info.major < 3: - # Python 2.7's ConfigParser interprets as comment - # a line that starts with # or ;. - # Python 3, on the other hand, allows comments to be indented. - # As a result, the same config file will result in a different - # config object depending on the Python version used. - # TODO: Deprecated with Python 2.7. - TEST_CHANNELS = [ - '#sopel', - '&peculiar', - '# python 3 only comment', # indented lines cannot be comments in Py2 - '#private', - '"#startquote', - '&endquote"', - '""ed"', - ] - class FakeConfigSection(types.StaticSection): valattr = types.ValidatedAttribute('valattr') From f3ec43901a987ff53fad82aa81bb25fd87fecea1 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Fri, 7 May 2021 00:03:59 +0200 Subject: [PATCH 03/16] sopel: remove obsolete 'unicode = str' shim --- sopel/bot.py | 13 ++------- sopel/config/types.py | 11 ++------ sopel/coretasks.py | 12 +++----- sopel/db.py | 7 +---- sopel/formatting.py | 6 +--- sopel/irc/__init__.py | 5 +--- sopel/irc/backends.py | 10 ++----- sopel/irc/utils.py | 12 ++------ sopel/modules/choose.py | 6 ---- sopel/modules/reddit.py | 2 -- sopel/modules/safety.py | 7 ++--- sopel/modules/tld.py | 3 -- sopel/modules/translate.py | 4 +-- sopel/modules/unicode_info.py | 15 ++-------- sopel/tools/__init__.py | 53 +++++++++++++++-------------------- sopel/tools/web.py | 20 ++++--------- sopel/trigger.py | 9 ++---- 17 files changed, 52 insertions(+), 143 deletions(-) diff --git a/sopel/bot.py b/sopel/bot.py index f5d4ebfc9f..398c0aac11 100644 --- a/sopel/bot.py +++ b/sopel/bot.py @@ -14,7 +14,6 @@ import logging import re import signal -import sys import threading import time @@ -44,14 +43,6 @@ SIGNALS = QUIT_SIGNALS + RESTART_SIGNALS -if sys.version_info.major >= 3: - unicode = str - basestring = str - py3 = True -else: - py3 = False - - class Sopel(irc.AbstractBot): def __init__(self, config, daemon=False): super(Sopel, self).__init__(config) @@ -1129,7 +1120,7 @@ def register_url_callback(self, pattern, callback): if 'url_callbacks' not in self.memory: self.memory['url_callbacks'] = tools.SopelMemory() - if isinstance(pattern, basestring): + if isinstance(pattern, str): pattern = re.compile(pattern) # Mark the callback as checked: using this method is safe. @@ -1180,7 +1171,7 @@ def unregister_url_callback(self, pattern, callback): # nothing to unregister return - if isinstance(pattern, basestring): + if isinstance(pattern, str): pattern = re.compile(pattern) try: diff --git a/sopel/config/types.py b/sopel/config/types.py index a7701f2d60..160d76a4d0 100644 --- a/sopel/config/types.py +++ b/sopel/config/types.py @@ -29,14 +29,9 @@ import getpass import os.path import re -import sys from sopel.tools import deprecated, get_input -if sys.version_info.major >= 3: - unicode = str - basestring = (str, bytes) - class NO_DEFAULT(object): """A special value to indicate that there should be no default.""" @@ -267,7 +262,7 @@ def __delete__(self, instance): def _parse_boolean(value): if value is True or value == 1: return value - if isinstance(value, basestring): + if isinstance(value, str): return value.lower() in ['1', 'yes', 'y', 'true', 'on'] return bool(value) @@ -325,7 +320,7 @@ def serialize(self, value): :param value: the option value :rtype: str """ - return unicode(value) + return str(value) def parse(self, value): """No-op: simply returns the given ``value``, unchanged. @@ -392,7 +387,7 @@ def parse(self, value): """ if value is True or value == 1: return True - if isinstance(value, basestring): + if isinstance(value, str): return value.lower() in [ '1', 'enable', diff --git a/sopel/coretasks.py b/sopel/coretasks.py index 979d42c8a0..10df1efdc4 100644 --- a/sopel/coretasks.py +++ b/sopel/coretasks.py @@ -29,7 +29,6 @@ import functools import logging import re -import sys import time from sopel import loader, module, plugin @@ -39,9 +38,6 @@ from sopel.tools import events, Identifier, iteritems, SopelMemory, target, web -if sys.version_info.major >= 3: - unicode = str - LOGGER = logging.getLogger(__name__) CORE_QUERYTYPE = '999' @@ -1187,13 +1183,13 @@ def blocks(bot, trigger): if len(text) == 3 and text[1] == "list": if text[2] == "hostmask": if len(masks) > 0: - blocked = ', '.join(unicode(mask) for mask in masks) + blocked = ', '.join(str(mask) for mask in masks) bot.say("Blocked hostmasks: {}".format(blocked)) else: bot.reply(STRINGS['nonelisted'] % ('hostmasks')) elif text[2] == "nick": if len(nicks) > 0: - blocked = ', '.join(unicode(nick) for nick in nicks) + blocked = ', '.join(str(nick) for nick in nicks) bot.say("Blocked nicks: {}".format(blocked)) else: bot.reply(STRINGS['nonelisted'] % ('nicks')) @@ -1220,7 +1216,7 @@ def blocks(bot, trigger): bot.reply(STRINGS['no_nick'] % (text[3])) return nicks.remove(Identifier(text[3])) - bot.config.core.nick_blocks = [unicode(n) for n in nicks] + bot.config.core.nick_blocks = [str(n) for n in nicks] bot.config.save() bot.reply(STRINGS['success_del'] % (text[3])) elif text[2] == "hostmask": @@ -1229,7 +1225,7 @@ def blocks(bot, trigger): bot.reply(STRINGS['no_host'] % (text[3])) return masks.remove(mask) - bot.config.core.host_blocks = [unicode(m) for m in masks] + bot.config.core.host_blocks = [str(m) for m in masks] bot.config.save() bot.reply(STRINGS['success_del'] % (text[3])) else: diff --git a/sopel/db.py b/sopel/db.py index c29b519565..633711eafe 100644 --- a/sopel/db.py +++ b/sopel/db.py @@ -5,7 +5,6 @@ import json import logging import os.path -import sys import traceback from sqlalchemy import Column, create_engine, ForeignKey, Integer, String @@ -16,10 +15,6 @@ from sopel.tools import Identifier -if sys.version_info.major >= 3: - unicode = str - basestring = str - LOGGER = logging.getLogger(__name__) @@ -29,7 +24,7 @@ def _deserialize(value): return None # sqlite likes to return ints for strings that look like ints, even though # the column type is string. That's how you do dynamic typing wrong. - value = unicode(value) + value = str(value) # Just in case someone's mucking with the DB in a way we can't account for, # ignore json parsing errors try: diff --git a/sopel/formatting.py b/sopel/formatting.py index 4272a060b5..097e24e43e 100644 --- a/sopel/formatting.py +++ b/sopel/formatting.py @@ -10,7 +10,6 @@ import re import string -import sys __all__ = [ @@ -38,9 +37,6 @@ 'colors', ] -if sys.version_info.major >= 3: - unicode = str - # Color names are as specified at http://www.mirc.com/colors.html CONTROL_NORMAL = '\x0f' @@ -173,7 +169,7 @@ def _get_color(color): if isinstance(color, int): if color > 99: raise ValueError('Can not specify a color above 99.') - return unicode(color).rjust(2, '0') + return str(color).rjust(2, '0') # You can also pass the name of the color color_name = color.upper() diff --git a/sopel/irc/__init__.py b/sopel/irc/__init__.py index ef2c79bb5f..7dbce86242 100644 --- a/sopel/irc/__init__.py +++ b/sopel/irc/__init__.py @@ -28,7 +28,6 @@ from datetime import datetime import logging import os -import sys import threading import time @@ -37,8 +36,6 @@ from .isupport import ISupport from .utils import CapReq, safe -if sys.version_info.major >= 3: - unicode = str __all__ = ['abstract_backends', 'backends', 'utils'] @@ -584,7 +581,7 @@ def say(self, text, recipient, max_messages=1, truncation='', trailing=''): """ excess = '' - if not isinstance(text, unicode): + if not isinstance(text, str): # Make sure we are dealing with a Unicode string text = text.decode('utf-8') diff --git a/sopel/irc/backends.py b/sopel/irc/backends.py index 59b723a71f..052255b074 100644 --- a/sopel/irc/backends.py +++ b/sopel/irc/backends.py @@ -14,7 +14,6 @@ import os import socket import ssl -import sys import threading from sopel import loader, plugin @@ -22,9 +21,6 @@ from .abstract_backends import AbstractIRCBackend from .utils import get_cnames -if sys.version_info.major >= 3: - unicode = str - LOGGER = logging.getLogger(__name__) @@ -203,15 +199,15 @@ def collect_incoming_data(self, data): """ # We can't trust clients to pass valid Unicode. try: - data = unicode(data, encoding='utf-8') + data = str(data, encoding='utf-8') except UnicodeDecodeError: # not Unicode; let's try CP-1252 try: - data = unicode(data, encoding='cp1252') + data = str(data, encoding='cp1252') except UnicodeDecodeError: # Okay, let's try ISO 8859-1 try: - data = unicode(data, encoding='iso8859-1') + data = str(data, encoding='iso8859-1') except UnicodeDecodeError: # Discard line if encoding is unknown return diff --git a/sopel/irc/utils.py b/sopel/irc/utils.py index 6a65342754..c1fa6c653b 100644 --- a/sopel/irc/utils.py +++ b/sopel/irc/utils.py @@ -5,15 +5,11 @@ from __future__ import absolute_import, division, print_function, unicode_literals import collections -import sys from dns import rdtypes, resolver from sopel.tools import deprecated -if sys.version_info.major >= 3: - unicode = str - MYINFO_ARGS = ['client', 'servername', 'version'] @@ -45,8 +41,7 @@ def safe(string): :raises TypeError: when ``string`` is ``None`` This function removes newlines from a string and always returns a unicode - string (as in ``str`` on Python 3 and ``unicode`` on Python 2), but doesn't - strip or alter it in any other way:: + string (``str``), but doesn't strip or alter it in any other way:: >>> safe('some text\\r\\n') 'some text' @@ -61,11 +56,8 @@ def safe(string): """ if string is None: raise TypeError('safe function requires a string, not NoneType') - if sys.version_info.major >= 3 and isinstance(string, bytes): + if isinstance(string, bytes): string = string.decode("utf8") - elif sys.version_info.major < 3: - if not isinstance(string, unicode): - string = unicode(string, encoding='utf8') string = string.replace('\n', '') string = string.replace('\r', '') return string diff --git a/sopel/modules/choose.py b/sopel/modules/choose.py index 69ecc17119..7095fd520f 100644 --- a/sopel/modules/choose.py +++ b/sopel/modules/choose.py @@ -16,12 +16,6 @@ from sopel import formatting, plugin -# Remove when dropping py2 support -try: - str = unicode -except NameError: - pass - def _format_safe(text): """Remove excess whitespace and terminate IRC formatting. diff --git a/sopel/modules/reddit.py b/sopel/modules/reddit.py index f731ce1f7a..6f4b315e79 100644 --- a/sopel/modules/reddit.py +++ b/sopel/modules/reddit.py @@ -24,8 +24,6 @@ from sopel.tools.web import USER_AGENT -unicode = str - PLUGIN_OUTPUT_PREFIX = '[reddit] ' domain = r'https?://(?:www\.|old\.|pay\.|ssl\.|[a-z]{2}\.)?reddit\.com' diff --git a/sopel/modules/safety.py b/sopel/modules/safety.py index 88bd4fb119..d32af63ea5 100644 --- a/sopel/modules/safety.py +++ b/sopel/modules/safety.py @@ -23,7 +23,6 @@ from sopel import formatting, plugin, tools from sopel.config import types -unicode = str LOGGER = logging.getLogger(__name__) PLUGIN_OUTPUT_PREFIX = '[safety] ' @@ -96,7 +95,7 @@ def setup(bot): _download_domain_list(loc) with open(loc, 'r') as f: for line in f: - clean_line = unicode(line).strip().lower() + clean_line = str(line).strip().lower() if not clean_line or clean_line[0] == '#': # blank line or comment continue @@ -164,7 +163,7 @@ def url_handler(bot, trigger): apikey = bot.config.safety.vt_api_key try: if apikey is not None and use_vt: - payload = {'resource': unicode(trigger), + payload = {'resource': str(trigger), 'apikey': apikey, 'scan': '1'} @@ -194,7 +193,7 @@ def url_handler(bot, trigger): # Ignoring exceptions with VT so domain list will always work LOGGER.debug('[VirusTotal] Malformed response (invalid JSON).', exc_info=True) - if unicode(netloc).lower() in malware_domains: + if str(netloc).lower() in malware_domains: positives += 1 total += 1 diff --git a/sopel/modules/tld.py b/sopel/modules/tld.py index 90cd93b09e..c1854bc293 100644 --- a/sopel/modules/tld.py +++ b/sopel/modules/tld.py @@ -21,9 +21,6 @@ from sopel import formatting, plugin, tools -unicode = str - - LOGGER = logging.getLogger(__name__) diff --git a/sopel/modules/translate.py b/sopel/modules/translate.py index ebd4ef11b7..0a49290f6a 100644 --- a/sopel/modules/translate.py +++ b/sopel/modules/translate.py @@ -18,8 +18,6 @@ from sopel import plugin, tools from sopel.tools import web -if sys.version_info.major >= 3: - unicode = str PLUGIN_OUTPUT_PREFIX = '[translate] ' @@ -38,7 +36,7 @@ def shutdown(bot): def translate(text, in_lang='auto', out_lang='en'): raw = False - if unicode(out_lang).endswith('-raw'): + if str(out_lang).endswith('-raw'): out_lang = out_lang[:-4] raw = True diff --git a/sopel/modules/unicode_info.py b/sopel/modules/unicode_info.py index 735b2ba4f2..ba300ae070 100644 --- a/sopel/modules/unicode_info.py +++ b/sopel/modules/unicode_info.py @@ -9,26 +9,15 @@ """ from __future__ import absolute_import, division, print_function, unicode_literals -import sys import unicodedata from sopel import plugin -if sys.version_info.major >= 3: - # Note on unicode and str (required for py2 compatibility) - # the `hex` function returns a `str`, both in py2 and py3 - # however, a `str` is a unicode string in py3, but a bytestring in py2 - # in order to prevent that, we encode the return from `hex` as `unicode` - # and since this class does not exist anymore on py3, we create an alias - # for `str` in py3 - unichr = chr - unicode = str - def get_codepoint_name(char): """Retrieve the code point (and name, if possible) for a given character""" # Get the hex value for the code point, and drop the 0x from the front - point = unicode(hex(ord(char)))[2:] + point = hex(ord(char))[2:] # Make the hex 4 characters long with preceding 0s, and all upper case point = point.rjust(4, '0').upper() @@ -60,7 +49,7 @@ def codepoint(bot, trigger): if arg.startswith('U+'): arg = arg[2:] try: - arg = unichr(int(arg, 16)) + arg = chr(int(arg, 16)) except (ValueError, TypeError): bot.reply("That's not a valid code point.") return plugin.NOLIMIT diff --git a/sopel/tools/__init__.py b/sopel/tools/__init__.py index 2b0f90b11a..9168ef18ae 100644 --- a/sopel/tools/__init__.py +++ b/sopel/tools/__init__.py @@ -32,16 +32,11 @@ from ._events import events # NOQA from . import time, web # NOQA -if sys.version_info.major >= 3: - raw_input = input - unicode = str - iteritems = dict.items - itervalues = dict.values - iterkeys = dict.keys -else: - iteritems = dict.iteritems - itervalues = dict.itervalues - iterkeys = dict.iterkeys + +raw_input = input +iteritems = dict.items +itervalues = dict.values +iterkeys = dict.keys _channel_prefixes = ('#', '&', '+', '!') @@ -317,7 +312,7 @@ def get_nickname_command_regexp(nick, command, alias_nicks): # Must defer import to avoid cyclic dependency from sopel.plugins.rules import NickCommand - if isinstance(alias_nicks, unicode): + if isinstance(alias_nicks, str): alias_nicks = [alias_nicks] elif not isinstance(alias_nicks, (list, tuple)): raise ValueError('A list or string is required.') @@ -443,26 +438,22 @@ def __getitem__(self, key): return dict.__getitem__(self, key) -class Identifier(unicode): - """A `unicode` subclass which acts appropriately for IRC identifiers. +class Identifier(str): + """A ``str`` subclass which acts appropriately for IRC identifiers. - When used as normal `unicode` objects, case will be preserved. + When used as normal ``str`` objects, case will be preserved. However, when comparing two Identifier objects, or comparing a Identifier - object with a `unicode` object, the comparison will be case insensitive. + object with a ``str`` object, the comparison will be case insensitive. This case insensitivity includes the case convention conventions regarding ``[]``, ``{}``, ``|``, ``\\``, ``^`` and ``~`` described in RFC 2812. """ - # May want to tweak this and update documentation accordingly when dropping - # Python 2 support, since in py3 plain str is Unicode and a "unicode" type - # no longer exists. Probably lots of code will need tweaking, tbh. - def __new__(cls, identifier): # According to RFC2812, identifiers have to be in the ASCII range. # However, I think it's best to let the IRCd determine that, and we'll # just assume unicode. It won't hurt anything, and is more internally # consistent. And who knows, maybe there's another use case for this # weird case convention. - s = unicode.__new__(cls, identifier) + s = str.__new__(cls, identifier) s._lowered = Identifier._lower(identifier) return s @@ -521,29 +512,29 @@ def __hash__(self): return self._lowered.__hash__() def __lt__(self, other): - if isinstance(other, unicode): + if isinstance(other, str): other = Identifier._lower(other) - return unicode.__lt__(self._lowered, other) + return str.__lt__(self._lowered, other) def __le__(self, other): - if isinstance(other, unicode): + if isinstance(other, str): other = Identifier._lower(other) - return unicode.__le__(self._lowered, other) + return str.__le__(self._lowered, other) def __gt__(self, other): - if isinstance(other, unicode): + if isinstance(other, str): other = Identifier._lower(other) - return unicode.__gt__(self._lowered, other) + return str.__gt__(self._lowered, other) def __ge__(self, other): - if isinstance(other, unicode): + if isinstance(other, str): other = Identifier._lower(other) - return unicode.__ge__(self._lowered, other) + return str.__ge__(self._lowered, other) def __eq__(self, other): - if isinstance(other, unicode): + if isinstance(other, str): other = Identifier._lower(other) - return unicode.__eq__(self._lowered, other) + return str.__eq__(self._lowered, other) def __ne__(self, other): return not (self == other) @@ -610,7 +601,7 @@ def write(self, string): logfile.write(string) except UnicodeDecodeError: # we got an invalid string, safely encode it to utf-8 - logfile.write(unicode(string, 'utf8', errors="replace")) + logfile.write(str(string, 'utf8', errors="replace")) def flush(self): """Flush the file writing buffer.""" diff --git a/sopel/tools/web.py b/sopel/tools/web.py index a34e8bb482..0e5815e8e4 100644 --- a/sopel/tools/web.py +++ b/sopel/tools/web.py @@ -28,10 +28,6 @@ from sopel import __version__ -unichr = chr -unicode = str - - __all__ = [ 'USER_AGENT', 'DEFAULT_HEADERS', @@ -105,11 +101,11 @@ def entity(match): """ value = match.group(1).lower() if value.startswith('#x'): - return unichr(int(value[2:], 16)) + return chr(int(value[2:], 16)) elif value.startswith('#'): - return unichr(int(value[1:])) + return chr(int(value[1:])) elif value in name2codepoint: - return unichr(name2codepoint[value]) + return chr(name2codepoint[value]) return '[' + value + ']' @@ -122,7 +118,6 @@ def decode(html): return r_entity.sub(entity, html) -# Identical to urllib2.quote def quote(string, safe='/'): """Safely encodes a string for use in a URL. @@ -135,13 +130,8 @@ def quote(string, safe='/'): This is a shim to make writing cross-compatible plugins for both Python 2 and Python 3 easier. """ - if sys.version_info.major < 3: - if isinstance(string, unicode): - string = string.encode('utf8') - string = urllib.quote(string, safe.encode('utf8')) - else: - string = urllib.parse.quote(str(string), safe) - return string + # TODO deprecated? + return urllib.parse.quote(str(string), safe) # six-like shim for Unicode safety diff --git a/sopel/trigger.py b/sopel/trigger.py index 3615349f31..49a5aa466f 100644 --- a/sopel/trigger.py +++ b/sopel/trigger.py @@ -4,7 +4,6 @@ import datetime import re -import sys from sopel import formatting, tools from sopel.tools import web @@ -15,10 +14,6 @@ 'Trigger', ] -if sys.version_info.major >= 3: - unicode = str - basestring = str - class PreTrigger(object): """A parsed raw message from the server. @@ -200,7 +195,7 @@ def __init__(self, own_nick, line, url_schemes=None): self.plain = formatting.plain(self.args[-1]) -class Trigger(unicode): +class Trigger(str): """A line from the server, which has matched a callable's rules. :param config: Sopel's current configuration settings object @@ -412,7 +407,7 @@ class Trigger(unicode): """ def __new__(cls, config, message, match, account=None): - self = unicode.__new__(cls, message.args[-1] if message.args else '') + self = str.__new__(cls, message.args[-1] if message.args else '') self._account = account self._pretrigger = message self._match = match From 3c64a7e86d492e43d84e4ab4bed546255cd83907 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Fri, 7 May 2021 14:30:38 +0200 Subject: [PATCH 04/16] quality: replace and enforce future import rules for Py3.6+ --- pytest_run.py | 2 +- setup.cfg | 10 +++------- setup.py | 2 +- sopel.py | 2 +- sopel/__init__.py | 2 +- sopel/bot.py | 2 +- sopel/cli/__init__.py | 2 +- sopel/cli/config.py | 2 +- sopel/cli/plugins.py | 2 +- sopel/cli/run.py | 2 +- sopel/cli/utils.py | 2 +- sopel/config/__init__.py | 2 +- sopel/config/core_section.py | 2 +- sopel/config/types.py | 2 +- sopel/coretasks.py | 2 +- sopel/db.py | 2 +- sopel/formatting.py | 2 +- sopel/irc/__init__.py | 2 +- sopel/irc/abstract_backends.py | 2 +- sopel/irc/backends.py | 2 +- sopel/irc/isupport.py | 2 +- sopel/irc/utils.py | 2 +- sopel/loader.py | 2 +- sopel/logger.py | 2 +- sopel/module.py | 2 +- sopel/modules/__init__.py | 2 +- sopel/modules/admin.py | 2 +- sopel/modules/adminchannel.py | 2 +- sopel/modules/announce.py | 2 +- sopel/modules/bugzilla.py | 2 +- sopel/modules/calc.py | 2 +- sopel/modules/choose.py | 2 +- sopel/modules/clock.py | 2 +- sopel/modules/countdown.py | 2 +- sopel/modules/currency.py | 2 +- sopel/modules/dice.py | 2 +- sopel/modules/emoticons.py | 2 +- sopel/modules/find.py | 2 +- sopel/modules/find_updates.py | 2 +- sopel/modules/help.py | 2 +- sopel/modules/invite.py | 2 +- sopel/modules/ip.py | 2 +- sopel/modules/isup.py | 2 +- sopel/modules/lmgtfy.py | 2 +- sopel/modules/meetbot.py | 2 +- sopel/modules/ping.py | 2 +- sopel/modules/pronouns.py | 2 +- sopel/modules/py.py | 2 +- sopel/modules/rand.py | 2 +- sopel/modules/reddit.py | 2 +- sopel/modules/reload.py | 2 +- sopel/modules/remind.py | 2 +- sopel/modules/safety.py | 2 +- sopel/modules/search.py | 2 +- sopel/modules/seen.py | 2 +- sopel/modules/tell.py | 2 +- sopel/modules/tld.py | 2 +- sopel/modules/translate.py | 2 +- sopel/modules/unicode_info.py | 2 +- sopel/modules/units.py | 2 +- sopel/modules/uptime.py | 2 +- sopel/modules/url.py | 2 +- sopel/modules/version.py | 2 +- sopel/modules/wikipedia.py | 2 +- sopel/modules/wiktionary.py | 2 +- sopel/modules/xkcd.py | 2 +- sopel/plugin.py | 2 +- sopel/plugins/__init__.py | 2 +- sopel/plugins/exceptions.py | 2 +- sopel/plugins/handlers.py | 2 +- sopel/plugins/jobs.py | 2 +- sopel/plugins/rules.py | 2 +- sopel/test_tools.py | 2 +- sopel/tests/__init__.py | 2 +- sopel/tests/factories.py | 2 +- sopel/tests/mocks.py | 2 +- sopel/tests/pytest_plugin.py | 2 +- sopel/tools/__init__.py | 2 +- sopel/tools/_events.py | 2 +- sopel/tools/calculation.py | 2 +- sopel/tools/jobs.py | 2 +- sopel/tools/target.py | 2 +- sopel/tools/time.py | 2 +- sopel/tools/web.py | 2 +- sopel/trigger.py | 2 +- sopel/web.py | 2 +- test/cli/test_cli_run.py | 2 +- test/cli/test_cli_utils.py | 2 +- test/config/test_config_types.py | 2 +- test/irc/test_irc_abstract_backends.py | 2 +- test/irc/test_irc_isupport.py | 2 +- test/irc/test_irc_utils.py | 2 +- test/modules/test_modules_choose.py | 2 +- test/modules/test_modules_find_updates.py | 2 +- test/modules/test_modules_isup.py | 2 +- test/modules/test_modules_remind.py | 2 +- test/modules/test_modules_tell.py | 2 +- test/modules/test_modules_url.py | 2 +- test/plugins/test_plugins_handlers.py | 2 +- test/plugins/test_plugins_rules.py | 2 +- test/test_bot.py | 2 +- test/test_config.py | 2 +- test/test_coretasks.py | 2 +- test/test_db.py | 2 +- test/test_formatting.py | 2 +- test/test_irc.py | 2 +- test/test_loader.py | 2 +- test/test_module.py | 2 +- test/test_plugin.py | 2 +- test/test_plugins.py | 2 +- test/test_regression.py | 2 +- test/test_tools.py | 2 +- test/test_trigger.py | 2 +- test/tests/test_tests_mocks.py | 2 +- test/tools/test_tools_jobs.py | 2 +- test/tools/test_tools_target.py | 2 +- test/tools/test_tools_time.py | 2 +- test/tools/test_tools_web.py | 2 +- 118 files changed, 120 insertions(+), 124 deletions(-) diff --git a/pytest_run.py b/pytest_run.py index a0a1dd8ad9..decd8a8aa8 100755 --- a/pytest_run.py +++ b/pytest_run.py @@ -11,7 +11,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop if __name__ == "__main__": import sys diff --git a/setup.cfg b/setup.cfg index 7fc3c896e1..1468b41173 100644 --- a/setup.cfg +++ b/setup.cfg @@ -53,14 +53,10 @@ ignore = # These are forbidding certain __future__ imports. The future-import plugin # has errors both for having and not having them; we want to have these until # Sopel no longer supports Python versions that require them. - FI50,FI51,FI53,FI54,FI55, + FI55, # These would require future imports that are not needed any more on Sopel's - # oldest supported Python version (2.7). - FI12,FI16,FI17, - # We ignore the error for missing generator_stop because it's only available - # in Python 3.5+ (switch this to FI55 in the above list when Sopel drops - # support for Python older than 3.5) - FI15, + # oldest supported Python version (3.6). + FI10,FI11,FI12,FI13,FI14,FI16,FI17, # Ignore "annotations" future import, since it's not available before 3.7 FI18 exclude = diff --git a/setup.py b/setup.py index 3ce6ae2994..96a1df7445 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import sys diff --git a/sopel.py b/sopel.py index 34ef947e92..a405c303d2 100755 --- a/sopel.py +++ b/sopel.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import sys diff --git a/sopel/__init__.py b/sopel/__init__.py index 1add04f02a..1dc20f6287 100644 --- a/sopel/__init__.py +++ b/sopel/__init__.py @@ -10,7 +10,7 @@ # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from collections import namedtuple import locale diff --git a/sopel/bot.py b/sopel/bot.py index 398c0aac11..3f2f3f7a1b 100644 --- a/sopel/bot.py +++ b/sopel/bot.py @@ -6,7 +6,7 @@ # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from ast import literal_eval from datetime import datetime diff --git a/sopel/cli/__init__.py b/sopel/cli/__init__.py index 623d5265a3..c1aa0ec6f2 100644 --- a/sopel/cli/__init__.py +++ b/sopel/cli/__init__.py @@ -1,5 +1,5 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop # Shortcut imports from .utils import ( # noqa diff --git a/sopel/cli/config.py b/sopel/cli/config.py index 1c8923cf93..16990c66bc 100644 --- a/sopel/cli/config.py +++ b/sopel/cli/config.py @@ -1,6 +1,6 @@ # coding=utf-8 """Sopel Config Command Line Interface (CLI): ``sopel-config``""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import argparse import os diff --git a/sopel/cli/plugins.py b/sopel/cli/plugins.py index 8cd34f6250..aed8b45d33 100644 --- a/sopel/cli/plugins.py +++ b/sopel/cli/plugins.py @@ -1,6 +1,6 @@ # coding=utf-8 """Sopel Plugins Command Line Interface (CLI): ``sopel-plugins``""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import argparse import inspect diff --git a/sopel/cli/run.py b/sopel/cli/run.py index 3c47251711..5c6397eff0 100755 --- a/sopel/cli/run.py +++ b/sopel/cli/run.py @@ -8,7 +8,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import argparse import logging diff --git a/sopel/cli/utils.py b/sopel/cli/utils.py index 4f3623c6fd..448c82acaa 100644 --- a/sopel/cli/utils.py +++ b/sopel/cli/utils.py @@ -1,5 +1,5 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import inspect import logging diff --git a/sopel/config/__init__.py b/sopel/config/__init__.py index 561e1cccee..bf88326fd9 100644 --- a/sopel/config/__init__.py +++ b/sopel/config/__init__.py @@ -48,7 +48,7 @@ class SpamSection(config.types.StaticSection): # Copyright © 2012, Elad Alfassa # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import configparser import os diff --git a/sopel/config/core_section.py b/sopel/config/core_section.py index 025a897196..4e47d973b2 100644 --- a/sopel/config/core_section.py +++ b/sopel/config/core_section.py @@ -1,6 +1,6 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import os.path diff --git a/sopel/config/types.py b/sopel/config/types.py index 160d76a4d0..5697652812 100644 --- a/sopel/config/types.py +++ b/sopel/config/types.py @@ -24,7 +24,7 @@ ValueError: ListAttribute value must be a list. """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import getpass import os.path diff --git a/sopel/coretasks.py b/sopel/coretasks.py index 10df1efdc4..9974f26398 100644 --- a/sopel/coretasks.py +++ b/sopel/coretasks.py @@ -21,7 +21,7 @@ # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import base64 import collections diff --git a/sopel/db.py b/sopel/db.py index 633711eafe..c718dcc012 100644 --- a/sopel/db.py +++ b/sopel/db.py @@ -1,5 +1,5 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import errno import json diff --git a/sopel/formatting.py b/sopel/formatting.py index 097e24e43e..170706807f 100644 --- a/sopel/formatting.py +++ b/sopel/formatting.py @@ -6,7 +6,7 @@ # Copyright 2014, Elsie Powell, embolalia.com # Copyright 2019, dgw, technobabbl.es # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re import string diff --git a/sopel/irc/__init__.py b/sopel/irc/__init__.py index 7dbce86242..0c48f83bc6 100644 --- a/sopel/irc/__init__.py +++ b/sopel/irc/__init__.py @@ -23,7 +23,7 @@ # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from datetime import datetime import logging diff --git a/sopel/irc/abstract_backends.py b/sopel/irc/abstract_backends.py index 758d27c7d1..bc65444c11 100644 --- a/sopel/irc/abstract_backends.py +++ b/sopel/irc/abstract_backends.py @@ -2,7 +2,7 @@ # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from .utils import safe diff --git a/sopel/irc/backends.py b/sopel/irc/backends.py index 052255b074..05df76fba3 100644 --- a/sopel/irc/backends.py +++ b/sopel/irc/backends.py @@ -4,7 +4,7 @@ # Licensed under the Eiffel Forum License 2. # When working on core IRC protocol related features, consult protocol # documentation at http://www.irchelp.org/irchelp/rfc/ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import asynchat import asyncore diff --git a/sopel/irc/isupport.py b/sopel/irc/isupport.py index 12ae56780f..92e069be32 100644 --- a/sopel/irc/isupport.py +++ b/sopel/irc/isupport.py @@ -12,7 +12,7 @@ # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import functools import itertools diff --git a/sopel/irc/utils.py b/sopel/irc/utils.py index c1fa6c653b..796f22ce22 100644 --- a/sopel/irc/utils.py +++ b/sopel/irc/utils.py @@ -2,7 +2,7 @@ # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import collections diff --git a/sopel/loader.py b/sopel/loader.py index eb55d76cd1..cb627b6e07 100644 --- a/sopel/loader.py +++ b/sopel/loader.py @@ -10,7 +10,7 @@ Do **not** build your plugin based on what is here, you do **not** need to. """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import inspect import logging diff --git a/sopel/logger.py b/sopel/logger.py index 75cd163199..75500d1d27 100644 --- a/sopel/logger.py +++ b/sopel/logger.py @@ -1,5 +1,5 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import logging from logging.config import dictConfig diff --git a/sopel/module.py b/sopel/module.py index 9da952a9d9..a352c26620 100644 --- a/sopel/module.py +++ b/sopel/module.py @@ -6,7 +6,7 @@ Use :mod:`sopel.plugin` instead. This will be removed in Sopel 9. """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop # Import everything from sopel.plugin at the time of replacement. # Everything new from this point on must *not* leak here. diff --git a/sopel/modules/__init__.py b/sopel/modules/__init__.py index c5b3997ac1..b87fd388f9 100644 --- a/sopel/modules/__init__.py +++ b/sopel/modules/__init__.py @@ -1,2 +1,2 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop diff --git a/sopel/modules/admin.py b/sopel/modules/admin.py index 50f3c11fd8..cfff9c520f 100644 --- a/sopel/modules/admin.py +++ b/sopel/modules/admin.py @@ -10,7 +10,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import logging diff --git a/sopel/modules/adminchannel.py b/sopel/modules/adminchannel.py index 42c0c21c40..f5b38f383a 100644 --- a/sopel/modules/adminchannel.py +++ b/sopel/modules/adminchannel.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re diff --git a/sopel/modules/announce.py b/sopel/modules/announce.py index 2d2997981e..d556e0a351 100644 --- a/sopel/modules/announce.py +++ b/sopel/modules/announce.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel import plugin diff --git a/sopel/modules/bugzilla.py b/sopel/modules/bugzilla.py index 6c92265405..0affc415d3 100644 --- a/sopel/modules/bugzilla.py +++ b/sopel/modules/bugzilla.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import logging import re diff --git a/sopel/modules/calc.py b/sopel/modules/calc.py index 521c850859..b3a10e490f 100644 --- a/sopel/modules/calc.py +++ b/sopel/modules/calc.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel import plugin from sopel.tools.calculation import eval_equation diff --git a/sopel/modules/choose.py b/sopel/modules/choose.py index 7095fd520f..39e93cec95 100644 --- a/sopel/modules/choose.py +++ b/sopel/modules/choose.py @@ -9,7 +9,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import random import unicodedata diff --git a/sopel/modules/clock.py b/sopel/modules/clock.py index 1b4eaeb953..1715172cb2 100644 --- a/sopel/modules/clock.py +++ b/sopel/modules/clock.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel import plugin, tools from sopel.tools.time import ( diff --git a/sopel/modules/countdown.py b/sopel/modules/countdown.py index 182f39da48..481099ab6a 100644 --- a/sopel/modules/countdown.py +++ b/sopel/modules/countdown.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime diff --git a/sopel/modules/currency.py b/sopel/modules/currency.py index cc1f8a7350..30717731c5 100644 --- a/sopel/modules/currency.py +++ b/sopel/modules/currency.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import logging import re diff --git a/sopel/modules/dice.py b/sopel/modules/dice.py index 583f8ec3ee..a24263cbdd 100644 --- a/sopel/modules/dice.py +++ b/sopel/modules/dice.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import operator import random diff --git a/sopel/modules/emoticons.py b/sopel/modules/emoticons.py index 5f55f1adbb..d03ff5451a 100644 --- a/sopel/modules/emoticons.py +++ b/sopel/modules/emoticons.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel import plugin diff --git a/sopel/modules/find.py b/sopel/modules/find.py index 647c4ac068..2d14536777 100644 --- a/sopel/modules/find.py +++ b/sopel/modules/find.py @@ -12,7 +12,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from collections import deque import re diff --git a/sopel/modules/find_updates.py b/sopel/modules/find_updates.py index fcb49724a8..eb90f4f4ef 100644 --- a/sopel/modules/find_updates.py +++ b/sopel/modules/find_updates.py @@ -9,7 +9,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import requests diff --git a/sopel/modules/help.py b/sopel/modules/help.py index 569f1b25f4..7a53a3304b 100644 --- a/sopel/modules/help.py +++ b/sopel/modules/help.py @@ -10,7 +10,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import collections import logging diff --git a/sopel/modules/invite.py b/sopel/modules/invite.py index 885f547999..46793a136c 100644 --- a/sopel/modules/invite.py +++ b/sopel/modules/invite.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel import plugin, tools diff --git a/sopel/modules/ip.py b/sopel/modules/ip.py index 39be7a9eca..62e8896083 100644 --- a/sopel/modules/ip.py +++ b/sopel/modules/ip.py @@ -8,7 +8,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import logging import os diff --git a/sopel/modules/isup.py b/sopel/modules/isup.py index 7290548f77..59141d73a5 100644 --- a/sopel/modules/isup.py +++ b/sopel/modules/isup.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import requests diff --git a/sopel/modules/lmgtfy.py b/sopel/modules/lmgtfy.py index f9fe61c1eb..6d2c495ff9 100644 --- a/sopel/modules/lmgtfy.py +++ b/sopel/modules/lmgtfy.py @@ -6,7 +6,7 @@ https://sopel.chat/ """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from urllib.parse import urlencode diff --git a/sopel/modules/meetbot.py b/sopel/modules/meetbot.py index 3eea864c31..51da7065ed 100644 --- a/sopel/modules/meetbot.py +++ b/sopel/modules/meetbot.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import codecs import collections diff --git a/sopel/modules/ping.py b/sopel/modules/ping.py index 2bac281354..2c418c221a 100644 --- a/sopel/modules/ping.py +++ b/sopel/modules/ping.py @@ -5,7 +5,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import random diff --git a/sopel/modules/pronouns.py b/sopel/modules/pronouns.py index 1723317371..bd615e2c2e 100644 --- a/sopel/modules/pronouns.py +++ b/sopel/modules/pronouns.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel import plugin diff --git a/sopel/modules/py.py b/sopel/modules/py.py index 3753ac1b2b..80ea34406d 100644 --- a/sopel/modules/py.py +++ b/sopel/modules/py.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from requests import get diff --git a/sopel/modules/rand.py b/sopel/modules/rand.py index b6daeb11c8..7fef23011e 100644 --- a/sopel/modules/rand.py +++ b/sopel/modules/rand.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import random import sys diff --git a/sopel/modules/reddit.py b/sopel/modules/reddit.py index 6f4b315e79..1f9b364e40 100644 --- a/sopel/modules/reddit.py +++ b/sopel/modules/reddit.py @@ -8,7 +8,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime as dt import html diff --git a/sopel/modules/reload.py b/sopel/modules/reload.py index 63c2755128..a82f0333e2 100644 --- a/sopel/modules/reload.py +++ b/sopel/modules/reload.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import logging import subprocess diff --git a/sopel/modules/remind.py b/sopel/modules/remind.py index 5282860f42..4a9e9f4cfc 100644 --- a/sopel/modules/remind.py +++ b/sopel/modules/remind.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import collections from datetime import datetime diff --git a/sopel/modules/safety.py b/sopel/modules/safety.py index d32af63ea5..4cf8ac8361 100644 --- a/sopel/modules/safety.py +++ b/sopel/modules/safety.py @@ -6,7 +6,7 @@ This plugin uses virustotal.com """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import json import logging diff --git a/sopel/modules/search.py b/sopel/modules/search.py index 91804328ef..3f0d425695 100644 --- a/sopel/modules/search.py +++ b/sopel/modules/search.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re diff --git a/sopel/modules/seen.py b/sopel/modules/seen.py index 2b609a1d01..93013948f7 100644 --- a/sopel/modules/seen.py +++ b/sopel/modules/seen.py @@ -8,7 +8,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime import time diff --git a/sopel/modules/tell.py b/sopel/modules/tell.py index f96f3111bb..7e80ef48fb 100644 --- a/sopel/modules/tell.py +++ b/sopel/modules/tell.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from collections import defaultdict import io # don't use `codecs` for loading the DB; it will split lines on some IRC formatting diff --git a/sopel/modules/tld.py b/sopel/modules/tld.py index c1854bc293..2f3f5a46c4 100644 --- a/sopel/modules/tld.py +++ b/sopel/modules/tld.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from datetime import datetime from encodings import idna diff --git a/sopel/modules/translate.py b/sopel/modules/translate.py index 0a49290f6a..1557c951f2 100644 --- a/sopel/modules/translate.py +++ b/sopel/modules/translate.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import json import random diff --git a/sopel/modules/unicode_info.py b/sopel/modules/unicode_info.py index ba300ae070..824bcfeafe 100644 --- a/sopel/modules/unicode_info.py +++ b/sopel/modules/unicode_info.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import unicodedata diff --git a/sopel/modules/units.py b/sopel/modules/units.py index f170329613..68c427b136 100644 --- a/sopel/modules/units.py +++ b/sopel/modules/units.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re diff --git a/sopel/modules/uptime.py b/sopel/modules/uptime.py index 8af9d93a14..ebd0f35d96 100644 --- a/sopel/modules/uptime.py +++ b/sopel/modules/uptime.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime diff --git a/sopel/modules/url.py b/sopel/modules/url.py index 442ff8fd33..e789874fe2 100644 --- a/sopel/modules/url.py +++ b/sopel/modules/url.py @@ -9,7 +9,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import ipaddress import logging diff --git a/sopel/modules/version.py b/sopel/modules/version.py index 50a1a0d67b..430820993a 100644 --- a/sopel/modules/version.py +++ b/sopel/modules/version.py @@ -7,7 +7,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime import os diff --git a/sopel/modules/wikipedia.py b/sopel/modules/wikipedia.py index 86e7f3b800..969a5d3302 100644 --- a/sopel/modules/wikipedia.py +++ b/sopel/modules/wikipedia.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from html.parser import HTMLParser import re diff --git a/sopel/modules/wiktionary.py b/sopel/modules/wiktionary.py index 53b3dc2d50..f982a9705a 100644 --- a/sopel/modules/wiktionary.py +++ b/sopel/modules/wiktionary.py @@ -6,7 +6,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re diff --git a/sopel/modules/xkcd.py b/sopel/modules/xkcd.py index dc369010de..259412678f 100644 --- a/sopel/modules/xkcd.py +++ b/sopel/modules/xkcd.py @@ -8,7 +8,7 @@ https://sopel.chat """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import random import re diff --git a/sopel/plugin.py b/sopel/plugin.py index 28f407c488..c60ea0ea00 100644 --- a/sopel/plugin.py +++ b/sopel/plugin.py @@ -8,7 +8,7 @@ # Copyright 2019, Florian Strzelecki # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import functools import re diff --git a/sopel/plugins/__init__.py b/sopel/plugins/__init__.py index dbaea5a78b..29344fbff2 100644 --- a/sopel/plugins/__init__.py +++ b/sopel/plugins/__init__.py @@ -28,7 +28,7 @@ # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import collections import imp diff --git a/sopel/plugins/exceptions.py b/sopel/plugins/exceptions.py index 1d840e4afa..529f968499 100644 --- a/sopel/plugins/exceptions.py +++ b/sopel/plugins/exceptions.py @@ -3,7 +3,7 @@ # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop class PluginError(Exception): diff --git a/sopel/plugins/handlers.py b/sopel/plugins/handlers.py index 76902aa077..3188e7eb04 100644 --- a/sopel/plugins/handlers.py +++ b/sopel/plugins/handlers.py @@ -42,7 +42,7 @@ # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import imp import importlib diff --git a/sopel/plugins/jobs.py b/sopel/plugins/jobs.py index c9ebe6968f..a170aaf676 100644 --- a/sopel/plugins/jobs.py +++ b/sopel/plugins/jobs.py @@ -15,7 +15,7 @@ # Copyright 2020, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import itertools import logging diff --git a/sopel/plugins/rules.py b/sopel/plugins/rules.py index cc8b04a972..3eaa56edf2 100644 --- a/sopel/plugins/rules.py +++ b/sopel/plugins/rules.py @@ -15,7 +15,7 @@ # Copyright 2020, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime diff --git a/sopel/test_tools.py b/sopel/test_tools.py index 8e25c6fd4b..2833b823f8 100644 --- a/sopel/test_tools.py +++ b/sopel/test_tools.py @@ -17,7 +17,7 @@ # Copyright 2013, Ari Koivula, # Copyright 2019, Florian Strzelecki # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import os import re diff --git a/sopel/tests/__init__.py b/sopel/tests/__init__.py index c67efcfc5d..2d5c9702df 100644 --- a/sopel/tests/__init__.py +++ b/sopel/tests/__init__.py @@ -3,7 +3,7 @@ .. versionadded:: 7.0 """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop def rawlist(*args): diff --git a/sopel/tests/factories.py b/sopel/tests/factories.py index 4334702de9..bf4d1f850b 100644 --- a/sopel/tests/factories.py +++ b/sopel/tests/factories.py @@ -3,7 +3,7 @@ .. versionadded:: 7.0 """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re diff --git a/sopel/tests/mocks.py b/sopel/tests/mocks.py index dadc1c8709..5e7cf90746 100644 --- a/sopel/tests/mocks.py +++ b/sopel/tests/mocks.py @@ -3,7 +3,7 @@ .. versionadded:: 7.0 """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel.irc.abstract_backends import AbstractIRCBackend diff --git a/sopel/tests/pytest_plugin.py b/sopel/tests/pytest_plugin.py index d690b0fc55..c664bdf1fe 100644 --- a/sopel/tests/pytest_plugin.py +++ b/sopel/tests/pytest_plugin.py @@ -3,7 +3,7 @@ .. versionadded:: 7.0 """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re import sys diff --git a/sopel/tools/__init__.py b/sopel/tools/__init__.py index 9168ef18ae..288cf53e24 100644 --- a/sopel/tools/__init__.py +++ b/sopel/tools/__init__.py @@ -12,7 +12,7 @@ # https://sopel.chat -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import codecs from collections import defaultdict diff --git a/sopel/tools/_events.py b/sopel/tools/_events.py index 3d3101838a..7909a9b11a 100644 --- a/sopel/tools/_events.py +++ b/sopel/tools/_events.py @@ -1,5 +1,5 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop class events(object): diff --git a/sopel/tools/calculation.py b/sopel/tools/calculation.py index 4ca0124278..5a32fe3258 100644 --- a/sopel/tools/calculation.py +++ b/sopel/tools/calculation.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tools to help safely do calculations from user input""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import ast import numbers diff --git a/sopel/tools/jobs.py b/sopel/tools/jobs.py index fe7f6a29d4..8a35fd88d0 100644 --- a/sopel/tools/jobs.py +++ b/sopel/tools/jobs.py @@ -12,7 +12,7 @@ # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import inspect import logging diff --git a/sopel/tools/target.py b/sopel/tools/target.py index 20501619cd..4c74fd1c0d 100644 --- a/sopel/tools/target.py +++ b/sopel/tools/target.py @@ -1,5 +1,5 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import functools diff --git a/sopel/tools/time.py b/sopel/tools/time.py index e52dfb4b92..49f16f49ed 100644 --- a/sopel/tools/time.py +++ b/sopel/tools/time.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tools for getting and displaying the time.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime diff --git a/sopel/tools/web.py b/sopel/tools/web.py index 0e5815e8e4..5afd9306f8 100644 --- a/sopel/tools/web.py +++ b/sopel/tools/web.py @@ -17,7 +17,7 @@ # Copyright © 2019, dgw, technobabbl.es # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from html.entities import name2codepoint import re diff --git a/sopel/trigger.py b/sopel/trigger.py index 49a5aa466f..dc71cb1be7 100644 --- a/sopel/trigger.py +++ b/sopel/trigger.py @@ -1,6 +1,6 @@ # coding=utf-8 """Triggers are how Sopel tells callables about their runtime context.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime import re diff --git a/sopel/web.py b/sopel/web.py index 03ec2f9b7b..48dfe57116 100644 --- a/sopel/web.py +++ b/sopel/web.py @@ -12,7 +12,7 @@ # Copyright © 2019, dgw, technobabbl.es # Licensed under the Eiffel Forum License 2. -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import sys diff --git a/test/cli/test_cli_run.py b/test/cli/test_cli_run.py index f20fe71cc8..94b98172de 100644 --- a/test/cli/test_cli_run.py +++ b/test/cli/test_cli_run.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for command handling""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import argparse from contextlib import contextmanager diff --git a/test/cli/test_cli_utils.py b/test/cli/test_cli_utils.py index a9123bb3df..0cb15bb4ed 100644 --- a/test/cli/test_cli_utils.py +++ b/test/cli/test_cli_utils.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for sopel.cli.utils""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import argparse from contextlib import contextmanager diff --git a/test/config/test_config_types.py b/test/config/test_config_types.py index 36f6133e7c..46081b9322 100644 --- a/test/config/test_config_types.py +++ b/test/config/test_config_types.py @@ -1,5 +1,5 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import os diff --git a/test/irc/test_irc_abstract_backends.py b/test/irc/test_irc_abstract_backends.py index 8821bee1d6..bb0c8c73ed 100644 --- a/test/irc/test_irc_abstract_backends.py +++ b/test/irc/test_irc_abstract_backends.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for core ``sopel.irc.backends``""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel.irc.abstract_backends import AbstractIRCBackend diff --git a/test/irc/test_irc_isupport.py b/test/irc/test_irc_isupport.py index a56d9d0272..8c0d7bfe35 100644 --- a/test/irc/test_irc_isupport.py +++ b/test/irc/test_irc_isupport.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for core ``sopel.irc.isupport``""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import pytest diff --git a/test/irc/test_irc_utils.py b/test/irc/test_irc_utils.py index 6bbf9ac672..c9a5b1f7fa 100644 --- a/test/irc/test_irc_utils.py +++ b/test/irc/test_irc_utils.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for core ``sopel.irc.utils``""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import pytest diff --git a/test/modules/test_modules_choose.py b/test/modules/test_modules_choose.py index f956b8da05..e402afe0d1 100644 --- a/test/modules/test_modules_choose.py +++ b/test/modules/test_modules_choose.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for Sopel's ``choose`` plugin""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import pytest diff --git a/test/modules/test_modules_find_updates.py b/test/modules/test_modules_find_updates.py index aff2124bd1..4063b87050 100644 --- a/test/modules/test_modules_find_updates.py +++ b/test/modules/test_modules_find_updates.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for Sopel's ``find_updates`` plugin""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import pytest import requests.exceptions diff --git a/test/modules/test_modules_isup.py b/test/modules/test_modules_isup.py index 3003358cbe..2c7fa0cb7b 100644 --- a/test/modules/test_modules_isup.py +++ b/test/modules/test_modules_isup.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for Sopel's ``isup`` plugin""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import pytest import requests.exceptions diff --git a/test/modules/test_modules_remind.py b/test/modules/test_modules_remind.py index 564159356b..b972491d05 100644 --- a/test/modules/test_modules_remind.py +++ b/test/modules/test_modules_remind.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for Sopel's ``remind`` plugin""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from datetime import datetime import os diff --git a/test/modules/test_modules_tell.py b/test/modules/test_modules_tell.py index 66c113f0d0..7dfa968483 100644 --- a/test/modules/test_modules_tell.py +++ b/test/modules/test_modules_tell.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for Sopel's ``tell`` plugin""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime import io diff --git a/test/modules/test_modules_url.py b/test/modules/test_modules_url.py index a2c1fbf6d9..8c37b5a969 100644 --- a/test/modules/test_modules_url.py +++ b/test/modules/test_modules_url.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for Sopel's ``url`` plugin""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re diff --git a/test/plugins/test_plugins_handlers.py b/test/plugins/test_plugins_handlers.py index 991751301f..e91e6032e4 100644 --- a/test/plugins/test_plugins_handlers.py +++ b/test/plugins/test_plugins_handlers.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for the ``sopel.plugins.handlers`` module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import os import sys diff --git a/test/plugins/test_plugins_rules.py b/test/plugins/test_plugins_rules.py index 9d019a0cbb..b534dc867a 100644 --- a/test/plugins/test_plugins_rules.py +++ b/test/plugins/test_plugins_rules.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for the ``sopel.plugins.rules`` module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re diff --git a/test/test_bot.py b/test/test_bot.py index a21f412d7a..7727f85ae7 100644 --- a/test/test_bot.py +++ b/test/test_bot.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for core ``sopel.bot`` module""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re diff --git a/test/test_config.py b/test/test_config.py index 3b1bbdc7a6..70cf241296 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -1,5 +1,5 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import os diff --git a/test/test_coretasks.py b/test/test_coretasks.py index fd60f3c7ac..b523773733 100644 --- a/test/test_coretasks.py +++ b/test/test_coretasks.py @@ -1,6 +1,6 @@ # coding=utf-8 """coretasks.py tests""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import pytest diff --git a/test/test_db.py b/test/test_db.py index ab4ebc7d11..498f925379 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -4,7 +4,7 @@ TODO: Most of these tests assume functionality tested in other tests. This is enough to get everything working (and is better than nothing), but best practice would probably be not to do that.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import json import os diff --git a/test/test_formatting.py b/test/test_formatting.py index becb8a5459..11bf079064 100644 --- a/test/test_formatting.py +++ b/test/test_formatting.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for message formatting""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import pytest diff --git a/test/test_irc.py b/test/test_irc.py index a6314bcac9..3156073db4 100644 --- a/test/test_irc.py +++ b/test/test_irc.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for core ``sopel.irc``""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import pytest diff --git a/test/test_loader.py b/test/test_loader.py index c4d4faa1e6..211edd52cc 100644 --- a/test/test_loader.py +++ b/test/test_loader.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for the ``sopel.loader`` module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import inspect import re diff --git a/test/test_module.py b/test/test_module.py index 1d33b1c30f..834cfe1d2c 100644 --- a/test/test_module.py +++ b/test/test_module.py @@ -7,7 +7,7 @@ compatible up to Sopel 9, when it will be removed. """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import pytest diff --git a/test/test_plugin.py b/test/test_plugin.py index 098c08be2c..5836bd6a4c 100644 --- a/test/test_plugin.py +++ b/test/test_plugin.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for sopel.plugin decorators""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel import plugin from sopel.tests import rawlist diff --git a/test/test_plugins.py b/test/test_plugins.py index 940579aba3..aaafee68bf 100644 --- a/test/test_plugins.py +++ b/test/test_plugins.py @@ -1,6 +1,6 @@ # coding=utf-8 """Test for the ``sopel.plugins`` module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import sys diff --git a/test/test_regression.py b/test/test_regression.py index 164720da09..2862e11a22 100644 --- a/test/test_regression.py +++ b/test/test_regression.py @@ -1,6 +1,6 @@ # coding=utf-8 """Regression tests""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel import coretasks, tools diff --git a/test/test_tools.py b/test/test_tools.py index 0815f5f302..76be576c1c 100644 --- a/test/test_tools.py +++ b/test/test_tools.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests sopel.tools""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import re diff --git a/test/test_trigger.py b/test/test_trigger.py index f88e404780..03a14084b6 100644 --- a/test/test_trigger.py +++ b/test/test_trigger.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for message parsing""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime import re diff --git a/test/tests/test_tests_mocks.py b/test/tests/test_tests_mocks.py index 6c4cf78276..600d3cb151 100644 --- a/test/tests/test_tests_mocks.py +++ b/test/tests/test_tests_mocks.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for ``sopel.tests.mocks`` module""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel.tests.mocks import MockIRCBackend diff --git a/test/tools/test_tools_jobs.py b/test/tools/test_tools_jobs.py index 34ac61d9a8..809d011a1e 100644 --- a/test/tools/test_tools_jobs.py +++ b/test/tools/test_tools_jobs.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for Job Scheduler""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import time diff --git a/test/tools/test_tools_target.py b/test/tools/test_tools_target.py index 3de25bea5d..bd57c5b29f 100644 --- a/test/tools/test_tools_target.py +++ b/test/tools/test_tools_target.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests for targets: Channel & User""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop from sopel import plugin from sopel.tools import Identifier, target diff --git a/test/tools/test_tools_time.py b/test/tools/test_tools_time.py index d493882572..c49064a184 100644 --- a/test/tools/test_tools_time.py +++ b/test/tools/test_tools_time.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tools for getting and displaying the time.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import datetime diff --git a/test/tools/test_tools_web.py b/test/tools/test_tools_web.py index c42e5f88d9..ce3d574c38 100644 --- a/test/tools/test_tools_web.py +++ b/test/tools/test_tools_web.py @@ -1,6 +1,6 @@ # coding=utf-8 """Tests Sopel's web tools""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import generator_stop import pytest From 43e58f9bb5b2a48f06dd9ff1667741b222c2cc09 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Fri, 7 May 2021 15:17:47 +0200 Subject: [PATCH 05/16] setup: adapt setup.[cfg|py] for Py3.6+ Co-authored-by: dgw --- setup.cfg | 7 ++----- setup.py | 19 +++++++++---------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/setup.cfg b/setup.cfg index 1468b41173..fb7953bf0e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,17 +16,14 @@ classifiers = License :: Eiffel Forum License (EFL) License :: OSI Approved :: Eiffel Forum License Operating System :: POSIX :: Linux - 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 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 Topic :: Communications :: Chat :: Internet Relay Chat [options] -python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4 +python_requires = >=3.6, <4 packages = find: zip_safe = false diff --git a/setup.py b/setup.py index 96a1df7445..d77e9c8079 100755 --- a/setup.py +++ b/setup.py @@ -34,16 +34,17 @@ # We check Python's version ourselves in case someone installed Sopel on an # old version of pip (<9.0.0), which doesn't know about `python_requires`. -if sys.version_info < (2, 7) or ( - sys.version_info.major >= 3 and sys.version_info < (3, 3) -): +if sys.version_info < (3, 6): # Maybe not the best way to do this, but this question is tiring. - raise ImportError('Sopel requires Python 2.7+ or 3.3+.') -# Py2 EOL: https://www.python.org/dev/peps/pep-0373/#maintenance-releases -if sys.version_info.major == 2: + raise ImportError('Sopel requires Python 3.6+.') + +# Py3.6 EOL: https://www.python.org/dev/peps/pep-0494/#lifespan +if sys.version_info < (3, 7): + # TODO check this warning before releasing Sopel 8.0 print( - 'Warning: Python 2.x has reached end of life and will receive ' - 'no further updates. Sopel 8.0 will drop support for it.', + 'Warning: Python 3.6 will reach end of life by the end of 2021 ' + 'and will receive no further updates. ' + 'Sopel 9.0 will drop support for it.', file=sys.stderr, ) @@ -54,8 +55,6 @@ def read_reqs(path): requires = read_reqs('requirements.txt') -if sys.version_info[0] < 3: - requires.append('backports.ssl_match_hostname') dev_requires = requires + read_reqs('dev-requirements.txt') setup( From b000f920a092c87e725f133a6c97a736c9a811a4 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Fri, 7 May 2021 16:21:27 +0200 Subject: [PATCH 06/16] cli: update run script rules for Py3.6+ --- sopel/cli/run.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/sopel/cli/run.py b/sopel/cli/run.py index 5c6397eff0..c657eea37d 100755 --- a/sopel/cli/run.py +++ b/sopel/cli/run.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python2.7 -# coding=utf-8 """ Sopel - An IRC Bot Copyright 2008, Sean B. Palmer, inamidst.com @@ -27,12 +25,18 @@ if sys.version_info < (2, 7) or ( sys.version_info.major >= 3 and sys.version_info < (3, 3) ): - tools.stderr('Error: Sopel requires Python 2.7+ or 3.3+.') + tools.stderr('Error: Sopel requires Python 3.6+.') sys.exit(1) -if sys.version_info.major == 2: - tools.stderr( - 'Warning: Python 2.x has reached end of life and will receive ' - 'no further updates. Sopel 8.0 will drop support for it.') + +# Py3.6 EOL: https://www.python.org/dev/peps/pep-0494/#lifespan +if sys.version_info < (3, 7): + # TODO check this warning before releasing Sopel 8.0 + print( + 'Warning: Python 3.6 will reach end of life by the end of 2021 ' + 'and will receive no further updates. ' + 'Sopel 9.0 will drop support for it.', + file=sys.stderr, + ) LOGGER = logging.getLogger(__name__) From 29dab11a57f3f9c3ff14d2d6be9ff594440c7d97 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Fri, 7 May 2021 17:15:58 +0200 Subject: [PATCH 07/16] checkstyle.sh: remove obsolete checks --- checkstyle.sh | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/checkstyle.sh b/checkstyle.sh index 72b5fa1d74..57febe811e 100755 --- a/checkstyle.sh +++ b/checkstyle.sh @@ -1,9 +1,5 @@ #!/bin/sh -find_source_files() { - find . -name '*.py' -size +0 -print | grep -ve './docs' -e 'env' -e './contrib' -e './conftest.py' -} -files=$(find_source_files) # For now, go through all the checking stages and only die at the end exit_code=0 @@ -12,20 +8,4 @@ if ! flake8; then exit_code=1 fi -# Find files which use the unicode type but (heuristically) don't make it py3 -# safe -fail_py3_unicode=false -for file in $(find_source_files); do - if grep -qle 'unicode(' -e 'class .*(unicode)' $file; then - if ! grep -ql 'unicode = str' $file; then - echo "Suspicious 'unicode' use: $file" - fail_py3_unicode=true - fi - fi -done -if $fail_py3_unicode; then - echo "ERROR: Above files use unicode() but do not make it safe for Python 3." - exit_code=1 -fi - exit $exit_code From d7dd19743cc87a85a903a4ada767151569cf4707 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Fri, 7 May 2021 20:51:05 +0200 Subject: [PATCH 08/16] sopel: remove obsolete usage of sys.version_info --- sopel/__init__.py | 11 +++++------ sopel/cli/run.py | 4 +--- sopel/config/__init__.py | 5 +---- sopel/loader.py | 8 ++------ sopel/modules/translate.py | 7 ------- sopel/test_tools.py | 8 ++------ sopel/tools/__init__.py | 5 +---- sopel/tools/web.py | 36 +++++++++++++----------------------- sopel/web.py | 6 +----- 9 files changed, 26 insertions(+), 64 deletions(-) diff --git a/sopel/__init__.py b/sopel/__init__.py index 1dc20f6287..e38fa1ba13 100644 --- a/sopel/__init__.py +++ b/sopel/__init__.py @@ -35,12 +35,11 @@ ] loc = locale.getlocale() -if sys.version_info.major > 2: - if not loc[1] or 'UTF-8' not in loc[1]: - print('WARNING!!! You are running with a non-UTF8 locale environment ' - 'variables (e.g. LC_ALL is set to "C"), which makes Python 3 do ' - 'stupid things. If you get strange errors, please set it to ' - 'something like "en_US.UTF-8".', file=sys.stderr) +if not loc[1] or 'UTF-8' not in loc[1]: + print('WARNING!!! You are running with a non-UTF8 locale environment ' + 'variables (e.g. LC_ALL is set to "C"), which makes Python 3 do ' + 'stupid things. If you get strange errors, please set it to ' + 'something like "en_US.UTF-8".', file=sys.stderr) __version__ = pkg_resources.get_distribution('sopel').version diff --git a/sopel/cli/run.py b/sopel/cli/run.py index c657eea37d..68d2ce3444 100755 --- a/sopel/cli/run.py +++ b/sopel/cli/run.py @@ -22,9 +22,7 @@ # This is in case someone somehow manages to install Sopel on an old version # of pip (<9.0.0), which doesn't know about `python_requires`, or tries to run # from source on an unsupported version of Python. -if sys.version_info < (2, 7) or ( - sys.version_info.major >= 3 and sys.version_info < (3, 3) -): +if sys.version_info < (3, 6): tools.stderr('Error: Sopel requires Python 3.6+.') sys.exit(1) diff --git a/sopel/config/__init__.py b/sopel/config/__init__.py index bf88326fd9..80e859233c 100644 --- a/sopel/config/__init__.py +++ b/sopel/config/__init__.py @@ -57,9 +57,6 @@ class SpamSection(config.types.StaticSection): from . import core_section, types -basestring = str - - __all__ = [ 'core_section', 'types', @@ -333,7 +330,7 @@ def get_list(self, name): value = getattr(self, name) if not value: return [] - if isinstance(value, basestring): + if isinstance(value, str): value = value.split(',') # Keep the split value, so we don't have to keep doing this setattr(self, name, value) diff --git a/sopel/loader.py b/sopel/loader.py index cb627b6e07..e59afce5af 100644 --- a/sopel/loader.py +++ b/sopel/loader.py @@ -21,10 +21,6 @@ from sopel.tools import deprecated, itervalues -if sys.version_info.major >= 3: - basestring = (str, bytes) - - LOGGER = logging.getLogger(__name__) @@ -106,7 +102,7 @@ def clean_callable(func, config): if not hasattr(func, 'event'): func.event = ['PRIVMSG'] else: - if isinstance(func.event, basestring): + if isinstance(func.event, (str, bytes)): func.event = [func.event.upper()] else: func.event = [event.upper() for event in func.event] @@ -114,7 +110,7 @@ def clean_callable(func, config): # TODO: remove in Sopel 8 # Stay compatible with old Phenny/Jenni "modules" (plugins) # that set the attribute directly - if hasattr(func, 'rule') and isinstance(func.rule, basestring): + if hasattr(func, 'rule') and isinstance(func.rule, (str, bytes)): LOGGER.warning( 'The `rule` attribute of %s.%s should be a list, not a string; ' 'this behavior is deprecated in Sopel 7.1 ' diff --git a/sopel/modules/translate.py b/sopel/modules/translate.py index 1557c951f2..fb2277b29d 100644 --- a/sopel/modules/translate.py +++ b/sopel/modules/translate.py @@ -11,7 +11,6 @@ import json import random -import sys import requests @@ -114,9 +113,6 @@ def tr(bot, trigger): ) return - if sys.version_info.major < 3 and isinstance(msg, str): - msg = msg.decode('utf-8') - msg = web.decode(msg) msg = '"%s" (%s to %s, translate.google.com)' % (msg, in_lang, out_lang) bot.say(msg) @@ -180,9 +176,6 @@ def langcode(p): % (src, dest)) return - if sys.version_info.major < 3 and isinstance(msg, str): - msg = msg.decode('utf-8') - msg = web.decode(msg) # msg.replace(''', "'") msg = '"%s" (%s to %s, translate.google.com)' % (msg, src, dest) diff --git a/sopel/test_tools.py b/sopel/test_tools.py index 2833b823f8..88876a6c85 100644 --- a/sopel/test_tools.py +++ b/sopel/test_tools.py @@ -21,7 +21,6 @@ import os import re -import sys import tempfile try: @@ -42,9 +41,6 @@ 'run_example_tests', ] -if sys.version_info.major >= 3: - basestring = str - class MockConfig(config.Config): @tools.deprecated('use configfactory fixture instead', '7.0', '8.0') @@ -103,13 +99,13 @@ def _init_config(self): cfg.parser.set('core', 'homedir', home_dir) def register_url_callback(self, pattern, callback): - if isinstance(pattern, basestring): + if isinstance(pattern, str): pattern = re.compile(pattern) self.memory['url_callbacks'][pattern] = callback def unregister_url_callback(self, pattern, callback): - if isinstance(pattern, basestring): + if isinstance(pattern, str): pattern = re.compile(pattern) try: diff --git a/sopel/tools/__init__.py b/sopel/tools/__init__.py index 288cf53e24..46786478bc 100644 --- a/sopel/tools/__init__.py +++ b/sopel/tools/__init__.py @@ -216,10 +216,7 @@ def get_input(prompt): dropped in Sopel 8.0. The function will be removed in Sopel 8.1. """ - if sys.version_info.major >= 3: - return input(prompt) - else: - return raw_input(prompt).decode('utf8') + return input(prompt) @deprecated('rule compilation tools are now private', '7.1', '8.0') diff --git a/sopel/tools/web.py b/sopel/tools/web.py index 5afd9306f8..ea1c5d668c 100644 --- a/sopel/tools/web.py +++ b/sopel/tools/web.py @@ -21,7 +21,6 @@ from html.entities import name2codepoint import re -import sys import urllib from urllib.parse import urlparse, urlunparse @@ -142,13 +141,10 @@ def unquote(string): :return str: the decoded ``string`` .. note:: - This is a shim to make writing cross-compatible plugins for both - Python 2 and Python 3 easier. + + This is a convenient shortcut for ``urllib.parse.unquote``. """ - if sys.version_info.major < 3: - return urllib.unquote(string.encode('utf-8')).decode('utf-8') - else: - return urllib.parse.unquote(string) + return urllib.parse.unquote(string) def quote_query(string): @@ -166,30 +162,24 @@ def quote_query(string): def urlencode_non_ascii(b): """Safely encodes non-ASCII characters in a URL.""" - regex = '[\x80-\xFF]' - if sys.version_info.major > 2: - regex = b'[\x80-\xFF]' - return re.sub(regex, lambda c: '%%%02x' % ord(c.group(0)), b) + return re.sub(b'[\x80-\xFF]', lambda c: '%%%02x' % ord(c.group(0)), b) def iri_to_uri(iri): """Decodes an internationalized domain name (IDN).""" parts = urlparse(iri) - parts_seq = (part.encode('idna') if parti == 1 else urlencode_non_ascii(part.encode('utf-8')) for parti, part in enumerate(parts)) - if sys.version_info.major > 2: - parts_seq = list(parts_seq) - + parts_seq = list( + part.encode('idna') + if parti == 1 else urlencode_non_ascii(part.encode('utf-8')) + for parti, part in enumerate(parts) + ) parsed = urlunparse(parts_seq) - if sys.version_info.major > 2: - return parsed.decode() - else: - return parsed + return parsed.decode() -if sys.version_info.major < 3: - urlencode = urllib.urlencode -else: - urlencode = urllib.parse.urlencode +# direct shortcut kept for backward compatibility reasons +# TODO consider removing this +urlencode = urllib.parse.urlencode # Functions for URL detection diff --git a/sopel/web.py b/sopel/web.py index 48dfe57116..8e7743cd16 100644 --- a/sopel/web.py +++ b/sopel/web.py @@ -14,16 +14,12 @@ from __future__ import generator_stop -import sys +import http.client as httplib import requests from .tools import deprecated -if sys.version_info.major < 3: - import httplib -else: - import http.client as httplib # Imports to facilitate transition from sopel.web to sopel.tools.web from .tools.web import ( # noqa From 15eeb2d645df7f6267630c850bc758cee5695e59 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Fri, 7 May 2021 21:28:44 +0200 Subject: [PATCH 09/16] test: remove obsolete usage of sys.version_info --- test/test_db.py | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/test/test_db.py b/test/test_db.py index 498f925379..e0c17d8547 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -8,7 +8,6 @@ import json import os -import sys import tempfile import pytest @@ -16,17 +15,8 @@ from sopel.db import ChannelValues, Nicknames, NickValues, PluginValues, SopelDB from sopel.tools import Identifier + db_filename = tempfile.mkstemp()[1] -if sys.version_info.major >= 3: - unicode = str - basestring = str - iteritems = dict.items - itervalues = dict.values - iterkeys = dict.keys -else: - iteritems = dict.iteritems - itervalues = dict.itervalues - iterkeys = dict.iterkeys TMP_CONFIG = """ @@ -116,15 +106,15 @@ def test_set_nick_value(db): } def check(): - for key, value in iteritems(data): + for key, value in data.items(): db.set_nick_value(nick, key, value) - for key, value in iteritems(data): + for key, value in data.items(): found_value = session.query(NickValues.value) \ .filter(NickValues.nick_id == nick_id) \ .filter(NickValues.key == key) \ .scalar() - assert json.loads(unicode(found_value)) == value + assert json.loads(str(found_value)) == value check() # Test updates @@ -144,12 +134,12 @@ def test_get_nick_value(db): 'unicode': 'EmbölaliÅ', } - for key, value in iteritems(data): + for key, value in data.items(): nv = NickValues(nick_id=nick_id, key=key, value=json.dumps(value, ensure_ascii=False)) session.add(nv) session.commit() - for key, value in iteritems(data): + for key, value in data.items(): found_value = db.get_nick_value(nick, key) assert found_value == value session.close() @@ -243,7 +233,7 @@ def test_merge_nick_groups(db): .filter(NickValues.nick_id == nick_id) \ .filter(NickValues.key == key) \ .scalar() - assert json.loads(unicode(found)) == value + assert json.loads(str(found)) == value session.close() From 3456d4cd5a95b7a548bc4427ba698a61db4c0b0f Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Sat, 8 May 2021 00:41:12 +0200 Subject: [PATCH 10/16] sopel: replace obsolete tools.iteritems --- sopel/bot.py | 4 ++-- sopel/coretasks.py | 6 +++--- sopel/loader.py | 4 ++-- sopel/modules/remind.py | 4 ++-- sopel/modules/safety.py | 2 +- sopel/test_tools.py | 2 +- sopel/tools/__init__.py | 2 ++ 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sopel/bot.py b/sopel/bot.py index 3f2f3f7a1b..82f8c479ca 100644 --- a/sopel/bot.py +++ b/sopel/bot.py @@ -349,7 +349,7 @@ def __setup_plugins_check_manual_url_callbacks(self, name): # nothing to check return - for key, callback in tools.iteritems(self.memory['url_callbacks']): + for key, callback in self.memory['url_callbacks'].items(): is_checked = getattr( callback, '_sopel_url_callbacks_checked', False) if is_checked: @@ -1207,7 +1207,7 @@ def search_url_callbacks(self, url): # nothing to search return - for regex, function in tools.iteritems(self.memory['url_callbacks']): + for regex, function in self.memory['url_callbacks'].items(): match = regex.search(url) if match: yield function, match diff --git a/sopel/coretasks.py b/sopel/coretasks.py index 9974f26398..c8b3ccd3e7 100644 --- a/sopel/coretasks.py +++ b/sopel/coretasks.py @@ -35,7 +35,7 @@ from sopel.config import ConfigurationError from sopel.irc import isupport from sopel.irc.utils import CapReq, MyInfo -from sopel.tools import events, Identifier, iteritems, SopelMemory, target, web +from sopel.tools import events, Identifier, SopelMemory, target, web LOGGER = logging.getLogger(__name__) @@ -451,7 +451,7 @@ def handle_names(bot, trigger): for name in names: priv = 0 - for prefix, value in iteritems(mapping): + for prefix, value in mapping.items(): if prefix in name: priv = priv | value nick = Identifier(name.lstrip(''.join(mapping.keys()))) @@ -933,7 +933,7 @@ def acct_warn(bot, cap): if cap not in bot._cap_reqs: bot._cap_reqs[cap] = [CapReq('', 'coretasks', acct_warn)] - for cap, reqs in iteritems(bot._cap_reqs): + for cap, reqs in bot._cap_reqs.items(): # At this point, we know mandatory and prohibited don't co-exist, but # we need to call back for optionals if they're also prohibited prefix = '' diff --git a/sopel/loader.py b/sopel/loader.py index e59afce5af..bdb48b5014 100644 --- a/sopel/loader.py +++ b/sopel/loader.py @@ -18,7 +18,7 @@ import sys from sopel.config.core_section import COMMAND_DEFAULT_HELP_PREFIX -from sopel.tools import deprecated, itervalues +from sopel.tools import deprecated LOGGER = logging.getLogger(__name__) @@ -278,7 +278,7 @@ def clean_module(module, config): shutdowns = [] jobs = [] urls = [] - for obj in itervalues(vars(module)): + for obj in vars(module).values(): if callable(obj): is_sopel_callable = getattr(obj, '_sopel_callable', False) is True if getattr(obj, '__name__', None) == 'shutdown': diff --git a/sopel/modules/remind.py b/sopel/modules/remind.py index 4a9e9f4cfc..343f20f34f 100644 --- a/sopel/modules/remind.py +++ b/sopel/modules/remind.py @@ -19,7 +19,7 @@ import pytz -from sopel import plugin, tools +from sopel import plugin from sopel.tools.time import format_time, get_timezone, validate_timezone @@ -95,7 +95,7 @@ def dump_database(filename, data): If the file does not exist, it is created. """ with io.open(filename, 'w', encoding='utf-8') as database: - for unixtime, reminders in tools.iteritems(data): + for unixtime, reminders in data.items(): for channel, nick, message in reminders: line = '%s\t%s\t%s\t%s\n' % (unixtime, channel, nick, message) database.write(line) diff --git a/sopel/modules/safety.py b/sopel/modules/safety.py index 4cf8ac8361..f5e755948d 100644 --- a/sopel/modules/safety.py +++ b/sopel/modules/safety.py @@ -240,7 +240,7 @@ def _clean_cache(bot): # clean up by age first cutoff = time.time() - (7 * 24 * 60 * 60) # 7 days ago old_keys = [] - for key, data in tools.iteritems(bot.memory['safety_cache']): + for key, data in bot.memory['safety_cache'].items(): if data['fetched'] <= cutoff: old_keys.append(key) for key in old_keys: diff --git a/sopel/test_tools.py b/sopel/test_tools.py index 88876a6c85..3bd6d69970 100644 --- a/sopel/test_tools.py +++ b/sopel/test_tools.py @@ -114,7 +114,7 @@ def unregister_url_callback(self, pattern, callback): pass def search_url_callbacks(self, url): - for regex, function in tools.iteritems(self.memory['url_callbacks']): + for regex, function in self.memory['url_callbacks'].items(): match = regex.search(url) if match: yield function, match diff --git a/sopel/tools/__init__.py b/sopel/tools/__init__.py index 46786478bc..272bfad7f6 100644 --- a/sopel/tools/__init__.py +++ b/sopel/tools/__init__.py @@ -33,6 +33,8 @@ from . import time, web # NOQA +# Kept for backward compatibility +# TODO: consider removing that raw_input = input iteritems = dict.items itervalues = dict.values From e3315bb2c17ed08169c65f237fa34e00f3c01c3d Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Sat, 5 Jun 2021 20:04:54 +0200 Subject: [PATCH 11/16] test_tools: import configparser --- sopel/test_tools.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sopel/test_tools.py b/sopel/test_tools.py index 3bd6d69970..873eedd016 100644 --- a/sopel/test_tools.py +++ b/sopel/test_tools.py @@ -19,15 +19,11 @@ # Licensed under the Eiffel Forum License 2. from __future__ import generator_stop +import configparser import os import re import tempfile -try: - import ConfigParser -except ImportError: - import configparser as ConfigParser - from sopel import bot, config, tools @@ -46,7 +42,7 @@ class MockConfig(config.Config): @tools.deprecated('use configfactory fixture instead', '7.0', '8.0') def __init__(self): self.filename = tempfile.mkstemp()[1] - self.parser = ConfigParser.RawConfigParser(allow_no_value=True) + self.parser = configparser.RawConfigParser(allow_no_value=True) self.parser.add_section('core') self.parser.set('core', 'owner', 'Embolalia') self.define_section('core', config.core_section.CoreSection) From 4d0dad898f9468ad5a01423843071ea1f4c8c81d Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Sat, 5 Jun 2021 20:28:40 +0200 Subject: [PATCH 12/16] sopel: minor cleanup after Py2.7 removal Cleaning old typo and comments. Co-authored-by: dgw --- sopel/__init__.py | 2 +- sopel/modules/ip.py | 3 --- sopel/tools/web.py | 1 + 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sopel/__init__.py b/sopel/__init__.py index e38fa1ba13..ffe235662b 100644 --- a/sopel/__init__.py +++ b/sopel/__init__.py @@ -37,7 +37,7 @@ loc = locale.getlocale() if not loc[1] or 'UTF-8' not in loc[1]: print('WARNING!!! You are running with a non-UTF8 locale environment ' - 'variables (e.g. LC_ALL is set to "C"), which makes Python 3 do ' + 'variable (e.g. LC_ALL is set to "C"), which makes Python 3 do ' 'stupid things. If you get strange errors, please set it to ' 'something like "en_US.UTF-8".', file=sys.stderr) diff --git a/sopel/modules/ip.py b/sopel/modules/ip.py index 62e8896083..baeec602cf 100644 --- a/sopel/modules/ip.py +++ b/sopel/modules/ip.py @@ -14,9 +14,6 @@ import os import socket import tarfile -# urlretrieve has been put under urllib.request in Python 3. -# It's also deprecated so this should probably be replaced with -# urllib2. from urllib.request import urlretrieve import geoip2.database diff --git a/sopel/tools/web.py b/sopel/tools/web.py index ea1c5d668c..b2929be961 100644 --- a/sopel/tools/web.py +++ b/sopel/tools/web.py @@ -144,6 +144,7 @@ def unquote(string): This is a convenient shortcut for ``urllib.parse.unquote``. """ + # TODO deprecated? return urllib.parse.unquote(string) From d9fd411db1c71d698d83e6f62401dfa49339a1f8 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Sat, 5 Jun 2021 20:41:07 +0200 Subject: [PATCH 13/16] all: remove coding header --- CONTRIBUTING.md | 6 ++---- docs/source/conf.py | 3 +-- pytest_run.py | 1 - setup.cfg | 2 +- setup.py | 1 - sopel.py | 1 - sopel/__init__.py | 1 - sopel/bot.py | 1 - sopel/cli/__init__.py | 1 - sopel/cli/config.py | 1 - sopel/cli/plugins.py | 1 - sopel/cli/utils.py | 1 - sopel/config/__init__.py | 1 - sopel/config/core_section.py | 2 -- sopel/config/types.py | 1 - sopel/coretasks.py | 1 - sopel/db.py | 1 - sopel/formatting.py | 1 - sopel/irc/__init__.py | 1 - sopel/irc/abstract_backends.py | 1 - sopel/irc/backends.py | 1 - sopel/irc/isupport.py | 1 - sopel/irc/utils.py | 1 - sopel/loader.py | 1 - sopel/logger.py | 1 - sopel/module.py | 1 - sopel/modules/__init__.py | 1 - sopel/modules/admin.py | 1 - sopel/modules/adminchannel.py | 1 - sopel/modules/announce.py | 1 - sopel/modules/bugzilla.py | 1 - sopel/modules/calc.py | 1 - sopel/modules/choose.py | 1 - sopel/modules/clock.py | 1 - sopel/modules/countdown.py | 1 - sopel/modules/currency.py | 1 - sopel/modules/dice.py | 1 - sopel/modules/emoticons.py | 1 - sopel/modules/find.py | 1 - sopel/modules/find_updates.py | 1 - sopel/modules/help.py | 1 - sopel/modules/invite.py | 1 - sopel/modules/ip.py | 1 - sopel/modules/isup.py | 1 - sopel/modules/lmgtfy.py | 1 - sopel/modules/meetbot.py | 1 - sopel/modules/ping.py | 1 - sopel/modules/pronouns.py | 1 - sopel/modules/py.py | 1 - sopel/modules/rand.py | 1 - sopel/modules/reddit.py | 1 - sopel/modules/reload.py | 1 - sopel/modules/remind.py | 1 - sopel/modules/safety.py | 1 - sopel/modules/search.py | 1 - sopel/modules/seen.py | 1 - sopel/modules/tell.py | 1 - sopel/modules/tld.py | 1 - sopel/modules/translate.py | 1 - sopel/modules/unicode_info.py | 1 - sopel/modules/units.py | 1 - sopel/modules/uptime.py | 1 - sopel/modules/url.py | 1 - sopel/modules/version.py | 1 - sopel/modules/wikipedia.py | 1 - sopel/modules/wiktionary.py | 1 - sopel/modules/xkcd.py | 1 - sopel/plugin.py | 1 - sopel/plugins/__init__.py | 1 - sopel/plugins/exceptions.py | 1 - sopel/plugins/handlers.py | 1 - sopel/plugins/jobs.py | 1 - sopel/plugins/rules.py | 1 - sopel/test_tools.py | 1 - sopel/tests/__init__.py | 1 - sopel/tests/factories.py | 1 - sopel/tests/mocks.py | 1 - sopel/tests/pytest_plugin.py | 1 - sopel/tools/__init__.py | 1 - sopel/tools/_events.py | 1 - sopel/tools/calculation.py | 1 - sopel/tools/jobs.py | 1 - sopel/tools/target.py | 1 - sopel/tools/time.py | 1 - sopel/tools/web.py | 1 - sopel/trigger.py | 1 - sopel/web.py | 1 - test/cli/test_cli_run.py | 1 - test/cli/test_cli_utils.py | 1 - test/config/test_config_types.py | 1 - test/irc/test_irc_abstract_backends.py | 1 - test/irc/test_irc_isupport.py | 1 - test/irc/test_irc_utils.py | 1 - test/modules/test_modules_choose.py | 1 - test/modules/test_modules_find_updates.py | 1 - test/modules/test_modules_isup.py | 1 - test/modules/test_modules_remind.py | 1 - test/modules/test_modules_tell.py | 1 - test/modules/test_modules_url.py | 1 - test/plugins/test_plugins_handlers.py | 3 +-- test/plugins/test_plugins_rules.py | 1 - test/test_bot.py | 3 +-- test/test_config.py | 1 - test/test_coretasks.py | 1 - test/test_db.py | 1 - test/test_formatting.py | 1 - test/test_irc.py | 1 - test/test_loader.py | 3 +-- test/test_module.py | 1 - test/test_plugin.py | 1 - test/test_plugins.py | 3 +-- test/test_regression.py | 1 - test/test_tools.py | 1 - test/test_trigger.py | 1 - test/tests/test_tests_mocks.py | 1 - test/tools/test_tools_jobs.py | 1 - test/tools/test_tools_target.py | 1 - test/tools/test_tools_time.py | 1 - test/tools/test_tools_web.py | 1 - 119 files changed, 8 insertions(+), 128 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f532ef33b9..32f62d3a2d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,10 +45,8 @@ include your changes. the name of the thing you're changing in at the beginning of the message, followed by a colon: the plugin name for plugins, "docs" for documentation files, "coretasks" for `coretasks.py`, "db" for the database feature, etc. -* Python files should always have `# coding=utf-8` as the first line (or the - second, if the first is `#!/usr/bin/env python`), and `from __future__ import - unicode_literals, absolute_import, print_function, division` as the first - line after the module docstring. +* Python files should always have `from __future__ import generator_stop` + as the first line after the module docstring. Documenting Code ---------------- diff --git a/docs/source/conf.py b/docs/source/conf.py index f227476e3b..eda29d5268 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,5 +1,4 @@ -# -*- coding: utf-8 -*- -# +from __future__ import generator_stop # Sopel IRC Bot documentation build configuration file, created by # sphinx-quickstart on Mon Jul 16 23:45:29 2012. # diff --git a/pytest_run.py b/pytest_run.py index decd8a8aa8..023914483e 100755 --- a/pytest_run.py +++ b/pytest_run.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# coding=utf-8 """This is a script for running pytest from the command line. This script exists so that the project directory gets added to sys.path, which diff --git a/setup.cfg b/setup.cfg index fb7953bf0e..ca5ab4fae8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -61,4 +61,4 @@ exclude = env/*, contrib/*, conftest.py -accept-encodings = utf-8 +no-accept-encodings = True diff --git a/setup.py b/setup.py index d77e9c8079..1e16b6afe9 100755 --- a/setup.py +++ b/setup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# coding=utf-8 from __future__ import generator_stop import sys diff --git a/sopel.py b/sopel.py index a405c303d2..3b98ccc424 100755 --- a/sopel.py +++ b/sopel.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# coding=utf-8 from __future__ import generator_stop import sys diff --git a/sopel/__init__.py b/sopel/__init__.py index ffe235662b..12ef61d824 100644 --- a/sopel/__init__.py +++ b/sopel/__init__.py @@ -1,4 +1,3 @@ -# coding=utf-8 # ASCII ONLY IN THIS FILE THOUGH!!!!!!! # Python does some stupid bullshit of respecting LC_ALL over the encoding on the # file, so in order to undo Python's ridiculous fucking idiocy, we have to have diff --git a/sopel/bot.py b/sopel/bot.py index 82f8c479ca..dea31b6b5c 100644 --- a/sopel/bot.py +++ b/sopel/bot.py @@ -1,4 +1,3 @@ -# coding=utf-8 # Copyright 2008, Sean B. Palmer, inamidst.com # Copyright © 2012, Elad Alfassa # Copyright 2012-2015, Elsie Powell, http://embolalia.com diff --git a/sopel/cli/__init__.py b/sopel/cli/__init__.py index c1aa0ec6f2..cefdc40fd4 100644 --- a/sopel/cli/__init__.py +++ b/sopel/cli/__init__.py @@ -1,4 +1,3 @@ -# coding=utf-8 from __future__ import generator_stop # Shortcut imports diff --git a/sopel/cli/config.py b/sopel/cli/config.py index 16990c66bc..f19d79465f 100644 --- a/sopel/cli/config.py +++ b/sopel/cli/config.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Sopel Config Command Line Interface (CLI): ``sopel-config``""" from __future__ import generator_stop diff --git a/sopel/cli/plugins.py b/sopel/cli/plugins.py index aed8b45d33..b40dec92d0 100644 --- a/sopel/cli/plugins.py +++ b/sopel/cli/plugins.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Sopel Plugins Command Line Interface (CLI): ``sopel-plugins``""" from __future__ import generator_stop diff --git a/sopel/cli/utils.py b/sopel/cli/utils.py index 448c82acaa..8a6facd8fa 100644 --- a/sopel/cli/utils.py +++ b/sopel/cli/utils.py @@ -1,4 +1,3 @@ -# coding=utf-8 from __future__ import generator_stop import inspect diff --git a/sopel/config/__init__.py b/sopel/config/__init__.py index 80e859233c..21e334bd3c 100644 --- a/sopel/config/__init__.py +++ b/sopel/config/__init__.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Sopel's configuration module. The :class:`~sopel.config.Config` object provides an interface to access Sopel's diff --git a/sopel/config/core_section.py b/sopel/config/core_section.py index 4e47d973b2..020851c99a 100644 --- a/sopel/config/core_section.py +++ b/sopel/config/core_section.py @@ -1,5 +1,3 @@ -# coding=utf-8 - from __future__ import generator_stop import os.path diff --git a/sopel/config/types.py b/sopel/config/types.py index 5697652812..e1dcaebaae 100644 --- a/sopel/config/types.py +++ b/sopel/config/types.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Types for creating section definitions. A section definition consists of a subclass of :class:`StaticSection`, on which diff --git a/sopel/coretasks.py b/sopel/coretasks.py index c8b3ccd3e7..a02269c908 100644 --- a/sopel/coretasks.py +++ b/sopel/coretasks.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Core Sopel plugin that handles IRC protocol functions. This plugin allows the bot to run without user-facing functionality: diff --git a/sopel/db.py b/sopel/db.py index c718dcc012..c06b41c7e5 100644 --- a/sopel/db.py +++ b/sopel/db.py @@ -1,4 +1,3 @@ -# coding=utf-8 from __future__ import generator_stop import errno diff --git a/sopel/formatting.py b/sopel/formatting.py index 170706807f..8674001f92 100644 --- a/sopel/formatting.py +++ b/sopel/formatting.py @@ -1,4 +1,3 @@ -# coding=utf-8 """The formatting module includes functions to apply IRC formatting to text. *Availability: 4.5+* diff --git a/sopel/irc/__init__.py b/sopel/irc/__init__.py index 0c48f83bc6..ae265f7073 100644 --- a/sopel/irc/__init__.py +++ b/sopel/irc/__init__.py @@ -1,4 +1,3 @@ -# coding=utf-8 """:mod:`sopel.irc` is the core IRC module for Sopel. This sub-package contains everything that is related to the IRC protocol diff --git a/sopel/irc/abstract_backends.py b/sopel/irc/abstract_backends.py index bc65444c11..3ba5fda288 100644 --- a/sopel/irc/abstract_backends.py +++ b/sopel/irc/abstract_backends.py @@ -1,4 +1,3 @@ -# coding=utf-8 # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. diff --git a/sopel/irc/backends.py b/sopel/irc/backends.py index 05df76fba3..9203e08899 100644 --- a/sopel/irc/backends.py +++ b/sopel/irc/backends.py @@ -1,4 +1,3 @@ -# coding=utf-8 # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. diff --git a/sopel/irc/isupport.py b/sopel/irc/isupport.py index 92e069be32..48b2622c9d 100644 --- a/sopel/irc/isupport.py +++ b/sopel/irc/isupport.py @@ -1,4 +1,3 @@ -# coding=utf-8 """IRC Tools for ISUPPORT management. When a server wants to advertise its features and settings, it can use the diff --git a/sopel/irc/utils.py b/sopel/irc/utils.py index 796f22ce22..f4d53a95a7 100644 --- a/sopel/irc/utils.py +++ b/sopel/irc/utils.py @@ -1,4 +1,3 @@ -# coding=utf-8 # Copyright 2019, Florian Strzelecki # # Licensed under the Eiffel Forum License 2. diff --git a/sopel/loader.py b/sopel/loader.py index bdb48b5014..93a57372b0 100644 --- a/sopel/loader.py +++ b/sopel/loader.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Utility functions to manage plugin callables from a Python module. .. important:: diff --git a/sopel/logger.py b/sopel/logger.py index 75500d1d27..50dd5ebd49 100644 --- a/sopel/logger.py +++ b/sopel/logger.py @@ -1,4 +1,3 @@ -# coding=utf-8 from __future__ import generator_stop import logging diff --git a/sopel/module.py b/sopel/module.py index a352c26620..4d0b249274 100644 --- a/sopel/module.py +++ b/sopel/module.py @@ -1,4 +1,3 @@ -# coding=utf-8 """The :mod:`sopel.module` sub-module is replaced by :mod:`sopel.plugin`. .. deprecated:: 7.1 diff --git a/sopel/modules/__init__.py b/sopel/modules/__init__.py index b87fd388f9..c813b73b6b 100644 --- a/sopel/modules/__init__.py +++ b/sopel/modules/__init__.py @@ -1,2 +1 @@ -# coding=utf-8 from __future__ import generator_stop diff --git a/sopel/modules/admin.py b/sopel/modules/admin.py index cfff9c520f..deabd2b65b 100644 --- a/sopel/modules/admin.py +++ b/sopel/modules/admin.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ admin.py - Sopel Admin Plugin Copyright 2010-2011, Sean B. Palmer (inamidst.com) and Michael Yanovich diff --git a/sopel/modules/adminchannel.py b/sopel/modules/adminchannel.py index f5b38f383a..1e49b643ee 100644 --- a/sopel/modules/adminchannel.py +++ b/sopel/modules/adminchannel.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ adminchannel.py - Sopel Channel Admin Plugin Copyright 2010-2011, Michael Yanovich, Alek Rollyson, and Elsie Powell diff --git a/sopel/modules/announce.py b/sopel/modules/announce.py index d556e0a351..b0bcea5ee1 100644 --- a/sopel/modules/announce.py +++ b/sopel/modules/announce.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ announce.py - Sopel Announcement Plugin Sends announcements to all channels the bot has joined. diff --git a/sopel/modules/bugzilla.py b/sopel/modules/bugzilla.py index 0affc415d3..56b039a3aa 100644 --- a/sopel/modules/bugzilla.py +++ b/sopel/modules/bugzilla.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ bugzilla.py - Sopel Bugzilla Plugin Copyright 2013-2015, Embolalia, embolalia.com diff --git a/sopel/modules/calc.py b/sopel/modules/calc.py index b3a10e490f..73b8bc629b 100644 --- a/sopel/modules/calc.py +++ b/sopel/modules/calc.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ calc.py - Sopel Calculator Plugin Copyright 2008, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/choose.py b/sopel/modules/choose.py index 39e93cec95..3008377b51 100644 --- a/sopel/modules/choose.py +++ b/sopel/modules/choose.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ choose.py - Sopel Choice Plugin Copyright 2010-2013, Dimitri "Tyrope" Molenaars, TyRope.nl diff --git a/sopel/modules/clock.py b/sopel/modules/clock.py index 1715172cb2..4c4b13fb56 100644 --- a/sopel/modules/clock.py +++ b/sopel/modules/clock.py @@ -1,4 +1,3 @@ -# coding=utf-8 """clock.py - Sopel Clock Plugin Copyright 2008-9, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/countdown.py b/sopel/modules/countdown.py index 481099ab6a..65025e1067 100644 --- a/sopel/modules/countdown.py +++ b/sopel/modules/countdown.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ countdown.py - Sopel Countdown Plugin Copyright 2011, Michael Yanovich, yanovich.net diff --git a/sopel/modules/currency.py b/sopel/modules/currency.py index 30717731c5..1048b94e26 100644 --- a/sopel/modules/currency.py +++ b/sopel/modules/currency.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ currency.py - Sopel Currency Conversion Plugin Copyright 2013, Elsie Powell, embolalia.com diff --git a/sopel/modules/dice.py b/sopel/modules/dice.py index a24263cbdd..18a7a21aba 100644 --- a/sopel/modules/dice.py +++ b/sopel/modules/dice.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ dice.py - Sopel Dice Plugin Copyright 2010-2013, Dimitri "Tyrope" Molenaars, TyRope.nl diff --git a/sopel/modules/emoticons.py b/sopel/modules/emoticons.py index d03ff5451a..3eedaa59f3 100644 --- a/sopel/modules/emoticons.py +++ b/sopel/modules/emoticons.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ emoticons.py - Sopel Emoticons Plugin Copyright 2018, brasstax diff --git a/sopel/modules/find.py b/sopel/modules/find.py index 2d14536777..ef649f3b88 100644 --- a/sopel/modules/find.py +++ b/sopel/modules/find.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ find.py - Sopel Spelling Correction Plugin This plugin will fix spelling errors if someone corrects them diff --git a/sopel/modules/find_updates.py b/sopel/modules/find_updates.py index eb90f4f4ef..01893c18bb 100644 --- a/sopel/modules/find_updates.py +++ b/sopel/modules/find_updates.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ find_updates.py - Sopel Update Check Plugin This is separated from version.py, so that it can be easily overridden by diff --git a/sopel/modules/help.py b/sopel/modules/help.py index 7a53a3304b..686202ce7a 100644 --- a/sopel/modules/help.py +++ b/sopel/modules/help.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ help.py - Sopel Help Plugin Copyright 2008, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/invite.py b/sopel/modules/invite.py index 46793a136c..fcd3654bd0 100644 --- a/sopel/modules/invite.py +++ b/sopel/modules/invite.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ invite.py - Sopel Invite Plugin Copyright © 2016, João Vanzuita, https://github.com/converge diff --git a/sopel/modules/ip.py b/sopel/modules/ip.py index baeec602cf..59310d4e41 100644 --- a/sopel/modules/ip.py +++ b/sopel/modules/ip.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ ip.py - Sopel GeoIP Lookup Plugin Copyright 2011, Dimitri Molenaars, TyRope.nl, diff --git a/sopel/modules/isup.py b/sopel/modules/isup.py index 59141d73a5..0b98858366 100644 --- a/sopel/modules/isup.py +++ b/sopel/modules/isup.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ isup.py - Sopel Website Status Check Plugin Copyright 2011, Elsie Powell http://embolalia.com diff --git a/sopel/modules/lmgtfy.py b/sopel/modules/lmgtfy.py index 6d2c495ff9..a79dee25f4 100644 --- a/sopel/modules/lmgtfy.py +++ b/sopel/modules/lmgtfy.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ lmgtfy.py - Sopel Let Me Google That For You Plugin Copyright 2013, Dimitri Molenaars http://tyrope.nl/ diff --git a/sopel/modules/meetbot.py b/sopel/modules/meetbot.py index 51da7065ed..fceae33e83 100644 --- a/sopel/modules/meetbot.py +++ b/sopel/modules/meetbot.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ meetbot.py - Sopel Meeting Logger Plugin This plugin is an attempt to implement some of the functionality of Debian's meetbot diff --git a/sopel/modules/ping.py b/sopel/modules/ping.py index 2c418c221a..d45d94ed6a 100644 --- a/sopel/modules/ping.py +++ b/sopel/modules/ping.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ ping.py - Sopel Ping Plugin Copyright 2008 (?), Sean B. Palmer, inamidst.com diff --git a/sopel/modules/pronouns.py b/sopel/modules/pronouns.py index bd615e2c2e..cc57876c34 100644 --- a/sopel/modules/pronouns.py +++ b/sopel/modules/pronouns.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ pronouns.py - Sopel Pronouns Plugin Copyright © 2016, Elsie Powell diff --git a/sopel/modules/py.py b/sopel/modules/py.py index 80ea34406d..2f3dd8b986 100644 --- a/sopel/modules/py.py +++ b/sopel/modules/py.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ py.py - Sopel Python Eval Plugin Copyright 2008, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/rand.py b/sopel/modules/rand.py index 7fef23011e..0b46de09f0 100644 --- a/sopel/modules/rand.py +++ b/sopel/modules/rand.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ rand.py - Rand Plugin Copyright 2013, Ari Koivula, diff --git a/sopel/modules/reddit.py b/sopel/modules/reddit.py index 1f9b364e40..b9c77ffc87 100644 --- a/sopel/modules/reddit.py +++ b/sopel/modules/reddit.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ reddit.py - Sopel Reddit Plugin Copyright 2012, Elsie Powell, embolalia.com diff --git a/sopel/modules/reload.py b/sopel/modules/reload.py index a82f0333e2..dfca7c1c59 100644 --- a/sopel/modules/reload.py +++ b/sopel/modules/reload.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ reload.py - Sopel Plugin Reloader Plugin Copyright 2008, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/remind.py b/sopel/modules/remind.py index 343f20f34f..632f05cd9c 100644 --- a/sopel/modules/remind.py +++ b/sopel/modules/remind.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ remind.py - Sopel Reminder Plugin Copyright 2011, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/safety.py b/sopel/modules/safety.py index f5e755948d..bfba68ea83 100644 --- a/sopel/modules/safety.py +++ b/sopel/modules/safety.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ safety.py - Alerts about malicious URLs Copyright © 2014, Elad Alfassa, diff --git a/sopel/modules/search.py b/sopel/modules/search.py index 3f0d425695..7519bc14d2 100644 --- a/sopel/modules/search.py +++ b/sopel/modules/search.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ search.py - Sopel Search Engine Plugin Copyright 2008-9, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/seen.py b/sopel/modules/seen.py index 93013948f7..675506c275 100644 --- a/sopel/modules/seen.py +++ b/sopel/modules/seen.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ seen.py - Sopel Seen Plugin Copyright 2008, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/tell.py b/sopel/modules/tell.py index 7e80ef48fb..92ad9a6518 100644 --- a/sopel/modules/tell.py +++ b/sopel/modules/tell.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ tell.py - Sopel Tell and Ask Plugin Copyright 2008, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/tld.py b/sopel/modules/tld.py index 2f3f5a46c4..e9fc9840f8 100644 --- a/sopel/modules/tld.py +++ b/sopel/modules/tld.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ tld.py - Sopel TLD Plugin Copyright 2009-10, Michael Yanovich, yanovich.net diff --git a/sopel/modules/translate.py b/sopel/modules/translate.py index fb2277b29d..8d09eb9778 100644 --- a/sopel/modules/translate.py +++ b/sopel/modules/translate.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ translate.py - Sopel Translation Plugin Copyright 2008, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/unicode_info.py b/sopel/modules/unicode_info.py index 824bcfeafe..556d637373 100644 --- a/sopel/modules/unicode_info.py +++ b/sopel/modules/unicode_info.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ unicode_info.py - Sopel Codepoints Plugin Copyright 2013, Elsie Powell, embolalia.com diff --git a/sopel/modules/units.py b/sopel/modules/units.py index 68c427b136..12fdf0d546 100644 --- a/sopel/modules/units.py +++ b/sopel/modules/units.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ units.py - Sopel Unit Conversion Plugin Copyright © 2013, Elad Alfassa, diff --git a/sopel/modules/uptime.py b/sopel/modules/uptime.py index ebd0f35d96..8c45dcd730 100644 --- a/sopel/modules/uptime.py +++ b/sopel/modules/uptime.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ uptime.py - Sopel Uptime Plugin Copyright 2014, Fabian Neundorf diff --git a/sopel/modules/url.py b/sopel/modules/url.py index e789874fe2..fcff7700e5 100644 --- a/sopel/modules/url.py +++ b/sopel/modules/url.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ url.py - Sopel URL Title Plugin Copyright 2010-2011, Michael Yanovich (yanovich.net) & Kenneth Sham diff --git a/sopel/modules/version.py b/sopel/modules/version.py index 430820993a..d1aeab6a49 100644 --- a/sopel/modules/version.py +++ b/sopel/modules/version.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ version.py - Sopel Version Plugin Copyright 2009, Silas Baronda diff --git a/sopel/modules/wikipedia.py b/sopel/modules/wikipedia.py index 969a5d3302..5e33547b3f 100644 --- a/sopel/modules/wikipedia.py +++ b/sopel/modules/wikipedia.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ wikipedia.py - Sopel Wikipedia Plugin Copyright 2013 Elsie Powell - embolalia.com diff --git a/sopel/modules/wiktionary.py b/sopel/modules/wiktionary.py index f982a9705a..ff02c95f78 100644 --- a/sopel/modules/wiktionary.py +++ b/sopel/modules/wiktionary.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ wiktionary.py - Sopel Wiktionary Plugin Copyright 2009, Sean B. Palmer, inamidst.com diff --git a/sopel/modules/xkcd.py b/sopel/modules/xkcd.py index 259412678f..1be5de696d 100644 --- a/sopel/modules/xkcd.py +++ b/sopel/modules/xkcd.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ xkcd.py - Sopel xkcd Plugin Copyright 2010, Michael Yanovich (yanovich.net), and Morgan Goose diff --git a/sopel/plugin.py b/sopel/plugin.py index c60ea0ea00..50a25005d4 100644 --- a/sopel/plugin.py +++ b/sopel/plugin.py @@ -1,4 +1,3 @@ -# coding=utf-8 """This contains decorators and other tools for creating Sopel plugins.""" # Copyright 2013, Ari Koivula, # Copyright © 2013, Elad Alfassa diff --git a/sopel/plugins/__init__.py b/sopel/plugins/__init__.py index 29344fbff2..4213e0fa42 100644 --- a/sopel/plugins/__init__.py +++ b/sopel/plugins/__init__.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Sopel's plugins interface. .. versionadded:: 7.0 diff --git a/sopel/plugins/exceptions.py b/sopel/plugins/exceptions.py index 529f968499..1e7284401f 100644 --- a/sopel/plugins/exceptions.py +++ b/sopel/plugins/exceptions.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Sopel's plugins exceptions.""" # Copyright 2019, Florian Strzelecki # diff --git a/sopel/plugins/handlers.py b/sopel/plugins/handlers.py index 3188e7eb04..e0847e7c93 100644 --- a/sopel/plugins/handlers.py +++ b/sopel/plugins/handlers.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Sopel's plugin handlers. .. versionadded:: 7.0 diff --git a/sopel/plugins/jobs.py b/sopel/plugins/jobs.py index a170aaf676..a03073991e 100644 --- a/sopel/plugins/jobs.py +++ b/sopel/plugins/jobs.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Sopel's plugin jobs management. .. versionadded:: 7.1 diff --git a/sopel/plugins/rules.py b/sopel/plugins/rules.py index 3eaa56edf2..43a9c02c0f 100644 --- a/sopel/plugins/rules.py +++ b/sopel/plugins/rules.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Sopel's plugin rules management. .. versionadded:: 7.1 diff --git a/sopel/test_tools.py b/sopel/test_tools.py index 873eedd016..c5a5570bb9 100644 --- a/sopel/test_tools.py +++ b/sopel/test_tools.py @@ -1,4 +1,3 @@ -# coding=utf-8 """This module provided tools that helped to write tests. .. deprecated:: 7.1 diff --git a/sopel/tests/__init__.py b/sopel/tests/__init__.py index 2d5c9702df..cfbbfc6501 100644 --- a/sopel/tests/__init__.py +++ b/sopel/tests/__init__.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Test tools, factories, pytest fixtures, and mocks. .. versionadded:: 7.0 diff --git a/sopel/tests/factories.py b/sopel/tests/factories.py index bf4d1f850b..fdfd8048dd 100644 --- a/sopel/tests/factories.py +++ b/sopel/tests/factories.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Test factories: they create objects for testing purposes. .. versionadded:: 7.0 diff --git a/sopel/tests/mocks.py b/sopel/tests/mocks.py index 5e7cf90746..feb33bc80e 100644 --- a/sopel/tests/mocks.py +++ b/sopel/tests/mocks.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Test mocks: they fake objects for testing. .. versionadded:: 7.0 diff --git a/sopel/tests/pytest_plugin.py b/sopel/tests/pytest_plugin.py index c664bdf1fe..cffb22013c 100644 --- a/sopel/tests/pytest_plugin.py +++ b/sopel/tests/pytest_plugin.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Pytest plugin for Sopel. .. versionadded:: 7.0 diff --git a/sopel/tools/__init__.py b/sopel/tools/__init__.py index 272bfad7f6..da3dd44761 100644 --- a/sopel/tools/__init__.py +++ b/sopel/tools/__init__.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Useful miscellaneous tools and shortcuts for Sopel plugins *Availability: 3+* diff --git a/sopel/tools/_events.py b/sopel/tools/_events.py index 7909a9b11a..c60628e03f 100644 --- a/sopel/tools/_events.py +++ b/sopel/tools/_events.py @@ -1,4 +1,3 @@ -# coding=utf-8 from __future__ import generator_stop diff --git a/sopel/tools/calculation.py b/sopel/tools/calculation.py index 5a32fe3258..d57c9f0986 100644 --- a/sopel/tools/calculation.py +++ b/sopel/tools/calculation.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tools to help safely do calculations from user input""" from __future__ import generator_stop diff --git a/sopel/tools/jobs.py b/sopel/tools/jobs.py index 8a35fd88d0..d183c4b7bc 100644 --- a/sopel/tools/jobs.py +++ b/sopel/tools/jobs.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Sopel's Job Scheduler: internal tool for job management. .. important:: diff --git a/sopel/tools/target.py b/sopel/tools/target.py index 4c74fd1c0d..d2b1a79951 100644 --- a/sopel/tools/target.py +++ b/sopel/tools/target.py @@ -1,4 +1,3 @@ -# coding=utf-8 from __future__ import generator_stop import functools diff --git a/sopel/tools/time.py b/sopel/tools/time.py index 49f16f49ed..fb82967629 100644 --- a/sopel/tools/time.py +++ b/sopel/tools/time.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tools for getting and displaying the time.""" from __future__ import generator_stop diff --git a/sopel/tools/web.py b/sopel/tools/web.py index b2929be961..19d786694e 100644 --- a/sopel/tools/web.py +++ b/sopel/tools/web.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ The ``tools.web`` package contains utility functions for interaction with web applications, APIs, or websites in your plugins. diff --git a/sopel/trigger.py b/sopel/trigger.py index dc71cb1be7..6a0cc04664 100644 --- a/sopel/trigger.py +++ b/sopel/trigger.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Triggers are how Sopel tells callables about their runtime context.""" from __future__ import generator_stop diff --git a/sopel/web.py b/sopel/web.py index 8e7743cd16..cf4229aae1 100644 --- a/sopel/web.py +++ b/sopel/web.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ *Availability: 3+, deprecated in 6.2.0* diff --git a/test/cli/test_cli_run.py b/test/cli/test_cli_run.py index 94b98172de..fca5e8ba63 100644 --- a/test/cli/test_cli_run.py +++ b/test/cli/test_cli_run.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for command handling""" from __future__ import generator_stop diff --git a/test/cli/test_cli_utils.py b/test/cli/test_cli_utils.py index 0cb15bb4ed..dbfb87d879 100644 --- a/test/cli/test_cli_utils.py +++ b/test/cli/test_cli_utils.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for sopel.cli.utils""" from __future__ import generator_stop diff --git a/test/config/test_config_types.py b/test/config/test_config_types.py index 46081b9322..b042b5306a 100644 --- a/test/config/test_config_types.py +++ b/test/config/test_config_types.py @@ -1,4 +1,3 @@ -# coding=utf-8 from __future__ import generator_stop import os diff --git a/test/irc/test_irc_abstract_backends.py b/test/irc/test_irc_abstract_backends.py index bb0c8c73ed..a13388d2fc 100644 --- a/test/irc/test_irc_abstract_backends.py +++ b/test/irc/test_irc_abstract_backends.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for core ``sopel.irc.backends``""" from __future__ import generator_stop diff --git a/test/irc/test_irc_isupport.py b/test/irc/test_irc_isupport.py index 8c0d7bfe35..3bf2373418 100644 --- a/test/irc/test_irc_isupport.py +++ b/test/irc/test_irc_isupport.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for core ``sopel.irc.isupport``""" from __future__ import generator_stop diff --git a/test/irc/test_irc_utils.py b/test/irc/test_irc_utils.py index c9a5b1f7fa..6c6daa0e50 100644 --- a/test/irc/test_irc_utils.py +++ b/test/irc/test_irc_utils.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for core ``sopel.irc.utils``""" from __future__ import generator_stop diff --git a/test/modules/test_modules_choose.py b/test/modules/test_modules_choose.py index e402afe0d1..902e5a6215 100644 --- a/test/modules/test_modules_choose.py +++ b/test/modules/test_modules_choose.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for Sopel's ``choose`` plugin""" from __future__ import generator_stop diff --git a/test/modules/test_modules_find_updates.py b/test/modules/test_modules_find_updates.py index 4063b87050..6a7678de63 100644 --- a/test/modules/test_modules_find_updates.py +++ b/test/modules/test_modules_find_updates.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for Sopel's ``find_updates`` plugin""" from __future__ import generator_stop diff --git a/test/modules/test_modules_isup.py b/test/modules/test_modules_isup.py index 2c7fa0cb7b..4debb8608c 100644 --- a/test/modules/test_modules_isup.py +++ b/test/modules/test_modules_isup.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for Sopel's ``isup`` plugin""" from __future__ import generator_stop diff --git a/test/modules/test_modules_remind.py b/test/modules/test_modules_remind.py index b972491d05..4198b42199 100644 --- a/test/modules/test_modules_remind.py +++ b/test/modules/test_modules_remind.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for Sopel's ``remind`` plugin""" from __future__ import generator_stop diff --git a/test/modules/test_modules_tell.py b/test/modules/test_modules_tell.py index 7dfa968483..4da4884a09 100644 --- a/test/modules/test_modules_tell.py +++ b/test/modules/test_modules_tell.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for Sopel's ``tell`` plugin""" from __future__ import generator_stop diff --git a/test/modules/test_modules_url.py b/test/modules/test_modules_url.py index 8c37b5a969..44b1c6a2f7 100644 --- a/test/modules/test_modules_url.py +++ b/test/modules/test_modules_url.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for Sopel's ``url`` plugin""" from __future__ import generator_stop diff --git a/test/plugins/test_plugins_handlers.py b/test/plugins/test_plugins_handlers.py index e91e6032e4..91b4a069dc 100644 --- a/test/plugins/test_plugins_handlers.py +++ b/test/plugins/test_plugins_handlers.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for the ``sopel.plugins.handlers`` module.""" from __future__ import generator_stop @@ -11,7 +10,7 @@ from sopel.plugins import handlers -MOCK_MODULE_CONTENT = """# coding=utf-8 +MOCK_MODULE_CONTENT = """ \"\"\"plugin label \"\"\" """ diff --git a/test/plugins/test_plugins_rules.py b/test/plugins/test_plugins_rules.py index b534dc867a..c7d2fbe80a 100644 --- a/test/plugins/test_plugins_rules.py +++ b/test/plugins/test_plugins_rules.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for the ``sopel.plugins.rules`` module.""" from __future__ import generator_stop diff --git a/test/test_bot.py b/test/test_bot.py index 7727f85ae7..28aeddb6bb 100644 --- a/test/test_bot.py +++ b/test/test_bot.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for core ``sopel.bot`` module""" from __future__ import generator_stop @@ -19,7 +18,7 @@ enable = coretasks """ -MOCK_MODULE_CONTENT = """# coding=utf-8 +MOCK_MODULE_CONTENT = """from __future__ import generator_stop import sopel.module diff --git a/test/test_config.py b/test/test_config.py index 70cf241296..c2d9826e25 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -1,4 +1,3 @@ -# coding=utf-8 from __future__ import generator_stop import os diff --git a/test/test_coretasks.py b/test/test_coretasks.py index b523773733..4e287d3035 100644 --- a/test/test_coretasks.py +++ b/test/test_coretasks.py @@ -1,4 +1,3 @@ -# coding=utf-8 """coretasks.py tests""" from __future__ import generator_stop diff --git a/test/test_db.py b/test/test_db.py index e0c17d8547..65ceb625e4 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for the new database functionality. TODO: Most of these tests assume functionality tested in other tests. This is diff --git a/test/test_formatting.py b/test/test_formatting.py index 11bf079064..78cedf0664 100644 --- a/test/test_formatting.py +++ b/test/test_formatting.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for message formatting""" from __future__ import generator_stop diff --git a/test/test_irc.py b/test/test_irc.py index 3156073db4..d9744b7fce 100644 --- a/test/test_irc.py +++ b/test/test_irc.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for core ``sopel.irc``""" from __future__ import generator_stop diff --git a/test/test_loader.py b/test/test_loader.py index 211edd52cc..03d8a1ddc9 100644 --- a/test/test_loader.py +++ b/test/test_loader.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for the ``sopel.loader`` module.""" from __future__ import generator_stop @@ -10,7 +9,7 @@ from sopel import loader, module, plugins -MOCK_MODULE_CONTENT = """# coding=utf-8 +MOCK_MODULE_CONTENT = """from __future__ import generator_stop import re import sopel.module diff --git a/test/test_module.py b/test/test_module.py index 834cfe1d2c..db16895434 100644 --- a/test/test_module.py +++ b/test/test_module.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for sopel.module decorators .. important:: diff --git a/test/test_plugin.py b/test/test_plugin.py index 5836bd6a4c..406a6dfe49 100644 --- a/test/test_plugin.py +++ b/test/test_plugin.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for sopel.plugin decorators""" from __future__ import generator_stop diff --git a/test/test_plugins.py b/test/test_plugins.py index aaafee68bf..67730f2dfc 100644 --- a/test/test_plugins.py +++ b/test/test_plugins.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Test for the ``sopel.plugins`` module.""" from __future__ import generator_stop @@ -10,7 +9,7 @@ from sopel import plugins -MOCK_MODULE_CONTENT = """# coding=utf-8 +MOCK_MODULE_CONTENT = """from __future__ import generator_stop import sopel.module diff --git a/test/test_regression.py b/test/test_regression.py index 2862e11a22..89c91359e4 100644 --- a/test/test_regression.py +++ b/test/test_regression.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Regression tests""" from __future__ import generator_stop diff --git a/test/test_tools.py b/test/test_tools.py index 76be576c1c..f79a8da12e 100644 --- a/test/test_tools.py +++ b/test/test_tools.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests sopel.tools""" from __future__ import generator_stop diff --git a/test/test_trigger.py b/test/test_trigger.py index 03a14084b6..357e322ef4 100644 --- a/test/test_trigger.py +++ b/test/test_trigger.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for message parsing""" from __future__ import generator_stop diff --git a/test/tests/test_tests_mocks.py b/test/tests/test_tests_mocks.py index 600d3cb151..73619cee77 100644 --- a/test/tests/test_tests_mocks.py +++ b/test/tests/test_tests_mocks.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for ``sopel.tests.mocks`` module""" from __future__ import generator_stop diff --git a/test/tools/test_tools_jobs.py b/test/tools/test_tools_jobs.py index 809d011a1e..267724c62f 100644 --- a/test/tools/test_tools_jobs.py +++ b/test/tools/test_tools_jobs.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for Job Scheduler""" from __future__ import generator_stop diff --git a/test/tools/test_tools_target.py b/test/tools/test_tools_target.py index bd57c5b29f..671aa67799 100644 --- a/test/tools/test_tools_target.py +++ b/test/tools/test_tools_target.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for targets: Channel & User""" from __future__ import generator_stop diff --git a/test/tools/test_tools_time.py b/test/tools/test_tools_time.py index c49064a184..4de8ce1030 100644 --- a/test/tools/test_tools_time.py +++ b/test/tools/test_tools_time.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tools for getting and displaying the time.""" from __future__ import generator_stop diff --git a/test/tools/test_tools_web.py b/test/tools/test_tools_web.py index ce3d574c38..36d3c33bc7 100644 --- a/test/tools/test_tools_web.py +++ b/test/tools/test_tools_web.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests Sopel's web tools""" from __future__ import generator_stop From f70f7957036ff292ad44137f8df7c21f3b9acd79 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Mon, 14 Jun 2021 09:12:23 +0200 Subject: [PATCH 14/16] pip: update requirements and dev requirements for Python>=3.6 Co-authored-by: dgw --- dev-requirements.txt | 34 ++++++++-------------------------- requirements.txt | 24 ++++-------------------- 2 files changed, 12 insertions(+), 46 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index a150208986..005b95cf32 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,31 +1,13 @@ -coveralls<2.0; python_version < '3.5' -coveralls>=2.0; python_version >= '3.5' -flake8<3.6.0; python_version == '3.3' -flake8>=3.7.0,<3.8.0; python_version != '3.3' +coveralls>=2.0 +flake8>=3.7.0,<3.8.0 flake8-coding flake8-future-import<0.4.6 -flake8-import-order; python_version > '3.3' -flake8-import-order<=1.18.1; python_version <= '3.3' -# transitive dependency of Sphinx -# added f-strings in 2.x, but it's not worth doing a whole suite of version markers -MarkupSafe<2.0 -pytest<3.3; python_version == '3.3' -pytest>=4.6,<4.7; python_version != '3.3' -pytest-vcr==1.0.2; python_version != '3.3' -pytest-vcr==0.3.0; python_version == '3.3' -PyYAML<5.1; python_version == '3.3' -PyYAML<5.3; python_version == '3.4' +flake8-import-order +pytest>=4.6,<4.7 +pytest-vcr==1.0.2 requests-mock==1.9.1 -setuptools<40.0; python_version == '3.3' -# use Sphinx 3.x until dev begins on Sopel 8 and we drop the dead snakes -sphinx<4.0 -# autoprogram extension added type annotations in 0.1.6 -# such annotations require Python 3.5 -sphinxcontrib-autoprogram<0.1.6; python_version < '3.5' +sphinx # further constrain autoprogram version because the new (in 2021) maintainer # already demonstrated a willingness to make major changes in patch versions -sphinxcontrib-autoprogram<=0.1.7; python_version >= '3.5' -vcrpy==2.1.1; python_version == '2.7' -vcrpy<1.12.0; python_version == '3.3' -vcrpy<2.1.0; python_version == '3.4' -vcrpy<3.0.0; python_version >= '3.5' +sphinxcontrib-autoprogram<=0.1.7 +vcrpy<3.0.0 diff --git a/requirements.txt b/requirements.txt index 60572eb803..b68186af9b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,23 +1,7 @@ -xmltodict<0.12.0; python_version == '3.3' -xmltodict==0.12; python_version != '3.3' +xmltodict==0.12 pytz praw>=4.0.0,<6.0.0 -# transitive dependency of praw; v0.18 introduced f-string syntax -update-checker<0.18; python_version < '3.6' -geoip2<3.0; python_version <= '3.5' and python_version != '2.7' -geoip2>=3.0,<4.0; python_version == '2.7' -geoip2>=4.0,<5.0; python_version >= '3.6' -# transitive dependency of geoip2; v2 dropped py2.7 & py3 < 3.6 -maxminddb<2.0; python_version < '3.6' -ipaddress<2.0; python_version < '3.3' +geoip2>=4.0,<5.0 requests>=2.0.0,<3.0.0 -# transitive dependency of requests -# 2.0 will drop EOL Python 2.7 & 3.5, just like Sopel 8 plans to -urllib3<1.27; python_version != '3.3' and python_version != '3.4' -urllib3<1.23; python_version == '3.3' -urllib3<1.25; python_version == '3.4' -dnspython<2.0; python_version == '2.7' -dnspython<1.16.0; python_version == '3.3' -dnspython<3.0; python_version >= '3.4' -sqlalchemy<1.3; python_version == '3.3' -sqlalchemy<1.4; python_version != '3.3' +dnspython<3.0 +sqlalchemy<1.4 From bd431b07f2e88815a707225529d0d792934c69e5 Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Mon, 14 Jun 2021 09:25:29 +0200 Subject: [PATCH 15/16] README: Python 3.6+ now! --- README.rst | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/README.rst b/README.rst index 1ff5da25c1..6540d82a91 100644 --- a/README.rst +++ b/README.rst @@ -31,14 +31,7 @@ First, either clone the repository with ``git clone git://github.com/sopel-irc/sopel.git`` or download a tarball `from GitHub `_. -Note: Sopel requires Python 2.7.x or Python 3.3+ to run. On Python 2.7, -Sopel requires ``backports.ssl_match_hostname`` to be installed. Use -``pip install backports.ssl_match_hostname`` or -``yum install python-backports.ssl_match_hostname`` to install it, or download -and install it manually `from PyPI `_. - -Important: Sopel 8.0 will drop support for many old Python versions, -including Python 2.7! +Note: Sopel requires Python 3.6+ to run. In the source directory (whether cloned or from the tarball) run ``pip install -e .``. You can then run ``sopel`` to configure and start the bot. From f9fe98fae1d4c94f466296cdb3dae85bfb8c6dae Mon Sep 17 00:00:00 2001 From: Florian Strzelecki Date: Sat, 26 Jun 2021 12:22:49 +0200 Subject: [PATCH 16/16] quality: upgrade flake8 --- dev-requirements.txt | 4 ++-- sopel/modules/help.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 005b95cf32..8d9f4fd8d6 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,7 +1,7 @@ coveralls>=2.0 -flake8>=3.7.0,<3.8.0 +flake8 flake8-coding -flake8-future-import<0.4.6 +flake8-future-import flake8-import-order pytest>=4.6,<4.7 pytest-vcr==1.0.2 diff --git a/sopel/modules/help.py b/sopel/modules/help.py index 686202ce7a..90705eb06b 100644 --- a/sopel/modules/help.py +++ b/sopel/modules/help.py @@ -273,8 +273,8 @@ def respond(text): bot.reply('The documentation for this command is too long; ' 'I\'m sending it to you in a private message.') - def msgfun(l): - bot.say(l, trigger.nick) + def msgfun(message): + bot.say(message, trigger.nick) else: msgfun = respond