Skip to content

Commit

Permalink
Merge pull request #183 from HackSoc/update-python-version
Browse files Browse the repository at this point in the history
CI: add Python 3.10, drop Python 3.6, update to Ubuntu 20.04
  • Loading branch information
alanbriolat committed Feb 14, 2022
2 parents 2b2d3dd + 8079ed7 commit 1e736ff
Show file tree
Hide file tree
Showing 24 changed files with 85 additions and 162 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ on:

jobs:
tests:
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]
python-version: ["3.7", "3.8", "3.9", "3.10"]
include:
- python-version: 3.6
toxenv: py36
- python-version: 3.7
- python-version: "3.7"
toxenv: py37
- python-version: 3.8
- python-version: "3.8"
toxenv: py38
- python-version: 3.9
toxenv: py39-flake8
- python-version: "3.9"
toxenv: py39
- python-version: "3.10"
toxenv: py310-flake8
env:
PYTHON: ${{ matrix.python-version }}
steps:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.9
FROM python:3.10

ARG UID=9000
ARG GID=9000
Expand Down
1 change: 1 addition & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ testpaths = tests/
addopts = --cov=src/ --cov-report=xml -W ignore::schematics.deprecated.SchematicsDeprecationWarning
markers =
bot: mark a test as Bot-based rather than IRCClient-based
asyncio_mode = auto
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Requirements for unit testing
pytest>=5.2.2,<6.0
pytest-asyncio==0.10.0
pytest-aiohttp==0.3.0
aioresponses==0.7.2
pytest>=7.0.1,<8
pytest-asyncio==0.18.1
pytest-aiohttp==1.0.4
aioresponses==0.7.3
pytest-cov
asynctest==0.13.0
aiofastforward==0.0.24
Expand Down
4 changes: 2 additions & 2 deletions src/csbot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,8 @@ def _write(self, s, raw=False):
"""Write *s* to the current stream; if *raw* is True, don't apply comment filter."""
if not raw and self._commented:
lines = s.split("\n")
modified = [f"# {l}" if l and not l.startswith("#") else l
for l in lines]
modified = [f"# {line}" if line and not line.startswith("#") else line
for line in lines]
s = "\n".join(modified)
self._stream.write(s)
self._at_start = False
Expand Down
21 changes: 6 additions & 15 deletions src/csbot/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(self, handle_event, loop=None):
self.loop = loop

self.pending = set()
self.pending_event = asyncio.Event(loop=self.loop)
self.pending_event = asyncio.Event()
self.pending_event.clear()
self.future = None

Expand Down Expand Up @@ -116,8 +116,7 @@ def _get_pending(self):
self.pending_event.clear()
return pending

@asyncio.coroutine
def _run(self):
async def _run(self):
# Use self as context manager so an escaping exception doesn't break
# the event runner instance permanently (i.e. we clean up the future)
with self:
Expand All @@ -133,9 +132,7 @@ def _run(self):
new_pending.cancel()
break
# Run until 1 or more tasks complete (or more tasks are added)
done, not_done = yield from asyncio.wait(not_done,
loop=self.loop,
return_when=asyncio.FIRST_COMPLETED)
done, not_done = await asyncio.wait(not_done, return_when=asyncio.FIRST_COMPLETED)
# Handle exceptions raised by tasks
for f in done:
e = f.exception()
Expand Down Expand Up @@ -181,7 +178,7 @@ def __init__(self, get_handlers, loop=None):
self.loop = loop

self.events = deque()
self.new_events = asyncio.Event(loop=self.loop)
self.new_events = asyncio.Event()
self.futures = set()
self.future = None

Expand Down Expand Up @@ -239,11 +236,7 @@ def _run_handler(self, handler, event):
result = handler(event)
except Exception as e:
self._handle_exception(exception=e, csbot_event=event)
future = maybe_future(
result,
log=LOG,
loop=self.loop,
)
future = maybe_future(result, log=LOG)
if future:
future = asyncio.ensure_future(self._finish_async_handler(future, event), loop=self.loop)
return future
Expand Down Expand Up @@ -277,9 +270,7 @@ async def _run(self):
# Run until one or more futures complete (or new events are added)
new_events = self.loop.create_task(self.new_events.wait())
LOG.debug('waiting on %s futures', len(self.futures))
done, pending = await asyncio.wait(self.futures | {new_events},
loop=self.loop,
return_when=asyncio.FIRST_COMPLETED)
done, pending = await asyncio.wait(self.futures | {new_events}, return_when=asyncio.FIRST_COMPLETED)
# Remove done futures from the set of futures being waited on
done_futures = done - {new_events}
LOG.debug('%s of %s futures done', len(done_futures), len(self.futures))
Expand Down
4 changes: 2 additions & 2 deletions src/csbot/irc.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,9 @@ def __init__(self, *, loop=None, **kwargs):

self.reader, self.writer = None, None
self._exiting = False
self.connected = asyncio.Event(loop=self.loop)
self.connected = asyncio.Event()
self.connected.clear()
self.disconnected = asyncio.Event(loop=self.loop)
self.disconnected = asyncio.Event()
self.disconnected.set()
self._last_message_received = self.loop.time()
self._client_ping = None
Expand Down
6 changes: 3 additions & 3 deletions src/csbot/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ def pairwise(iterable):
return zip(a, b)


def cap_string(s, l):
def cap_string(s, n):
"""If a string is longer than a particular length,
it gets truncated and has '...' added to the end.
"""
if len(s) <= l:
if len(s) <= n:
return s

