8.0.0
Re-published due to broken automation. Do not adjust your television set; there is no cause for alarm.
Changes between 7.1.9 and 8.0.0
Highlights
Detailed coverage of the major changes can be found in the dedicated
Sopel 8 upgrade guide.
For users:
- Python 3.8+ is now required
- IRC connections are made with TLS on port 6697 if not configured
- SASL EXTERNAL authentication is now supported
- Plugins in
~/.sopel/modulesare no longer loaded by default- Use the
core.extrasetting to add this directory back if needed
- Use the
- Database options can be configured all at once in new
db_urlsetting (useful
for managed cloud hosting such as Heroku) .blockscommand accepts "nick" and "host" types now, and no longer lies
about supporting "hostmasks" (further improvements to come)- Sopel no longer supports loading (very!) old Phenny/Jenni plugins
- Several built-in plugins have been converted to external packages, to simplify
maintenance and release-management going forward
For developers:
Identifierwas moved tosopel.tools.identifiersand now supports dynamic
casemapping; an optionalcasemappingoridentifier_factorykwarg has been
added to many object types to help manage this at runtime- You can usually just pass
bot.make_identifieras the factory function and
things will Just Work™ - Feel free to use
bot.make_identifier()yourself to get anIdentifier
representing any nick or channel name you get, e.g. as input to a command
- You can usually just pass
- The
core.nicksetting value is now returned as astr, not anIdentifier - Capability negotiation is a first-class plugin API feature (see
plugin.capabilityand the related documentation chapter) trigger.senderattribute as passed to plugin callables is nowNonein
cases where its value is meaningless (events with no channel/query context)- Numerous deprecated API features were removed:
bot.privileges(usebot.channels)bot.msg()(usebot.say())sopel.websubmodule (usesopel.tools.web)
- Messages from other bots are ignored by default on supported networks, but
plugins can opt back in with the@plugin.allow_botsdecorator STATUSMSGprefix is removed fromtrigger.senderif present and stored in a
separatetrigger.status_prefixattribute- See documentation for
bot.SopelWrapper.default_destination
- See documentation for
bot.connection_registeredis now the way to check whether the bot is
connected to IRC, registered with the network, and ready for your plugin to
send commands
Plugin changes
- admin:
- Added
.rawcommand to make Sopel send a raw IRC line [#2104]
- Added
- adminchannel:
- bugzilla:
- Extracted to its own package [#2481]
- calc:
- clock:
- Added
unsetcommands for user & channel time zone/format [#2181]
- Added
- coretasks:
- currency:
- dice:
- Refactoring, bugfixes, and improved test coverage [#2532]
- emoticons:
- find:
- help:
- Now updatable independently from its own package, but still
installs with Sopel as a dependency [#2332]
- Now updatable independently from its own package, but still
- ip:
- Miscellaneous code-style improvements [#2393]
- Extracted to its own package [#2523]
- meetbot:
- Extracted to its own package [#2477]
- pronouns:
- Accept abbreviated pronoun sets [#2070]
- Added
.clearpronounscommand [#2154] - Fetch pronoun list dynamically at startup [#2130]
- Support configurable pronoun backend [#2437, #2438]
- The old backend at
pronoun.iswent down and never came back, so now you
can use our replacement or host your own
- The old backend at
- py:
- Extracted to its own package [#2411, #2415]
- reddit:
- Newer
prawlibrary allowed [#2319] - Added configuration setting to turn off inline slash-references [#2418]
- Extracted to its own package [#2444]
- Newer
- reload:
- remind:
- Avoid trying to use IRC connection if it's not ready [#2351, #2374]
- Extracted to its own package [#2478]
- safety:
- search:
- seen:
- tell:
- Fixed edge cases in cleanup of tellee argument [#2584]
- translate:
- Improved help output [#2453]
- unicode_info:
- url:
- Improved interaction between
.titlecommand and link handlers [#2282] - Removed traceback from debug log when URL fetch fails [#2280]
- Made channel-privilege-based access to
.urlexcludecommand and friends
configurable [#2352] - Cleaned up code [#2304, #2307, #2433]
- Added better error handling for DNS lookups [#2428]
- Ignore invalid hostnames [#2472]
- Improved interaction between
- version:
- Support retrieving plugin versions with
.version pluginname[#2133]
- Support retrieving plugin versions with
- wikipedia:
- Commands are now
.wp,.wikipedia; old commands (.w,.wik, &.wiki)
were removed [#1966] - Remove deprecated
lang_per_channelsetting [#2142] - Work around excessive whitespace in math formulas [#2286]
- Don't ping the user who posted a URL that fails to load [#2315]
- Output image description if URL has an image viewer fragment [#2388]
- Handle query strings in article links [#2414]
- Fail gracefully on
Special:namespace links [#2575]
- Commands are now
- xkcd:
Core changes
- Removed support for EOL Python versions (2.7, 3.3, 3.4, 3.5, 3.6, & 3.7),
added testing on newer Python versions (up to 3.12), and modernized coding
standards [#2062, #2073, #2123, #2124, #2134, #2136,
#2138, #2205, #2213, #2227, #2298, #2326, #2327,
#2342, #2384, #2464, #2500, #2516] - Modified default settings:
- IRC backend refactored to use
asyncio[#2256]- Just in time, too: The
asynchatmodule was removed in Python 3.12
- Just in time, too: The
- Improved IRC connection error handling [#2430, #2431]
SopelDBadapted to SQLAlchemy 2.x style [#2243]- Database can be configured all at once with a new
db_urlsetting [#2087] - Replaced
pkg_resourceswithimportlib.metadata[#2261, #2268] - Added support for several new IRC features and IRCv3 specifications:
- Improved SASL handling when auth fails [#2187, #2191]
- Added automatic
CASEMAPPINGhandling based onRPL_ISUPPORT[#2231] - Plugins in
~/.sopel/modulesare no longer loaded by default [#2119] - Removed support for Phenny/Jenni plugin style [#2126]
- Ignore
bot-tagged messages by default [#2089, #2272] - Privilege tracking (MODE event handling) refactored [#2131]
- Maintain ordering of
ISupport.PREFIXproperty [#2200] - Added
__slots__toChannelandUserobjects [#2233] - Improved handling of the bot's nick getting changed [#2240]
- Improved tracking and enforcement of rate limits [#2297]
- Prevent infinite loop on connection failure [#2306]
- Added
ssl_ciphersandssl_minimum_versionsettings [#2246, #2306] - Added
antiloop_repeat_text,antiloop_silent_after,antiloop_threshold,
andantiloop_windowsettings to control command-loop prevention [#2320] - Using
,inListAttributevalues logs a warning [#2252]- Write lists with newlines instead; Sopel 9 will remove splitting on
,
- Write lists with newlines instead; Sopel 9 will remove splitting on
- IRC connections use TLS on port 6697 by default [#2277]
- Potentially a breaking change, but the configuration wizard has long
written these settings to the final config file even if they were left at
the default values
- Potentially a breaking change, but the configuration wizard has long
- Fixed
UHNAMESrace condition caused by joining channels too soon [#2321] - Removed hunting for CA root store [#2278, #2303]
- Sopel will simply use the system TLS library's default trust store unless
theca_certssetting is specified
- Sopel will simply use the system TLS library's default trust store unless
- Improved truncation/splitting of over-length messages in e.g.
bot.say()
[#2310, #2450] - Gracefully handle missing
userhost-in-namesdata, e.g. with ZNC [#2312]- See ZNC issue #1224
- Override
get_version()method forEntryPointPlugin[#2313] - Take advantage of
LINELENtoken if advertised in ISUPPORT [#2346] - Unescape ISUPPORT parameter values [#2429]
- Keep track of user realnames via WHO/WHOX [#2383, #2396]
- Raise error on receiving non-UTF-8 data if server advertises
UTF8ONLY
[#2365, #2369, #2372] - Make all arguments
safe()when preparing IRC commands [#2368] - Ignore disabling
coretaskshandlers in per-channel settings [#2400] - Add guardrails to channel logging [#2419]
- Default is now always WARNING, regardless of file logging level
- DEBUG level is no longer available for channel logs; it is far too noisy
- Handle
core.modessetting beingNone[#2510] - Handle broken symlinks to plugin files [#2545]
- Fixed auto-saving changes to Sopel's ignore list with
.blocks[#2550]
API changes
- Importing
sopel.modulenow emits a deprecation warning [#2170] - Removed support for Phenny/Jenni plugin style [#2126]
- Stopped searching
bot.memory['url_callbacks']for link handlers [#2121] - Deprecated
bot.search_url_callbacks()[#2121, #2156, #2581] - Deprecated
db.execute()[#2243] - Cleaned up parts of
sopel.toolsnamespace- Deprecated
tools.web.entity()and itsr_entityconstant, to be removed
in Sopel 9.0 [#2205] - Deprecated the
iteritems,iterkeys,itervalues, andraw_input
2to3-style shims, to be removed in Sopel 8.1 [#2228] - Moved
Identifierto its own submodule,tools.identifiers[#2231]tools.Identifierremains for now as a compatibility shortcut
- Moved
check_pid()andstderr()functions tocli.utils[#2385] - Deprecated
tools.OutputRedirectclass left over from the days before
modern logging, to be removed in Sopel 8.1 [#2385]
- Deprecated
- Moved channel privilege constants into their own
sopel.privilegessubmodule
[#2179, #2352, #2540]- The new
sopel.privileges.AccessLeveltype encapsulates all levels in a
single object, which can support dynamic features in the future - The original, individual constants in
sopel.pluginare still available for
now, mapped to their correspondingAccessLevelvalues
- The new
- Sopel's API now uses enumerated types where suitable:
bot-tagged messages are ignored by default [#2089]trigger.timeis offset-aware [#2099]tools.timeimprovements & changes:- Added
plugin.allow_botsdecorator [#2244] - Added more rate-limit controls [#2290, #2434]
- New
messagekeyword-only argument toplugin.ratedecorator, an optional
string sent via NOTICE when a command is rate-limited - New
plugin.rate_user,plugin.rate_channel, andplugin.rate_global
decorators provide simpler control over a single rate-limit type, with the
rateandmessage(optional) as positional parameters - Messages support various placeholders that will be replaced with runtime
data about the triggering user, the rate limit in effect, and the
plugin/command that was limited; seeplugin.rate
decorator documentation for details
- New
- Added
bot.safe_text_length()method [#2136] - Added
RPL_WHOISBOTtotools.eventslist [#2145] - Added
bot.pluginsproperty [#2199] - Added
db.forget_channel()anddb.forget_plugin()methods [#2224] - Renamed
db.delete_nick_group()todb.forget_nick_group()[#2224] - Added CASEMAPPING support to
Identifier[#2231]- Static
Identifier._lower()method now obeys RFC 1459 casing rules Identifierconstructor now takes optionalcasemappingandchantypes
kwargs; see documentation for details, or use thebot.make_identifier()
helper method to automatically use the bot's knowledge about the current
server's configuration
- Static
- Added CHANTYPES support to
Identifier[#2236] - Added
bot.make_identifier_memory()helper to easily take advantage of the
bot's CASEMAPPING and CHANTYPES knowledge [#2552] - Changed reading
core.nickfrom the bot's settings to return astrinstead
ofIdentifier[#2231]- Depending on what your plugin does, you might need to use the result of
bot.make_identifier(bot.settings.core.nick)instead of the raw value
- Depending on what your plugin does, you might need to use the result of
- Moved memory classes to
sopel.tools.memories[#2237] - Moved
deprecated()fromsopel.toolstosopel.lifecycle[#2232] db.get_nick_id()no longer creates a new nick ID by default [#2234]- Standardized on
ctcpinstead ofintent[#2253]- The old
module.intent()decorator was deprecated in Sopel 7.1; use the
plugin.ctcp()decorator instead - Sopel 8.0 removes
intentfromtrigger.tags; usetrigger.ctcpinstead
- The old
- Updated invite-related event names in
tools.events[#2270] - Fixed checking if
Noneexists in aSopelIdentifierMemory[#2306] - Fixed and tested
SopelIdentifierMemoryinteractions with plainer-vanilla
dictionary types [#2525] - Reworked capability negotiation [#2341]
- See Managing Capability Negotiation documentation chapter
- This replaces the
irc.utils.CapReqinterface, which is now deprecated
- Changed
trigger.senderproperty to beNonefor events not associated with
a channel or query [#2359] - Fixed
trigger.texterroneously containing command name for events with empty
args[#2360] - Removed
STATUSMSGprefix fromtrigger.sender[#2370, #2441]- Status prefix is now stored in a new
trigger.status_prefixattribute - The
botpassed to plugin callables will use thestatus_prefixand
senderattributes to build itsdefault_destination, meaning no change to
plugins' most common usages ofbot.say(),bot.reply(), etc.
- Status prefix is now stored in a new
- Fixed
formatting.colorresult when passing0asfgorbg[[#2366][]] config.types.FilenameAttributestrips quotes from its value [#2371]- Made
bot.connection_registeredmore robust [#2375, #2406, #2410] - The bot initializes with an
UninitializedBackendinstead ofNone, to
intercept actions that don't work prior to connecting [#2394]- Prohibited actions raise
RuntimeErrorinstead of falling through to a more
esoteric error type or—worse—silently failing
- Prohibited actions raise
- Added
realname&is_botfields toUserobjects [#2383, #2448] - Use of
plugin.require_privilege()orplugin.require_bot_privilege()
decorators now impliesrequire_chanmsg()[#2405, #2580] - Fixed an inconsistency between behavior and documentation for
tools.calculation.pow_complexity()[#2543] - Soft-deprecated
SopelWrappertype [#2521]- Long-term, we will phase out this subclass in favor of using
contextvars;
see #2460 for the full timeline
- Long-term, we will phase out this subclass in favor of using
- Moved
sopel.pluginstosopel.builtins[#2504]- We don't technically consider these to be part of the API, but if this
isn't mentioned we just know someone will complain that the move broke
some custom plugin code
- We don't technically consider these to be part of the API, but if this
- Removed previously-deprecated API features [#2128, #2129, #2141,
#2144, #2146, #2147, #2148, #2150, #2329]
Housekeeping changes
- Many, many additions & improvements to documentation [#1990, #2169,
#2178, #2182, #2226, #2238, #2239, #2257, #2275,
#2276, #2323, #2379, #2386, #2409, #2424, #2426,
#2442, #2489, #2494, #2495, #2496, #2533, #2539,
#2543, #2550, #2558, #2574, #2600, #2606] - Switched from Travis CI to GitHub Actions and incrementally improved tests
[#2075, #2078, #2123, #2188, #2262, #2335, #2342,
#2381, #2452, #2453, #2458, #2505, #2519, #2543] - Improved tooling for contributors, e.g.
Makefiletargets [#2502] - Modernized packaging [#2328]
- Cleanup on aisle
contrib/[#2085, #2520] - Cleanup of deprecated feature usage in core & built-in plugins [#2117,
#2464, #2468, #2470] - Import reorganization [#2179]
- Various code smell/style issues fixed [#2186, #2220, #2231,
#2382, #2393, #2514] - Various logging improvements [#2309, #2354, #2473, #2569]
- Deprecation warnings for the corresponding stable release now begin to emit
logs in prerelease versions [#2522] - Removed legacy CLI run mode [#2118]
- Removed obsolete, nonfunctional CLI argument
--quiet[#2404] - Removed old
sopel.test_tools[#2139, #2177] - Raw logs improved both output and decode failure handling [#2095]
- Started our journey into the wonderful world of type checking [#2185,
#2462, #2471, #2480, #2491, #2535, #2555]- Many many PRs added or updated type hints in the course of adding/fixing
something else, so we won't also list all of them here
- Many many PRs added or updated type hints in the course of adding/fixing