Sopel

Latest version: v8.0.0

Safety actively analyzes 635588 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 11

8.0.0

===============================

Highlights
----------

Detailed coverage of the major changes can be found in the dedicated
[Sopel 8 upgrade guide][sopel-8-migration].

**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/modules` are no longer loaded by default
* Use the `core.extra` setting to add this directory back if needed
* Database options can be configured all at once in new `db_url` setting (useful
for managed cloud hosting such as Heroku)
* `.blocks` command 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:**

* `Identifier` was moved to `sopel.tools.identifiers` and now supports dynamic
casemapping; an optional `casemapping` or `identifier_factory` kwarg has been
added to many object types to help manage this at runtime
* You can usually just pass `bot.make_identifier` as the factory function and
things will Just Work™
* Feel free to use `bot.make_identifier()` yourself to get an `Identifier`
representing any nick or channel name you get, e.g. as input to a command
* The `core.nick` setting value is now returned as a `str`, not an `Identifier`
* Capability negotiation is a first-class plugin API feature (see
`plugin.capability` and the [related documentation chapter][cap-mgmt-8])
* `trigger.sender` attribute as passed to plugin callables is now `None` in
cases where its value is meaningless (events with no channel/query context)
* Numerous deprecated API features were removed:
* `bot.privileges` (use `bot.channels`)
* `bot.msg()` (use `bot.say()`)
* `sopel.web` submodule (use `sopel.tools.web`)
* Messages from other bots are ignored by default on supported networks, but
plugins can opt back in with the `plugin.allow_bots` decorator
* `STATUSMSG` prefix is removed from `trigger.sender` if present and stored in a
separate `trigger.status_prefix` attribute
* See documentation for `bot.SopelWrapper.default_destination`
* `bot.connection_registered` is 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 `.raw` command to make Sopel send a raw IRC line [[2104][]]
* adminchannel:
* Refactored hostmask handling & added code comments/tests [[2222][]]
* Improved result of trying to kick the bot with `.kick` [[2240][]]
* Unified topic-mask management under `.tmask` with subcommands [[2601][]]
* bugzilla:
* Extracted to [its own package][sopel-bugzilla] [[2481][]]
* calc:
* Improved error handling [[2507][]]
* Improved help output & test coverage [[2530][]]
* clock:
* Added `unset` commands for user & channel time zone/format [[2181][]]
* coretasks:
* Replaced "hostmask" type with "host" in `.blocks` command [[2344][]]
* Real "hostmask" support is planned; see [1355][]
* Improved help output for `.blocks` [[2345][]]
* currency:
* Added `.currencies` command to list known currency symbols [[2439][]]
* `fiat_provider` setting takes precedence over the existence of a
`fixer_io_key` value [[2330][]]
* Switched from `exchangerate.host` to `open.er-api.com` [[2512][]]
* dice:
* Refactoring, bugfixes, and improved test coverage [[2532][]]
* emoticons:
* Added `.tback` alias for `.unflip` command [[2287][]]
* Made `.unflip` table more closely match the `.tflip` one [[2287][]]
* find:
* Fixed use of flags when `|` is used as input separator [[2447][]]
* Code cleanup [[2267][]]
* help:
* Now updatable independently from [its own package][sopel-help], but still
installs with Sopel as a dependency [[2332][]]
* ip:
* Miscellaneous code-style improvements [[2393][]]
* Extracted to [its own package][sopel-iplookup] [[2523][]]
* meetbot:
* Extracted to [its own package][sopel-meetbot] [[2477][]]
* pronouns:
* Accept abbreviated pronoun sets [[2070][]]
* Added `.clearpronouns` command [[2154][]]
* Fetch pronoun list dynamically at startup [[2130][]]
* Support configurable pronoun backend [[2437][], [2438][]]
* The old backend at `pronoun.is` went down and never came back, so now you
can use [our replacement][pronoun-ours] or [host your own][pronoun-base]
* py:
* Extracted to [its own package][sopel-py] [[2411][], [2415][]]
* reddit:
* Newer `praw` library allowed [[2319][]]
* Added configuration setting to turn off inline slash-references [[2418][]]
* Extracted to [its own package][sopel-reddit] [[2444][]]
* reload:
* Remove unsupported `.update` command [[2416][]]
* Improve plugin help strings [[2417][]]
* remind:
* Avoid trying to use IRC connection if it's not ready [[2351][], [2374][]]
* Extracted to [its own package][sopel-remind] [[2478][]]
* safety:
* Comprehensive rework improving caching, output, etc. [[2279][]]
* Ignore invalid hostnames [[2472][]]
* search:
* Fix `.suggest` when there is only one result [[2513][]]
* Code style and dependency updates [[2260][], [2334][], [2420][]]
* seen:
* Adapted to aware `trigger.time` [[2265][]]
* Prevent error spam if database is temporarily inaccessible [[2338][]]
* tell:
* Fixed edge cases in cleanup of tellee argument [[2584][]]
* translate:
* Improved help output [[2453][]]
* unicode_info:
* Uses `unicodedata2` if available [[2349][], [2361][]]
* url:
* Improved interaction between `.title` command and link handlers [[2282][]]
* Removed traceback from debug log when URL fetch fails [[2280][]]
* Made channel-privilege-based access to `.urlexclude` command and friends
configurable [[2352][]]
* Cleaned up code [[2304][], [2307][], [2433][]]
* Added better error handling for DNS lookups [[2428][]]
* Ignore invalid hostnames [[2472][]]
* version:
* Support retrieving plugin versions with `.version pluginname` [[2133][]]
* wikipedia:
* Commands are now `.wp`, `.wikipedia`; old commands (`.w`, `.wik`, & `.wiki`)
were removed [[1966][]]
* Remove deprecated `lang_per_channel` setting [[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][]]
* xkcd:
* Switched keyword-search backend [[2376][], [2377][]]

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:
* Removed default `B` mode from `core.modes` [[2448][]]
* Added space before timezone in `default_time_format` [[2531][]]
* IRC backend refactored to use `asyncio` [[2256][]]
* Just in time, too: The `asynchat` module was removed in Python 3.12
* Improved IRC connection error handling [[2430][], [2431][]]
* `SopelDB` adapted to SQLAlchemy 2.x style [[2243][]]
* Database can be configured all at once with a new `db_url` setting [[2087][]]
* Replaced `pkg_resources` with `importlib.metadata` [[2261][], [2268][]]
* Added support for several new IRC features and IRCv3 specifications:
* SASL EXTERNAL client certificate authentication [[2100][], [2561][]]
* Sopel uses [the Bot Mode specification][bot-mode-spec] to mark itself as a
bot and track other users that are flagged as bots [[2088][], [2448][]]
* `userhost-in-names` capability and the legacy `UHNAMES` feature [[2102][]]
* `chghost` capability [[2116][]]
* Improved SASL handling when auth fails [[2187][], [2191][]]
* Added automatic `CASEMAPPING` handling based on `RPL_ISUPPORT` [[2231][]]
* Plugins in `~/.sopel/modules` are 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.PREFIX` property [[2200][]]
* Added `__slots__` to `Channel` and `User` objects [[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_ciphers` and `ssl_minimum_version` settings [[2246][], [2306][]]
* Added `antiloop_repeat_text`, `antiloop_silent_after`, `antiloop_threshold`,
and `antiloop_window` settings to control command-loop prevention [[2320][]]
* Using `,` in `ListAttribute` values logs a warning [[2252][]]
* 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
* Fixed `UHNAMES` race 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
the `ca_certs` setting is specified
* Improved truncation/splitting of over-length messages in e.g. `bot.say()`
[[2310][], [2450][]]
* Gracefully handle missing `userhost-in-names` data, e.g. with ZNC [[2312][]]
* See [ZNC issue 1224][znc/znc1224]
* Override `get_version()` method for `EntryPointPlugin` [[2313][]]
* Take advantage of `LINELEN` token 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 `coretasks` handlers 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.modes` setting being `None` [[2510][]]
* Handle broken symlinks to plugin files [[2545][]]
* Fixed auto-saving changes to Sopel's ignore list with `.blocks` [[2550][]]

API changes
-----------

* Importing `sopel.module` now 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.tools` namespace
* Deprecated `tools.web.entity()` and its `r_entity` constant, to be removed
in Sopel 9.0 [[2205][]]
* Deprecated the `iteritems`, `iterkeys`, `itervalues`, and `raw_input`
2to3-style shims, to be removed in Sopel 8.1 [[2228][]]
* Moved `Identifier` to its own submodule, `tools.identifiers` [[2231][]]
* `tools.Identifier` remains for now as a compatibility shortcut
* Moved `check_pid()` and `stderr()` functions to `cli.utils` [[2385][]]
* Deprecated `tools.OutputRedirect` class left over from the days before
modern logging, to be removed in Sopel 8.1 [[2385][]]
* Moved channel privilege constants into their own `sopel.privileges` submodule
[[2179][], [2352][], [2540][]]
* The new `sopel.privileges.AccessLevel` type encapsulates all levels in a
single object, which can support dynamic features in the future
* The original, individual constants in `sopel.plugin` are still available for
now, mapped to their corresponding `AccessLevel` values
* Sopel's API now uses enumerated types where suitable:
* `formatting.colors` [[2122][]]
* `privileges.AccessLevel` [[2540][]]
* `tools.events` [[2127][]]
* `bot`-tagged messages are ignored by default [[2089][]]
* `trigger.time` is offset-aware [[2099][]]
* `tools.time` improvements & changes:
* `format_time()` accepts offset-aware `datetime` values [[2132][]]
* `seconds_to_split()` returns a `Duration` named tuple [[2446][]]
* `validate_timezone()` now raises `ValueError` for `None` [[2446][]]
* Added `plugin.allow_bots` decorator [[2244][]]
* Added more rate-limit controls [[2290][], [2434][]]
* New `message` keyword-only argument to `plugin.rate` decorator, an optional
string sent via NOTICE when a command is rate-limited
* New `plugin.rate_user`, `plugin.rate_channel`, and `plugin.rate_global`
decorators provide simpler control over a single rate-limit type, with the
`rate` and `message` (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; see [`plugin.rate`][rate-decorator]
decorator documentation for details
* Added `bot.safe_text_length()` method [[2136][]]
* Added `RPL_WHOISBOT` to `tools.events` list [[2145][]]
* Added `bot.plugins` property [[2199][]]
* Added `db.forget_channel()` and `db.forget_plugin()` methods [[2224][]]
* Renamed `db.delete_nick_group()` to `db.forget_nick_group()` [[2224][]]
* Added CASEMAPPING support to `Identifier` [[2231][]]
* Static `Identifier._lower()` method now obeys RFC 1459 casing rules
* `Identifier` constructor now takes optional `casemapping` and `chantypes`
kwargs; see documentation for details, or use the `bot.make_identifier()`
helper method to automatically use the bot's knowledge about the current
server's configuration
* 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.nick` from the bot's settings to return a `str` instead
of `Identifier` [[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
* Moved memory classes to `sopel.tools.memories` [[2237][]]
* Moved `deprecated()` from `sopel.tools` to `sopel.lifecycle` [[2232][]]
* `db.get_nick_id()` no longer creates a new nick ID by default [[2234][]]
* Standardized on `ctcp` instead of `intent` [[2253][]]
* The old `module.intent()` decorator was deprecated in Sopel 7.1; use the
`plugin.ctcp()` decorator instead
* Sopel 8.0 removes `intent` from `trigger.tags`; use `trigger.ctcp` instead
* Updated invite-related event names in `tools.events` [[2270][]]
* Fixed checking if `None` exists in a `SopelIdentifierMemory` [[2306][]]
* Fixed and tested `SopelIdentifierMemory` interactions with plainer-vanilla
dictionary types [[2525][]]
* Reworked capability negotiation [[2341][]]
* See [Managing Capability Negotiation][cap-mgmt-8] documentation chapter
* This replaces the `irc.utils.CapReq` interface, which is now deprecated
* Changed `trigger.sender` property to be `None` for events not associated with
a channel or query [[2359][]]
* Fixed `trigger.text` erroneously containing command name for events with empty
`args` [[2360][]]
* Removed `STATUSMSG` prefix from `trigger.sender` [[2370][], [2441][]]
* Status prefix is now stored in a new `trigger.status_prefix` attribute
* The `bot` passed to plugin callables will use the `status_prefix` and
`sender` attributes to build its `default_destination`, meaning no change to
plugins' most common usages of `bot.say()`, `bot.reply()`, etc.
* Fixed `formatting.color` result when passing `0` as `fg` or `bg` [[2366][]]
* `config.types.FilenameAttribute` strips quotes from its value [[2371][]]
* Made `bot.connection_registered` more robust [[2375][], [2406][], [2410][]]
* The bot initializes with an `UninitializedBackend` instead of `None`, to
intercept actions that don't work prior to connecting [[2394][]]
* Prohibited actions raise `RuntimeError` instead of falling through to a more
esoteric error type or—worse—silently failing
* Added `realname` & `is_bot` fields to `User` objects [[2383][], [2448][]]
* Use of `plugin.require_privilege()` or `plugin.require_bot_privilege()`
decorators now implies `require_chanmsg()` [[2405][], [2580][]]
* Fixed an inconsistency between behavior and documentation for
`tools.calculation.pow_complexity()` [[2543][]]
* Soft-deprecated `SopelWrapper` type [[2521]]
* Long-term, we will phase out this subclass in favor of using `contextvars`;
see [2460][] for the full timeline
* Moved `sopel.plugins` to `sopel.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
* 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. `Makefile` targets [[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

[bot-mode-spec]: https://ircv3.net/specs/extensions/bot-mode
[cap-mgmt-8]: https://sopel.chat/docs/plugin/advanced#managing-capability-negotiation
[pronoun-base]: https://github.com/lucasew/svelte-pronounisland
[pronoun-ours]: https://github.com/sopel-irc/pronoun-service
[rate-decorator]: https://sopel.chat/docs/plugin/decorators#sopel.plugin.rate
[sopel-8-migration]: https://sopel.chat/usage/installing/upgrading-to-sopel-8/
[sopel-bugzilla]: https://pypi.org/project/sopel-bugzilla/
[sopel-help]: https://pypi.org/project/sopel-help/
[sopel-iplookup]: https://pypi.org/project/sopel-iplookup/
[sopel-meetbot]: https://pypi.org/project/sopel-meetbot/
[sopel-py]: https://pypi.org/project/sopel-py/
[sopel-reddit]: https://pypi.org/project/sopel-reddit/
[sopel-remind]: https://pypi.org/project/sopel-remind/
[znc/znc1224]: https://github.com/znc/znc/issues/1224

[1355]: https://github.com/sopel-irc/sopel/issues/1355
[1966]: https://github.com/sopel-irc/sopel/pull/1966
[1990]: https://github.com/sopel-irc/sopel/pull/1990
[2062]: https://github.com/sopel-irc/sopel/pull/2062
[2070]: https://github.com/sopel-irc/sopel/pull/2070
[2073]: https://github.com/sopel-irc/sopel/pull/2073
[2075]: https://github.com/sopel-irc/sopel/pull/2075
[2078]: https://github.com/sopel-irc/sopel/pull/2078
[2085]: https://github.com/sopel-irc/sopel/pull/2085
[2087]: https://github.com/sopel-irc/sopel/pull/2087
[2088]: https://github.com/sopel-irc/sopel/pull/2088
[2089]: https://github.com/sopel-irc/sopel/pull/2089
[2095]: https://github.com/sopel-irc/sopel/pull/2095
[2099]: https://github.com/sopel-irc/sopel/pull/2099
[2100]: https://github.com/sopel-irc/sopel/pull/2100
[2102]: https://github.com/sopel-irc/sopel/pull/2102
[2104]: https://github.com/sopel-irc/sopel/pull/2104
[2116]: https://github.com/sopel-irc/sopel/pull/2116
[2117]: https://github.com/sopel-irc/sopel/pull/2117
[2118]: https://github.com/sopel-irc/sopel/pull/2118
[2119]: https://github.com/sopel-irc/sopel/pull/2119
[2121]: https://github.com/sopel-irc/sopel/pull/2121
[2122]: https://github.com/sopel-irc/sopel/pull/2122
[2123]: https://github.com/sopel-irc/sopel/pull/2123
[2124]: https://github.com/sopel-irc/sopel/pull/2124
[2126]: https://github.com/sopel-irc/sopel/pull/2126
[2127]: https://github.com/sopel-irc/sopel/pull/2127
[2128]: https://github.com/sopel-irc/sopel/pull/2128
[2129]: https://github.com/sopel-irc/sopel/pull/2129
[2130]: https://github.com/sopel-irc/sopel/pull/2130
[2131]: https://github.com/sopel-irc/sopel/pull/2131
[2132]: https://github.com/sopel-irc/sopel/pull/2132
[2133]: https://github.com/sopel-irc/sopel/pull/2133
[2134]: https://github.com/sopel-irc/sopel/pull/2134
[2136]: https://github.com/sopel-irc/sopel/pull/2136
[2138]: https://github.com/sopel-irc/sopel/pull/2138
[2139]: https://github.com/sopel-irc/sopel/pull/2139
[2141]: https://github.com/sopel-irc/sopel/pull/2141
[2142]: https://github.com/sopel-irc/sopel/pull/2142
[2144]: https://github.com/sopel-irc/sopel/pull/2144
[2145]: https://github.com/sopel-irc/sopel/pull/2145
[2146]: https://github.com/sopel-irc/sopel/pull/2146
[2147]: https://github.com/sopel-irc/sopel/pull/2147
[2148]: https://github.com/sopel-irc/sopel/pull/2148
[2150]: https://github.com/sopel-irc/sopel/pull/2150
[2154]: https://github.com/sopel-irc/sopel/pull/2154
[2156]: https://github.com/sopel-irc/sopel/pull/2156
[2169]: https://github.com/sopel-irc/sopel/pull/2169
[2170]: https://github.com/sopel-irc/sopel/pull/2170
[2177]: https://github.com/sopel-irc/sopel/pull/2177
[2178]: https://github.com/sopel-irc/sopel/pull/2178
[2179]: https://github.com/sopel-irc/sopel/pull/2179
[2181]: https://github.com/sopel-irc/sopel/pull/2181
[2182]: https://github.com/sopel-irc/sopel/pull/2182
[2185]: https://github.com/sopel-irc/sopel/pull/2185
[2186]: https://github.com/sopel-irc/sopel/pull/2186
[2187]: https://github.com/sopel-irc/sopel/pull/2187
[2188]: https://github.com/sopel-irc/sopel/pull/2188
[2191]: https://github.com/sopel-irc/sopel/pull/2191
[2199]: https://github.com/sopel-irc/sopel/pull/2199
[2200]: https://github.com/sopel-irc/sopel/pull/2200
[2205]: https://github.com/sopel-irc/sopel/pull/2205
[2213]: https://github.com/sopel-irc/sopel/pull/2213
[2220]: https://github.com/sopel-irc/sopel/pull/2220
[2222]: https://github.com/sopel-irc/sopel/pull/2222
[2224]: https://github.com/sopel-irc/sopel/pull/2224
[2226]: https://github.com/sopel-irc/sopel/pull/2226
[2227]: https://github.com/sopel-irc/sopel/pull/2227
[2228]: https://github.com/sopel-irc/sopel/pull/2228
[2231]: https://github.com/sopel-irc/sopel/pull/2231
[2232]: https://github.com/sopel-irc/sopel/pull/2232
[2233]: https://github.com/sopel-irc/sopel/pull/2233
[2234]: https://github.com/sopel-irc/sopel/pull/2234
[2236]: https://github.com/sopel-irc/sopel/pull/2236
[2237]: https://github.com/sopel-irc/sopel/pull/2237
[2238]: https://github.com/sopel-irc/sopel/pull/2238
[2239]: https://github.com/sopel-irc/sopel/pull/2239
[2240]: https://github.com/sopel-irc/sopel/pull/2240
[2243]: https://github.com/sopel-irc/sopel/pull/2243
[2244]: https://github.com/sopel-irc/sopel/pull/2244
[2246]: https://github.com/sopel-irc/sopel/pull/2246
[2252]: https://github.com/sopel-irc/sopel/pull/2252
[2253]: https://github.com/sopel-irc/sopel/pull/2253
[2256]: https://github.com/sopel-irc/sopel/pull/2256
[2257]: https://github.com/sopel-irc/sopel/pull/2257
[2260]: https://github.com/sopel-irc/sopel/pull/2260
[2261]: https://github.com/sopel-irc/sopel/pull/2261
[2262]: https://github.com/sopel-irc/sopel/pull/2262
[2265]: https://github.com/sopel-irc/sopel/pull/2265
[2267]: https://github.com/sopel-irc/sopel/pull/2267
[2268]: https://github.com/sopel-irc/sopel/pull/2268
[2270]: https://github.com/sopel-irc/sopel/pull/2270
[2272]: https://github.com/sopel-irc/sopel/pull/2272
[2275]: https://github.com/sopel-irc/sopel/pull/2275
[2276]: https://github.com/sopel-irc/sopel/pull/2276
[2277]: https://github.com/sopel-irc/sopel/pull/2277
[2278]: https://github.com/sopel-irc/sopel/pull/2278
[2279]: https://github.com/sopel-irc/sopel/pull/2279
[2280]: https://github.com/sopel-irc/sopel/pull/2280
[2282]: https://github.com/sopel-irc/sopel/pull/2282
[2286]: https://github.com/sopel-irc/sopel/pull/2286
[2287]: https://github.com/sopel-irc/sopel/pull/2287
[2290]: https://github.com/sopel-irc/sopel/pull/2290
[2297]: https://github.com/sopel-irc/sopel/pull/2297
[2298]: https://github.com/sopel-irc/sopel/pull/2298
[2303]: https://github.com/sopel-irc/sopel/pull/2303
[2304]: https://github.com/sopel-irc/sopel/pull/2304
[2306]: https://github.com/sopel-irc/sopel/pull/2306
[2307]: https://github.com/sopel-irc/sopel/pull/2307
[2309]: https://github.com/sopel-irc/sopel/pull/2309
[2310]: https://github.com/sopel-irc/sopel/pull/2310
[2312]: https://github.com/sopel-irc/sopel/pull/2312
[2313]: https://github.com/sopel-irc/sopel/pull/2313
[2315]: https://github.com/sopel-irc/sopel/pull/2315
[2319]: https://github.com/sopel-irc/sopel/pull/2319
[2320]: https://github.com/sopel-irc/sopel/pull/2320
[2321]: https://github.com/sopel-irc/sopel/pull/2321
[2323]: https://github.com/sopel-irc/sopel/pull/2323
[2326]: https://github.com/sopel-irc/sopel/pull/2326
[2327]: https://github.com/sopel-irc/sopel/pull/2327
[2328]: https://github.com/sopel-irc/sopel/pull/2328
[2329]: https://github.com/sopel-irc/sopel/pull/2329
[2330]: https://github.com/sopel-irc/sopel/pull/2330
[2332]: https://github.com/sopel-irc/sopel/pull/2332
[2334]: https://github.com/sopel-irc/sopel/pull/2334
[2335]: https://github.com/sopel-irc/sopel/pull/2335
[2338]: https://github.com/sopel-irc/sopel/pull/2338
[2341]: https://github.com/sopel-irc/sopel/pull/2341
[2342]: https://github.com/sopel-irc/sopel/pull/2342
[2344]: https://github.com/sopel-irc/sopel/pull/2344
[2345]: https://github.com/sopel-irc/sopel/pull/2345
[2346]: https://github.com/sopel-irc/sopel/pull/2346
[2349]: https://github.com/sopel-irc/sopel/pull/2349
[2351]: https://github.com/sopel-irc/sopel/pull/2351
[2352]: https://github.com/sopel-irc/sopel/pull/2352
[2354]: https://github.com/sopel-irc/sopel/pull/2354
[2359]: https://github.com/sopel-irc/sopel/pull/2359
[2360]: https://github.com/sopel-irc/sopel/pull/2360
[2361]: https://github.com/sopel-irc/sopel/pull/2361
[2365]: https://github.com/sopel-irc/sopel/pull/2365
[2368]: https://github.com/sopel-irc/sopel/pull/2368
[2369]: https://github.com/sopel-irc/sopel/pull/2369
[2370]: https://github.com/sopel-irc/sopel/pull/2370
[2371]: https://github.com/sopel-irc/sopel/pull/2371
[2372]: https://github.com/sopel-irc/sopel/pull/2372
[2374]: https://github.com/sopel-irc/sopel/pull/2374
[2375]: https://github.com/sopel-irc/sopel/pull/2375
[2376]: https://github.com/sopel-irc/sopel/pull/2376
[2377]: https://github.com/sopel-irc/sopel/pull/2377
[2379]: https://github.com/sopel-irc/sopel/pull/2379
[2381]: https://github.com/sopel-irc/sopel/pull/2381
[2382]: https://github.com/sopel-irc/sopel/pull/2382
[2383]: https://github.com/sopel-irc/sopel/pull/2383
[2384]: https://github.com/sopel-irc/sopel/pull/2384
[2385]: https://github.com/sopel-irc/sopel/pull/2385
[2386]: https://github.com/sopel-irc/sopel/pull/2386
[2388]: https://github.com/sopel-irc/sopel/pull/2388
[2393]: https://github.com/sopel-irc/sopel/pull/2393
[2394]: https://github.com/sopel-irc/sopel/pull/2394
[2396]: https://github.com/sopel-irc/sopel/pull/2396
[2400]: https://github.com/sopel-irc/sopel/pull/2400
[2404]: https://github.com/sopel-irc/sopel/pull/2404
[2405]: https://github.com/sopel-irc/sopel/pull/2405
[2406]: https://github.com/sopel-irc/sopel/pull/2406
[2409]: https://github.com/sopel-irc/sopel/pull/2409
[2410]: https://github.com/sopel-irc/sopel/pull/2410
[2411]: https://github.com/sopel-irc/sopel/pull/2411
[2414]: https://github.com/sopel-irc/sopel/pull/2414
[2415]: https://github.com/sopel-irc/sopel/pull/2415
[2416]: https://github.com/sopel-irc/sopel/pull/2416
[2417]: https://github.com/sopel-irc/sopel/pull/2417
[2418]: https://github.com/sopel-irc/sopel/pull/2418
[2419]: https://github.com/sopel-irc/sopel/pull/2419
[2420]: https://github.com/sopel-irc/sopel/pull/2420
[2424]: https://github.com/sopel-irc/sopel/pull/2424
[2426]: https://github.com/sopel-irc/sopel/pull/2426
[2428]: https://github.com/sopel-irc/sopel/pull/2428
[2429]: https://github.com/sopel-irc/sopel/pull/2429
[2430]: https://github.com/sopel-irc/sopel/pull/2430
[2431]: https://github.com/sopel-irc/sopel/pull/2431
[2433]: https://github.com/sopel-irc/sopel/pull/2433
[2434]: https://github.com/sopel-irc/sopel/pull/2434
[2437]: https://github.com/sopel-irc/sopel/pull/2437
[2438]: https://github.com/sopel-irc/sopel/pull/2438
[2439]: https://github.com/sopel-irc/sopel/pull/2439
[2441]: https://github.com/sopel-irc/sopel/pull/2441
[2442]: https://github.com/sopel-irc/sopel/pull/2442
[2444]: https://github.com/sopel-irc/sopel/pull/2444
[2446]: https://github.com/sopel-irc/sopel/pull/2446
[2447]: https://github.com/sopel-irc/sopel/pull/2447
[2448]: https://github.com/sopel-irc/sopel/pull/2448
[2450]: https://github.com/sopel-irc/sopel/pull/2450
[2452]: https://github.com/sopel-irc/sopel/pull/2452
[2453]: https://github.com/sopel-irc/sopel/pull/2453
[2455]: https://github.com/sopel-irc/sopel/pull/2455
[2458]: https://github.com/sopel-irc/sopel/pull/2458
[2460]: https://github.com/sopel-irc/sopel/issues/2460
[2462]: https://github.com/sopel-irc/sopel/pull/2462
[2464]: https://github.com/sopel-irc/sopel/pull/2464
[2468]: https://github.com/sopel-irc/sopel/pull/2468
[2470]: https://github.com/sopel-irc/sopel/pull/2470
[2471]: https://github.com/sopel-irc/sopel/pull/2471
[2472]: https://github.com/sopel-irc/sopel/pull/2472
[2473]: https://github.com/sopel-irc/sopel/pull/2473
[2477]: https://github.com/sopel-irc/sopel/pull/2477
[2478]: https://github.com/sopel-irc/sopel/pull/2478
[2480]: https://github.com/sopel-irc/sopel/pull/2480
[2481]: https://github.com/sopel-irc/sopel/pull/2481
[2489]: https://github.com/sopel-irc/sopel/pull/2489
[2491]: https://github.com/sopel-irc/sopel/pull/2491
[2494]: https://github.com/sopel-irc/sopel/pull/2494
[2495]: https://github.com/sopel-irc/sopel/pull/2495
[2496]: https://github.com/sopel-irc/sopel/pull/2496
[2500]: https://github.com/sopel-irc/sopel/pull/2500
[2502]: https://github.com/sopel-irc/sopel/pull/2502
[2504]: https://github.com/sopel-irc/sopel/pull/2504
[2505]: https://github.com/sopel-irc/sopel/pull/2505
[2507]: https://github.com/sopel-irc/sopel/pull/2507
[2510]: https://github.com/sopel-irc/sopel/pull/2510
[2512]: https://github.com/sopel-irc/sopel/pull/2512
[2513]: https://github.com/sopel-irc/sopel/pull/2513
[2514]: https://github.com/sopel-irc/sopel/pull/2514
[2516]: https://github.com/sopel-irc/sopel/pull/2516
[2519]: https://github.com/sopel-irc/sopel/pull/2519
[2520]: https://github.com/sopel-irc/sopel/pull/2520
[2521]: https://github.com/sopel-irc/sopel/pull/2521
[2522]: https://github.com/sopel-irc/sopel/pull/2522
[2523]: https://github.com/sopel-irc/sopel/pull/2523
[2525]: https://github.com/sopel-irc/sopel/pull/2525
[2530]: https://github.com/sopel-irc/sopel/pull/2530
[2531]: https://github.com/sopel-irc/sopel/pull/2531
[2532]: https://github.com/sopel-irc/sopel/pull/2532
[2533]: https://github.com/sopel-irc/sopel/pull/2533
[2535]: https://github.com/sopel-irc/sopel/pull/2535
[2539]: https://github.com/sopel-irc/sopel/pull/2539
[2540]: https://github.com/sopel-irc/sopel/pull/2540
[2543]: https://github.com/sopel-irc/sopel/pull/2543
[2545]: https://github.com/sopel-irc/sopel/pull/2545
[2550]: https://github.com/sopel-irc/sopel/pull/2550
[2552]: https://github.com/sopel-irc/sopel/pull/2552
[2555]: https://github.com/sopel-irc/sopel/pull/2555
[2558]: https://github.com/sopel-irc/sopel/pull/2558
[2561]: https://github.com/sopel-irc/sopel/pull/2561
[2569]: https://github.com/sopel-irc/sopel/pull/2569
[2574]: https://github.com/sopel-irc/sopel/pull/2574
[2575]: https://github.com/sopel-irc/sopel/pull/2575
[2580]: https://github.com/sopel-irc/sopel/pull/2580
[2581]: https://github.com/sopel-irc/sopel/pull/2581
[2584]: https://github.com/sopel-irc/sopel/pull/2584
[2600]: https://github.com/sopel-irc/sopel/pull/2600
[2601]: https://github.com/sopel-irc/sopel/pull/2601
[2606]: https://github.com/sopel-irc/sopel/pull/2606

7.1.9

===============================

Plugin changes
--------------

* search: replace deprecated git.io link in messaging [[2271][]]
* tell: fix exception when message is missing [[2264][]]

[2264]: https://github.com/sopel-irc/sopel/pull/2264
[2271]: https://github.com/sopel-irc/sopel/pull/2271

7.1.8

===============================

Plugin changes
--------------

* isup: ensure compatibility with newer `requests` versions [[2235][]]
* reddit: handle image preview links [[2245][]]
* search: per tests of both back-ends, warn more consistently about multiple
`site:` operators [[2254][]]
* translate: fix accepting language hints for Chinese [[2242][]]
* url:
* bump user-agent [[2218][]]
* tweak logging levels to better reflect severity [[2249][]]
* wikipedia: refine handling of sections with "hatnote" templates [[2225][]]
* xkcd: improve reliability of comic search [[2247][]]

Core changes
------------

* Formatting tweaks in IRC logging output [[2250][]]
* Requirement tweaks to make sure installing on Python 3.4 still works
(but if you're still using that, *please* update your Python)

API changes
-----------

* Fix/improve more documentation [[2251][]]

[2218]: https://github.com/sopel-irc/sopel/pull/2218
[2225]: https://github.com/sopel-irc/sopel/pull/2225
[2235]: https://github.com/sopel-irc/sopel/pull/2235
[2242]: https://github.com/sopel-irc/sopel/pull/2242
[2245]: https://github.com/sopel-irc/sopel/pull/2245
[2247]: https://github.com/sopel-irc/sopel/pull/2247
[2249]: https://github.com/sopel-irc/sopel/pull/2249
[2250]: https://github.com/sopel-irc/sopel/pull/2250
[2251]: https://github.com/sopel-irc/sopel/pull/2251
[2254]: https://github.com/sopel-irc/sopel/pull/2254

7.1.7

===============================

Plugin changes
--------------

* adminchannel: fix a very old bug in NUH (hostmask) handling [[2221][]]
* reddit:
* add flair text to submission output [[2209][]]
* further improve link matching [[2208][], [2216][]]
* wiktionary: correctly handle multi-paragraph etymologies [[2214][]]

Core changes
------------

* Added an alert if the IRC server registers the bot as a client using a
different nickname than what's set in `core.nick` [[2215][]]

[2208]: https://github.com/sopel-irc/sopel/pull/2208
[2209]: https://github.com/sopel-irc/sopel/pull/2209
[2214]: https://github.com/sopel-irc/sopel/pull/2214
[2215]: https://github.com/sopel-irc/sopel/pull/2215
[2216]: https://github.com/sopel-irc/sopel/pull/2216
[2221]: https://github.com/sopel-irc/sopel/pull/2221

7.1.6

===============================

Plugin changes
--------------

* reddit: fix regression in shortlink (`redd.it/<postID>`) handling [[2201][]]
* url: fix tripping on HTML character entities like `&apos;` if running on
Python 3.4+ [[2204][]]
* wikipedia: add mobile links to URL handling [[2201][]]

Core changes
------------

* Detect UTF-8 locale on Windows [[2174][]]

API changes
-----------

* `web.decode()`: use Python's built-in HTML character entity decoder if
available [[2204][]]
* Fix minor documentation error [[2196][]]

[2174]: https://github.com/sopel-irc/sopel/pull/2174
[2196]: https://github.com/sopel-irc/sopel/pull/2196
[2201]: https://github.com/sopel-irc/sopel/pull/2201
[2202]: https://github.com/sopel-irc/sopel/pull/2202
[2204]: https://github.com/sopel-irc/sopel/pull/2204

7.1.5

===============================

Since 7.1.4 was released, an [expiring TLS root certificate][le-expiration]
caused us some problems in the old CI system we're still using for Sopel 7.1.x
to run tests against EOL versions of Python. Our workaround in [2192][]
(basically "Workaround 1" from [this OpenSSL blog post][openssl-102-fixes])
might be of use to anyone still running Sopel on an old system.

Core changes
------------

* Fixed incorrect behavior during unrecognized SASL authentication [[2190][]]
* Ignore case when checking config sections for "defined" settings [[2193][]]

[2190]: https://github.com/sopel-irc/sopel/pull/2190
[2192]: https://github.com/sopel-irc/sopel/pull/2192
[2193]: https://github.com/sopel-irc/sopel/pull/2193
[le-expiration]: https://letsencrypt.org/2021/10/01/cert-chaining-help.html
[openssl-102-fixes]: https://www.openssl.org/blog/blog/2021/09/13/LetsEncryptRootCertExpire/

Page 1 of 11

© 2024 Safety CLI Cybersecurity Inc. All Rights Reserved.