Skip to content

Commit

Permalink
Merge pull request #2326 from Exirel/remove-python2-todos
Browse files Browse the repository at this point in the history
sopel: fix TODOs related to Python 2
  • Loading branch information
dgw authored Aug 3, 2022
2 parents 3afa016 + 596adc4 commit 0479737
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 52 deletions.
10 changes: 1 addition & 9 deletions sopel/modules/currency.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,7 @@ def exchange(bot, match):
LOGGER.error(err)
return

query = match.string

targets = query.split()
amount_in = targets.pop(0)
base = targets.pop(0)
targets.pop(0)

# TODO: Use this instead after dropping Python 2 support
# amount, base, _, *targets = query.split()
amount_in, base, _, *targets = match.string.split()

try:
amount = float(amount_in)
Expand Down
54 changes: 17 additions & 37 deletions sopel/plugins/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@
from __future__ import annotations

import abc
import imp
import importlib
import importlib.util
import inspect
import itertools
import os
import sys
from typing import Optional

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

try:
reload = importlib.reload
except AttributeError:
# py2: no reload function
# TODO: imp is deprecated, to be removed when py2 support is dropped
reload = imp.reload


class AbstractPluginHandler(abc.ABC):
"""Base class for plugin handlers.
Expand Down Expand Up @@ -334,7 +328,7 @@ def reload(self):
This method assumes the plugin is already loaded.
"""
self._module = reload(self._module)
self._module = importlib.reload(self._module)

def is_loaded(self):
return self._module is not None
Expand Down Expand Up @@ -435,45 +429,31 @@ def __init__(self, filename):

if good_file:
name = os.path.basename(filename)[:-3]
module_type = imp.PY_SOURCE
spec = importlib.util.spec_from_file_location(
name,
filename,
)
elif good_dir:
name = os.path.basename(filename)
module_type = imp.PKG_DIRECTORY
spec = importlib.util.spec_from_file_location(
name,
os.path.join(filename, '__init__.py'),
submodule_search_locations=filename,
)
else:
raise exceptions.PluginError('Invalid Sopel plugin: %s' % filename)

self.filename = filename
self.path = filename
self.module_type = module_type
self.module_spec = spec

super().__init__(name)

def _load(self):
# The current implementation uses `imp.load_module` to perform the
# load action, which also reloads the module. However, `imp` is
# deprecated in Python 3, so that might need to be changed when the
# support for Python 2 is dropped.
#
# However, the solution for Python 3 is non-trivial, since the
# `importlib` built-in module does not have a similar function,
# therefore requires to dive into its public internals
# (``importlib.machinery`` and ``importlib.util``).
#
# All of that is doable, but represents a lot of work. As long as
# Python 2 is supported, we can keep it for now.
#
# TODO: switch to ``importlib`` when Python2 support is dropped.
if self.module_type == imp.PY_SOURCE:
with open(self.path) as mod:
description = ('.py', 'U', self.module_type)
mod = imp.load_module(self.name, mod, self.path, description)
elif self.module_type == imp.PKG_DIRECTORY:
description = ('', '', self.module_type)
mod = imp.load_module(self.name, None, self.path, description)
else:
raise TypeError('Unsupported module type')

return mod
module = importlib.util.module_from_spec(self.module_spec)
sys.modules[self.name] = module
self.module_spec.loader.exec_module(module)
return module

def get_meta_description(self):
"""Retrieve a meta description for the plugin.
Expand Down
11 changes: 5 additions & 6 deletions sopel/tests/mocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,13 @@ class MockIRCServer:
def __init__(self, bot, join_threads=True):
self.bot = bot
self.join_threads = join_threads
# TODO: `blocking` method args below should be made kwarg-ONLY in py3

@property
def chanserv(self):
"""ChanServ's message prefix."""
return 'ChanServ!ChanServ@services.'

def channel_joined(self, channel, users=None, blocking=None):
def channel_joined(self, channel, users=None, *, blocking=None):
"""Send events as if the bot just joined a channel.
:param str channel: channel to send message for
Expand Down Expand Up @@ -195,7 +194,7 @@ def channel_joined(self, channel, users=None, blocking=None):
for t in self.bot.running_triggers:
t.join()

def mode_set(self, channel, flags, users, blocking=None):
def mode_set(self, channel, flags, users, *, blocking=None):
"""Send a MODE event for a ``channel``
:param str channel: channel receiving the MODE event
Expand Down Expand Up @@ -237,7 +236,7 @@ def mode_set(self, channel, flags, users, blocking=None):
for t in self.bot.running_triggers:
t.join()

def join(self, user, channel, blocking=None):
def join(self, user, channel, *, blocking=None):
"""Send a ``channel`` JOIN event from ``user``.
:param user: factory for the user who joins the ``channel``
Expand Down Expand Up @@ -275,7 +274,7 @@ def join(self, user, channel, blocking=None):
for t in self.bot.running_triggers:
t.join()

def say(self, user, channel, text, blocking=None):
def say(self, user, channel, text, *, blocking=None):
"""Send a ``PRIVMSG`` to ``channel`` by ``user``.
:param user: factory for the user who sends a message to ``channel``
Expand Down Expand Up @@ -314,7 +313,7 @@ def say(self, user, channel, text, blocking=None):
for t in self.bot.running_triggers:
t.join()

def pm(self, user, text, blocking=None):
def pm(self, user, text, *, blocking=None):
"""Send a ``PRIVMSG`` to the bot by a ``user``.
:param user: factory for the user object who sends a message
Expand Down

0 comments on commit 0479737

Please sign in to comment.