Skip to content

Commit 0479737

Browse files
authored
Merge pull request #2326 from Exirel/remove-python2-todos
sopel: fix TODOs related to Python 2
2 parents 3afa016 + 596adc4 commit 0479737

File tree

3 files changed

+23
-52
lines changed

3 files changed

+23
-52
lines changed

sopel/modules/currency.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,7 @@ def exchange(bot, match):
137137
LOGGER.error(err)
138138
return
139139

140-
query = match.string
141-
142-
targets = query.split()
143-
amount_in = targets.pop(0)
144-
base = targets.pop(0)
145-
targets.pop(0)
146-
147-
# TODO: Use this instead after dropping Python 2 support
148-
# amount, base, _, *targets = query.split()
140+
amount_in, base, _, *targets = match.string.split()
149141

150142
try:
151143
amount = float(amount_in)

sopel/plugins/handlers.py

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@
4444
from __future__ import annotations
4545

4646
import abc
47-
import imp
4847
import importlib
48+
import importlib.util
4949
import inspect
5050
import itertools
5151
import os
52+
import sys
5253
from typing import Optional
5354

5455
# TODO: refactor along with usage in sopel.__init__ in py3.8+ world
@@ -57,13 +58,6 @@
5758
from sopel import __version__ as release, loader
5859
from . import exceptions
5960

60-
try:
61-
reload = importlib.reload
62-
except AttributeError:
63-
# py2: no reload function
64-
# TODO: imp is deprecated, to be removed when py2 support is dropped
65-
reload = imp.reload
66-
6761

6862
class AbstractPluginHandler(abc.ABC):
6963
"""Base class for plugin handlers.
@@ -334,7 +328,7 @@ def reload(self):
334328
335329
This method assumes the plugin is already loaded.
336330
"""
337-
self._module = reload(self._module)
331+
self._module = importlib.reload(self._module)
338332

339333
def is_loaded(self):
340334
return self._module is not None
@@ -435,45 +429,31 @@ def __init__(self, filename):
435429

436430
if good_file:
437431
name = os.path.basename(filename)[:-3]
438-
module_type = imp.PY_SOURCE
432+
spec = importlib.util.spec_from_file_location(
433+
name,
434+
filename,
435+
)
439436
elif good_dir:
440437
name = os.path.basename(filename)
441-
module_type = imp.PKG_DIRECTORY
438+
spec = importlib.util.spec_from_file_location(
439+
name,
440+
os.path.join(filename, '__init__.py'),
441+
submodule_search_locations=filename,
442+
)
442443
else:
443444
raise exceptions.PluginError('Invalid Sopel plugin: %s' % filename)
444445

445446
self.filename = filename
446447
self.path = filename
447-
self.module_type = module_type
448+
self.module_spec = spec
448449

449450
super().__init__(name)
450451

451452
def _load(self):
452-
# The current implementation uses `imp.load_module` to perform the
453-
# load action, which also reloads the module. However, `imp` is
454-
# deprecated in Python 3, so that might need to be changed when the
455-
# support for Python 2 is dropped.
456-
#
457-
# However, the solution for Python 3 is non-trivial, since the
458-
# `importlib` built-in module does not have a similar function,
459-
# therefore requires to dive into its public internals
460-
# (``importlib.machinery`` and ``importlib.util``).
461-
#
462-
# All of that is doable, but represents a lot of work. As long as
463-
# Python 2 is supported, we can keep it for now.
464-
#
465-
# TODO: switch to ``importlib`` when Python2 support is dropped.
466-
if self.module_type == imp.PY_SOURCE:
467-
with open(self.path) as mod:
468-
description = ('.py', 'U', self.module_type)
469-
mod = imp.load_module(self.name, mod, self.path, description)
470-
elif self.module_type == imp.PKG_DIRECTORY:
471-
description = ('', '', self.module_type)
472-
mod = imp.load_module(self.name, None, self.path, description)
473-
else:
474-
raise TypeError('Unsupported module type')
475-
476-
return mod
453+
module = importlib.util.module_from_spec(self.module_spec)
454+
sys.modules[self.name] = module
455+
self.module_spec.loader.exec_module(module)
456+
return module
477457

478458
def get_meta_description(self):
479459
"""Retrieve a meta description for the plugin.

sopel/tests/mocks.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,13 @@ class MockIRCServer:
118118
def __init__(self, bot, join_threads=True):
119119
self.bot = bot
120120
self.join_threads = join_threads
121-
# TODO: `blocking` method args below should be made kwarg-ONLY in py3
122121

123122
@property
124123
def chanserv(self):
125124
"""ChanServ's message prefix."""
126125
return 'ChanServ!ChanServ@services.'
127126

128-
def channel_joined(self, channel, users=None, blocking=None):
127+
def channel_joined(self, channel, users=None, *, blocking=None):
129128
"""Send events as if the bot just joined a channel.
130129
131130
:param str channel: channel to send message for
@@ -195,7 +194,7 @@ def channel_joined(self, channel, users=None, blocking=None):
195194
for t in self.bot.running_triggers:
196195
t.join()
197196

198-
def mode_set(self, channel, flags, users, blocking=None):
197+
def mode_set(self, channel, flags, users, *, blocking=None):
199198
"""Send a MODE event for a ``channel``
200199
201200
:param str channel: channel receiving the MODE event
@@ -237,7 +236,7 @@ def mode_set(self, channel, flags, users, blocking=None):
237236
for t in self.bot.running_triggers:
238237
t.join()
239238

240-
def join(self, user, channel, blocking=None):
239+
def join(self, user, channel, *, blocking=None):
241240
"""Send a ``channel`` JOIN event from ``user``.
242241
243242
:param user: factory for the user who joins the ``channel``
@@ -275,7 +274,7 @@ def join(self, user, channel, blocking=None):
275274
for t in self.bot.running_triggers:
276275
t.join()
277276

278-
def say(self, user, channel, text, blocking=None):
277+
def say(self, user, channel, text, *, blocking=None):
279278
"""Send a ``PRIVMSG`` to ``channel`` by ``user``.
280279
281280
:param user: factory for the user who sends a message to ``channel``
@@ -314,7 +313,7 @@ def say(self, user, channel, text, blocking=None):
314313
for t in self.bot.running_triggers:
315314
t.join()
316315

317-
def pm(self, user, text, blocking=None):
316+
def pm(self, user, text, *, blocking=None):
318317
"""Send a ``PRIVMSG`` to the bot by a ``user``.
319318
320319
:param user: factory for the user object who sends a message

0 commit comments

Comments
 (0)