return s[0:l-3] + "..."
return s[0:n - 3] + "..."


def ordinal(value):
Expand Down
4 changes: 2 additions & 2 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ def close(self):
self._reader.feed_eof()


def paused(f, *, loop=None):
def paused(f):
"""Wrap a coroutine function so it waits until explicitly enabled.
"""
event = asyncio.Event(loop=loop)
event = asyncio.Event()
resume = event.set

async def _f(*args, **kwargs):
Expand Down
7 changes: 3 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def fast_forward(event_loop):
async def f(n):
# The wait_for() prevents forward(n) from blocking if there isn't enough async work to do
try:
await asyncio.wait_for(forward(n), n, loop=event_loop)
await asyncio.wait_for(forward(n), n)
except asyncio.TimeoutError:
pass
yield f
Expand Down Expand Up @@ -122,7 +122,7 @@ def receive(self, lines):
"""Shortcut to push a series of lines to the client."""
if isinstance(lines, str):
lines = [lines]
return [self.client.line_received(l) for l in lines]
return [self.client.line_received(line) for line in lines]

def assert_sent(self, lines):
"""Check that a list of (unicode) strings have been sent.
Expand All @@ -132,7 +132,7 @@ def assert_sent(self, lines):
"""
if isinstance(lines, str):
lines = [lines]
self.client.send_line.assert_has_calls([mock.call(l) for l in lines])
self.client.send_line.assert_has_calls([mock.call(line) for line in lines])
self.client.send_line.reset_mock()


Expand All @@ -149,7 +149,6 @@ async def run_client(event_loop, irc_client_helper):
point it should yield control to allow the client to progress.
>>> @pytest.mark.usefixtures("run_client")
... @pytest.mark.asyncio
... async def test_something(irc_client_helper):
... await irc_client_helper.receive_bytes(b":nick!user@host PRIVMSG #channel :hello\r\n")
... irc_client_helper.assert_sent('PRIVMSG #channel :what do you mean, hello?')
Expand Down
10 changes: 2 additions & 8 deletions tests/test_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ def quit(self, event):

pytestmark = pytest.mark.bot(plugins=[MockPlugin], config=CONFIG)

@pytest.mark.asyncio
async def test_hooks(self, bot_helper):
"""Check that hooks fire in the expected way."""
bot = bot_helper.bot
Expand Down Expand Up @@ -136,7 +135,6 @@ async def test_hooks(self, bot_helper):
mock.call('test3', {}),
]

@pytest.mark.asyncio
@pytest.mark.parametrize('n', list(range(1, 10)))
async def test_burst_in_order(self, bot_helper, n):
"""Check that a plugin always gets messages in receive order."""
Expand All @@ -146,7 +144,6 @@ async def test_burst_in_order(self, bot_helper, n):
await asyncio.wait(bot_helper.receive(messages))
assert plugin.handler_mock.mock_calls == [mock.call('quit', user) for user in users]

@pytest.mark.asyncio
async def test_non_blocking(self, bot_helper):
"""Check that long-running hooks don't block other events from being processed."""
plugin = bot_helper['mockplugin']
Expand Down Expand Up @@ -188,14 +185,13 @@ def command_b(self, *args, **kwargs):
def command_cd(self, *args, **kwargs):
self.handler_mock(inspect.currentframe().f_code.co_name)

CONFIG_A = f"""\
CONFIG_A = """\
["@bot"]
command_prefix = "&"
plugins = ["mockplugin1"]
"""

@pytest.mark.bot(plugins=[MockPlugin1], config=CONFIG_A)
@pytest.mark.asyncio
async def test_command_help(self, bot_helper):
"""Check that commands fire in the expected way."""
await asyncio.wait(bot_helper.receive([':nick!user@host PRIVMSG #channel :&plugins']))
Expand All @@ -214,7 +210,6 @@ async def test_command_help(self, bot_helper):
bot_helper.assert_sent('NOTICE #channel :This command has help')

@pytest.mark.bot(plugins=[MockPlugin1], config=CONFIG_A)
@pytest.mark.asyncio
async def test_command_fired(self, bot_helper):
"""Check that commands fire in the expected way."""
plugin = bot_helper['mockplugin1']
Expand Down Expand Up @@ -248,14 +243,13 @@ def __init__(self, *args, **kwargs):
def command_a(self, *args, **kwargs):
self.handler_mock(inspect.currentframe().f_code.co_name)

CONFIG_B = f"""\
CONFIG_B = """\
["@bot"]
command_prefix = "&"
plugins = ["mockplugin1", "mockplugin2"]
"""

@pytest.mark.bot(plugins=[MockPlugin1, MockPlugin2], config=CONFIG_B)
@pytest.mark.asyncio
async def test_command_single_handler(self, caplog, bot_helper):
count = 0
for r in caplog.get_records("setup"):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ def _test_config_generator_list_wrap():
class Config(config.Config):
a = config.option_list(str, default=["abcdefghijklmnopqrstuvwxyz" for _ in range(2)], help="")
b = config.option_list(str, default=["abcdefghijklmnopqrstuvwxyz" for _ in range(5)], help="")
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz = config.option_list(str, help="")
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz = config.option_list(str, help="") # noqa: E501

return Config, [
# Shorter than threshold, don't split
Expand All @@ -763,7 +763,7 @@ class Config(config.Config):
' "abcdefghijklmnopqrstuvwxyz",',
']',
# Key longer than threshold, but no items, don't split
'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz = []',
'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz = []', # noqa: E501
]


Expand Down

0 comments on commit 1e736ff

Please sign in to comment.