Python 3.9 introduced the zoneinfo module, which provides the only
feature we used pytz for (getting a datetime.tzinfo object from
an IANA timezone id); so let's use it instead of a third-party
dependency.
This commit reverts db7ef3f025
(though it keeps the year updates)
After discussion with several people, it seems better to mention
copyright owners explicitly. eg. https://reuse.software/faq/#vcs-copyright
explains the issue of using VCSs to track copyright.
As db7ef3f025 only replaced mentions
of my name with 'The Limnoria Contributors', this commit only needs
to undo that + add one person who contributed to setup.py.
nickFromHostmask now (legitimately) complains when it's getting @ or !
at the beginning of a hostmask; so we need to strip them before passing
it to nickFromHostmask.
Then re-add them before calling c.addUser, because it uses them to
sort users in the right sets (ops/halfops/voices).
Additionally, this commit replaces the hardcoded set of prefix chars
(`@%+&~!`) with the one advertised in ISUPPORT when possible.
When a driver's run() method crashes, supybot.drivers.run() marks it
as dead and sets its 'irc' attribute to None.
This would be fine for "normal" independent drivers (like Socket used
to be), because this driver would never be called again.
But now that we use select(), some other thread may hold a reference
to this driver in a select() call frame, and call the dead driver's
'_read()' method when there is data to be read from the socket.
There is already a safeguard in '_read()' in the case the socket could
be read from, but this safeguard was missing from _handleSocketError.
This caused the "live" driver's select() to crash, which propagagated
to its run(), which caused the driver to be marked as dead, etc.
Eventually, all drivers could die, and we end up with the dreadful
"Schedule is the only remaining driver, why do we continue to live?"
in an infinite loop.
* Fix joins to many channels
If you have enough channels that the 512 byte message limit on the JOIN
message is hit then limnoria was losing the channel that put it over the
limit and not including it in the next JOIN message. This resulted in
losing one channel for every JOIN message that pushed us over 512 bytes.
We fix this by generating the JOIN message immediately after resetting
the channels list to ensure we include the channel that pushed us over
the limit. Then the next time through our JOIN msg construction we'll
add subsequent channels without forgetting the one that pushed us over.
* Add test for channel join lists
This adds a test for the issue that is fixed in the previous commit. We
ensure that when JOINs are split over multiple messages we JOIN to all
channels that were part of the input list and don't forget any of them.
When the number of hostmasks exceeds 1000 (the hardcoded size of
_patternCache and _hostmaskPatternEqualCache), this triggers
a pathological case in the LRU caches, that causes all calls to be
a cache miss.
This means that on every IRC message received, ircdb.checkIgnored triggers
a recompilation of *all* user hostmasks, which is very expensive
computationally.
This commit stores them in their own cache to prevent them from
expiring.
It mistakenly used the bot's nick as target when the message is in private,
so 'more' after a private message always answered the user did not send
a command before (because said command was attributed to the bot)
This dict was filled with IrcString keys, which is hashed
as lowercase, so when queried with a non-lowercase string,
the key would not be found, and lead to very confusing errors.
If throttle time is set to 0.0 (e.g. in tests) and the reported time
since last dequeue is also 0.0 (maybe because the timer resolution is
too low), takeMsg would throttle. This would make tests fail because
they expect messages immediately.
This issue was observed on Windows 10 20H2 with both a mingw-w64 Python
v3.8.9 from MSYS2 and several version of official Python v3.x.
Confirmed at least as far back as
aa98d987a7.
Since it's a non-integer comparison, the change shouldn't have any
observable effect in normal operation.
ChannelPluginTestCase#setUp accepts the same parameters as its
super-method PluginTestCase#setUp, but it didn't pass the arguments down
the line. Now it does.
by moving the 'smart' reply() method from NestedCommandsIrcProxy
to ReplyIrcProxy.
There is no reason only commands should have a paginated output
and not snarfers defined in PluginRegexp.
1. it binds the port, which is useless while documenting
2. in some circumstances, it prevents supybot-plugin-doc from exiting
(because the server threads are still running)
It's pointless and looks stupid.
It will look even more stupid when we enable multiline, because the
suffixes will be in the middle of the concatenated message.
Otherwise, if some IP addresses don't work (eg. all odd ones), the bot will
consecutively fail because it can't connect, then connect + get STS + reconnect,
then fail again, then connect + get STS, etc.
Fixes a regression in ecc2c32950 that caused
Socket.py to ignore the IP address entirely after computing it, and
to call getSocket() and connect() with the hostname instead.
FAIL: testMoreIsCaseInsensitive (Misc.test.MiscTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File /home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/supybot/test.py, line 214, in runTest
originalRunTest()
File ./plugins/Misc/test.py, line 260, in testMoreIsCaseInsensitive
self.assertNotError('more %s' % nick.upper())
File /home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/supybot/test.py, line 355, in assertNotError
m = self._feedMsg(query, **kwargs)
File /home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/supybot/test.py, line 526, in _feedMsg
response = self.irc.takeMsg()
File /home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/supybot/log.py, line 368, in m
return f(self, *args, **kwargs)
File /home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/supybot/irclib.py, line 1308, in takeMsg
assert not msg.tagged('emulatedEcho')
AssertionError
I don't understand why it's happening or why it's only that specific test,
but there we go.
Plugins implementing inFilter do not set receivedAt, so incoming messages
rewritten by inFilter would be detected as echo messages, and ignored
by most plugins.