Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seen: catch database write errors #2338

Merged
merged 1 commit into from
Sep 3, 2022

Conversation

SnoopJ
Copy link
Contributor

@SnoopJ SnoopJ commented Aug 6, 2022

Description

Currently, if the DB writes that the seen plugin tries to do fail for any reason, the error will propagate up into bot.error() and cause very antisocial error report messages from the bot every time the channel receives messages, if the reply_errors (sic) feature is turned on. In particular, I've seen this with a disk that becomes full with the sqlite3 backend, but this patch should cover a broad class of such failures.

Checklist

  • I have read CONTRIBUTING.md
  • I can and do license this contribution under the EFLv2
  • No issues are reported by make qa (runs make quality and make test)
    • Just the same test failures I see when I run make qa against master (0479737):
      12 failed, 1268 passed, 8 xfailed, 1 warning, 73 errors in 44.38s
  • I have tested the functionality of the things this change touches

@dgw
Copy link
Member

dgw commented Aug 6, 2022

  • No issues are reported by make qa (runs make quality and make test)
    • Just the same test failures I see when I run make qa against master (0479737):
      12 failed, 1268 passed, 8 xfailed, 1 warning, 73 errors in 44.38s

Are you running make qa with the wrong version of pytest installed, or something? CI results show no failures on that commit.

Also this whole patch makes me wish that seen stored everything in one object/value, because this nonsense allows one or more of the writes to succeed before a later one fails and thus leave the data in an inconsistent state.

(Did someone say, "Add transactions to the key/value API? 🙃)

@SnoopJ
Copy link
Contributor Author

SnoopJ commented Aug 6, 2022

  • No issues are reported by make qa (runs make quality and make test)

    • Just the same test failures I see when I run make qa against master (0479737):
      12 failed, 1268 passed, 8 xfailed, 1 warning, 73 errors in 44.38s

Are you running make qa with the wrong version of pytest installed, or something? CI results show no failures on that commit.

Possibly. I don't know what the right version is, it doesn't appear to be one of the things pinned by requirements.txt. Below is the log from a fresh venv after installing requirements.txt, pytest==6.2.5, and sopel against this commit. I did also try it with a more recent pytest with not much apparent difference. Seems like most of the problem is with importlib_metadata, not sure what I did wrong here, but evidently something since as you say CI passes.

test.log
coverage run -m py.test -v .
============================= test session starts ==============================
platform linux -- Python 3.8.10, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- /usr/bin/python3
cachedir: .pytest_cache
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/home/snoopjedi/repos/sopel-src/.hypothesis/examples')
rootdir: /home/snoopjedi/repos/sopel-src, configfile: setup.cfg
plugins: sopel-8.0.0.dev0, anyio-3.5.0, hypothesis-5.38.1, cov-2.10.1, typeguard-2.10.0
collecting ... collected 1361 items

sopel/modules/calc.py::test_example_c_0 PASSED                           [  0%]
sopel/modules/calc.py::test_example_c_1 PASSED                           [  0%]
sopel/modules/calc.py::test_example_c_2 PASSED                           [  0%]
sopel/modules/calc.py::test_example_c_3 PASSED                           [  0%]
sopel/modules/calc.py::test_example_c_4 PASSED                           [  0%]
sopel/modules/calc.py::test_example_c_5 PASSED                           [  0%]
sopel/modules/calc.py::test_example_c_6 PASSED                           [  0%]
sopel/modules/choose.py::test_example_choose_0 PASSED                    [  0%]
sopel/modules/choose.py::test_example_choose_1 PASSED                    [  0%]
sopel/modules/choose.py::test_example_choose_2 PASSED                    [  0%]
sopel/modules/choose.py::test_example_choose_3 PASSED                    [  0%]
sopel/modules/choose.py::test_example_choose_4 PASSED                    [  0%]
sopel/modules/choose.py::test_example_choose_5 PASSED                    [  0%]
sopel/modules/choose.py::test_example_choose_6 PASSED                    [  1%]
sopel/modules/currency.py::test_example_exchange_cmd_0 PASSED            [  1%]
sopel/modules/currency.py::test_example_exchange_cmd_1 PASSED            [  1%]
sopel/modules/dice.py::test_example_roll_0 PASSED                        [  1%]
sopel/modules/dice.py::test_example_roll_1 PASSED                        [  1%]
sopel/modules/dice.py::test_example_roll_2 PASSED                        [  1%]
sopel/modules/dice.py::test_example_roll_3 PASSED                        [  1%]
sopel/modules/dice.py::test_example_roll_4 PASSED                        [  1%]
sopel/modules/dice.py::test_example_roll_5 PASSED                        [  1%]
sopel/modules/dice.py::test_example_roll_6 PASSED                        [  1%]
sopel/modules/dice.py::test_example_roll_7 PASSED                        [  1%]
sopel/modules/emoticons.py::test_example_shrug_0 PASSED                  [  1%]
sopel/modules/emoticons.py::test_example_happy_0 PASSED                  [  1%]
sopel/modules/emoticons.py::test_example_smirk_0 PASSED                  [  1%]
sopel/modules/emoticons.py::test_example_tableflip_0 PASSED              [  2%]
sopel/modules/emoticons.py::test_example_tableflip_1 PASSED              [  2%]
sopel/modules/emoticons.py::test_example_unflip_0 PASSED                 [  2%]
sopel/modules/emoticons.py::test_example_lenny_0 PASSED                  [  2%]
sopel/modules/emoticons.py::test_example_anger_0 PASSED                  [  2%]
sopel/modules/emoticons.py::test_example_anger_1 PASSED                  [  2%]
sopel/modules/emoticons.py::test_example_cry_0 PASSED                    [  2%]
sopel/modules/emoticons.py::test_example_love_0 PASSED                   [  2%]
sopel/modules/emoticons.py::test_example_success_0 PASSED                [  2%]
sopel/modules/emoticons.py::test_example_success_1 PASSED                [  2%]
sopel/modules/emoticons.py::test_example_wat_0 PASSED                    [  2%]
sopel/modules/emoticons.py::test_example_wat_1 PASSED                    [  2%]
sopel/modules/emoticons.py::test_example_crazy_0 PASSED                  [  2%]
sopel/modules/emoticons.py::test_example_hungry_0 PASSED                 [  3%]
sopel/modules/emoticons.py::test_example_surprised_0 PASSED              [  3%]
sopel/modules/emoticons.py::test_example_sick_0 PASSED                   [  3%]
sopel/modules/emoticons.py::test_example_afraid_0 PASSED                 [  3%]
sopel/modules/emoticons.py::test_example_worried_0 PASSED                [  3%]
sopel/modules/ip.py::test_example_ip_0 PASSED                            [  3%]
sopel/modules/lmgtfy.py::test_example_googleit_0 PASSED                  [  3%]
sopel/modules/lmgtfy.py::test_example_googleit_1 PASSED                  [  3%]
sopel/modules/lmgtfy.py::test_example_googleit_2 PASSED                  [  3%]
sopel/modules/py.py::test_example_py_0 PASSED                            [  3%]
sopel/modules/rand.py::test_example_rand_0 PASSED                        [  3%]
sopel/modules/rand.py::test_example_rand_1 PASSED                        [  3%]
sopel/modules/rand.py::test_example_rand_2 PASSED                        [  3%]
sopel/modules/rand.py::test_example_rand_3 PASSED                        [  3%]
sopel/modules/rand.py::test_example_rand_4 PASSED                        [  4%]
sopel/modules/search.py::test_example_duck_0 FAILED                      [  4%]
sopel/modules/search.py::test_example_duck_1 FAILED                      [  4%]
sopel/modules/search.py::test_example_suggest_0 PASSED                   [  4%]
sopel/modules/search.py::test_example_suggest_1 PASSED                   [  4%]
sopel/modules/search.py::test_example_suggest_2 PASSED                   [  4%]
sopel/modules/tell.py::test_example_f_remind_0 PASSED                    [  4%]
sopel/modules/tell.py::test_example_f_remind_1 PASSED                    [  4%]
sopel/modules/translate.py::test_example_tr2_0 PASSED                    [  4%]
sopel/modules/translate.py::test_example_tr2_1 PASSED                    [  4%]
sopel/modules/translate.py::test_example_tr2_2 PASSED                    [  4%]
sopel/modules/unicode_info.py::test_example_codepoint_0 PASSED           [  4%]
sopel/modules/unicode_info.py::test_example_codepoint_1 PASSED           [  4%]
sopel/modules/units.py::test_example_temperature_0 PASSED                [  4%]
sopel/modules/units.py::test_example_temperature_1 PASSED                [  5%]
sopel/modules/units.py::test_example_temperature_2 PASSED                [  5%]
sopel/modules/units.py::test_example_distance_0 PASSED                   [  5%]
sopel/modules/units.py::test_example_distance_1 PASSED                   [  5%]
sopel/modules/units.py::test_example_distance_2 PASSED                   [  5%]
sopel/modules/units.py::test_example_distance_3 PASSED                   [  5%]
sopel/modules/units.py::test_example_distance_4 PASSED                   [  5%]
sopel/modules/units.py::test_example_distance_5 PASSED                   [  5%]
sopel/modules/units.py::test_example_distance_6 PASSED                   [  5%]
sopel/modules/units.py::test_example_distance_7 PASSED                   [  5%]
sopel/modules/units.py::test_example_distance_8 PASSED                   [  5%]
sopel/modules/units.py::test_example_distance_9 PASSED                   [  5%]
sopel/modules/url.py::test_example_title_command_0 FAILED                [  5%]
sopel/modules/wiktionary.py::test_example_wiktionary_0 PASSED            [  6%]
sopel/modules/wiktionary.py::test_example_wiktionary_ety_0 PASSED        [  6%]
test/test_bot.py::test_wrapper_say PASSED                                [  6%]
test/test_bot.py::test_wrapper_say_override_destination PASSED           [  6%]
test/test_bot.py::test_wrapper_notice PASSED                             [  6%]
test/test_bot.py::test_wrapper_notice_override_destination PASSED        [  6%]
test/test_bot.py::test_wrapper_action PASSED                             [  6%]
test/test_bot.py::test_wrapper_action_override_destination PASSED        [  6%]
test/test_bot.py::test_wrapper_reply PASSED                              [  6%]
test/test_bot.py::test_wrapper_reply_override_destination PASSED         [  6%]
test/test_bot.py::test_wrapper_reply_override_reply_to PASSED            [  6%]
test/test_bot.py::test_wrapper_reply_override_destination_reply_to PASSED [  6%]
test/test_bot.py::test_wrapper_kick PASSED                               [  6%]
test/test_bot.py::test_wrapper_kick_message PASSED                       [  6%]
test/test_bot.py::test_wrapper_kick_error_nick PASSED                    [  7%]
test/test_bot.py::test_wrapper_kick_error_channel PASSED                 [  7%]
test/test_bot.py::test_wrapper_kick_override_destination PASSED          [  7%]
test/test_bot.py::test_wrapper_kick_override_destination_message PASSED  [  7%]
test/test_bot.py::test_register_plugin PASSED                            [  7%]
test/test_bot.py::test_register_unregister_plugin PASSED                 [  7%]
test/test_bot.py::test_remove_plugin_unknown_plugin PASSED               [  7%]
test/test_bot.py::test_remove_plugin_unregistered_plugin PASSED          [  7%]
test/test_bot.py::test_reload_plugin_unregistered_plugin PASSED          [  7%]
test/test_bot.py::test_register_callables PASSED                         [  7%]
test/test_bot.py::test_register_urls PASSED                              [  7%]
test/test_bot.py::test_call_rule PASSED                                  [  7%]
test/test_bot.py::test_call_rule_rate_limited_user PASSED                [  7%]
test/test_bot.py::test_call_rule_rate_limited_user_with_message PASSED   [  8%]
test/test_bot.py::test_call_rule_rate_limited_channel PASSED             [  8%]
test/test_bot.py::test_call_rule_rate_limited_channel_with_message PASSED [  8%]
test/test_bot.py::test_call_rule_rate_limited_global PASSED              [  8%]
test/test_bot.py::test_call_rule_rate_limited_global_with_message PASSED [  8%]
test/test_bot.py::test_has_channel_privilege_no_privilege FAILED         [  8%]
test/test_bot.py::test_has_channel_privilege_voice FAILED                [  8%]
test/test_bot.py::test_has_channel_privilege_halfop FAILED               [  8%]
test/test_bot.py::test_has_channel_privilege_op FAILED                   [  8%]
test/test_bot.py::test_has_channel_privilege_admin FAILED                [  8%]
test/test_bot.py::test_has_channel_privilege_owner FAILED                [  8%]
test/test_bot.py::test_has_channel_privilege_operator FAILED             [  8%]
test/test_bot.py::test_search_url_callbacks PASSED                       [  8%]
test/test_bot.py::test_search_url_callbacks_pattern PASSED               [  8%]
test/test_bot.py::test_search_url_callbacks_compiled_pattern PASSED      [  9%]
test/test_bot.py::test_search_url_callbacks_not_found PASSED             [  9%]
test/test_bot.py::test_register_url_callback_multiple PASSED             [  9%]
test/test_bot.py::test_unregister_url_callback PASSED                    [  9%]
test/test_bot.py::test_unregister_url_callback_no_memory PASSED          [  9%]
test/test_bot.py::test_unregister_url_callback_unknown_pattern PASSED    [  9%]
test/test_bot.py::test_unregister_url_callback_compiled_pattern PASSED   [  9%]
test/test_bot.py::test_multiple_url_callback PASSED                      [  9%]
test/test_bot.py::test_manual_url_callback_not_found PASSED              [  9%]
test/test_bot.py::test_ignore_replay_servertime PASSED                   [  9%]
test/test_bot.py::test_user_quit FAILED                                  [  9%]
test/test_config.py::test_validated_string_when_none PASSED              [  9%]
test/test_config.py::test_listattribute_when_empty PASSED                [  9%]
test/test_config.py::test_listattribute_with_one_value PASSED            [  9%]
test/test_config.py::test_listattribute_with_multiple_values PASSED      [ 10%]
test/test_config.py::test_listattribute_with_value_containing_comma PASSED [ 10%]
test/test_config.py::test_listattribute_with_value_containing_nonescape_backslash PASSED [ 10%]
test/test_config.py::test_listattribute_with_value_containing_standard_escape_sequence PASSED [ 10%]
test/test_config.py::test_listattribute_with_value_ending_in_special_chars PASSED [ 10%]
test/test_config.py::test_listattribute_with_value_containing_adjacent_special_chars PASSED [ 10%]
test/test_config.py::test_choiceattribute_when_none PASSED               [ 10%]
test/test_config.py::test_choiceattribute_when_not_in_set PASSED         [ 10%]
test/test_config.py::test_choiceattribute_when_valid PASSED              [ 10%]
test/test_config.py::test_booleanattribute_default PASSED                [ 10%]
test/test_config.py::test_fileattribute_valid_absolute_file_path PASSED  [ 10%]
test/test_config.py::test_fileattribute_valid_absolute_dir_path PASSED   [ 10%]
test/test_config.py::test_fileattribute_given_relative_when_absolute PASSED [ 10%]
test/test_config.py::test_fileattribute_given_absolute_when_relative PASSED [ 11%]
test/test_config.py::test_fileattribute_given_dir_when_file PASSED       [ 11%]
test/test_config.py::test_fileattribute_given_file_when_dir PASSED       [ 11%]
test/test_config.py::test_configparser_env_priority_over_file PASSED     [ 11%]
test/test_config.py::test_configparser_multi_lines PASSED                [ 11%]
test/test_config.py::test_configparser_multi_env PASSED                  [ 11%]
test/test_config.py::test_save_unmodified_config PASSED                  [ 11%]
test/test_config.py::test_save_modified_config PASSED                    [ 11%]
test/test_config.py::test_get_defined_sections PASSED                    [ 11%]
test/test_coretasks.py::test_bot_mixed_modes ERROR                       [ 11%]
test/test_coretasks.py::test_bot_mixed_mode_removal ERROR                [ 11%]
test/test_coretasks.py::test_bot_mixed_mode_types ERROR                  [ 11%]
test/test_coretasks.py::test_bot_unknown_mode ERROR                      [ 11%]
test/test_coretasks.py::test_bot_unknown_priv_mode ERROR                 [ 11%]
test/test_coretasks.py::test_bot_extra_mode_args ERROR                   [ 12%]
test/test_coretasks.py::test_handle_rpl_channelmodeis ERROR              [ 12%]
test/test_coretasks.py::test_handle_rpl_channelmodeis_clear ERROR        [ 12%]
test/test_coretasks.py::test_mode_colon ERROR                            [ 12%]
test/test_coretasks.py::test_execute_perform_raise_not_connected ERROR   [ 12%]
test/test_coretasks.py::test_execute_perform_send_commands ERROR         [ 12%]
test/test_coretasks.py::test_execute_perform_replaces_nickname ERROR     [ 12%]
test/test_coretasks.py::test_handle_isupport ERROR                       [ 12%]
test/test_coretasks.py::test_handle_isupport_casemapping ERROR           [ 12%]
test/test_coretasks.py::test_handle_isupport_chantypes ERROR             [ 12%]
test/test_coretasks.py::test_handle_isupport_bot_mode[] ERROR            [ 12%]
test/test_coretasks.py::test_handle_isupport_bot_mode[Rw] ERROR          [ 12%]
test/test_coretasks.py::test_handle_isupport_bot_mode_override[B] ERROR  [ 12%]
test/test_coretasks.py::test_handle_isupport_bot_mode_override[RBw] ERROR [ 13%]
test/test_coretasks.py::test_handle_isupport_namesx ERROR                [ 13%]
test/test_coretasks.py::test_handle_isupport_uhnames ERROR               [ 13%]
test/test_coretasks.py::test_handle_isupport_namesx_with_multi_prefix ERROR [ 13%]
test/test_coretasks.py::test_handle_rpl_myinfo ERROR                     [ 13%]
test/test_coretasks.py::test_sasl_plain_token_generation PASSED          [ 13%]
test/test_coretasks.py::test_recv_chghost ERROR                          [ 13%]
test/test_coretasks.py::test_recv_chghost_invalid ERROR                  [ 13%]
test/test_coretasks.py::test_join_time ERROR                             [ 13%]
test/test_coretasks.py::test_handle_rpl_namreply_with_malformed_uhnames ERROR [ 13%]
test/test_db.py::test_execute PASSED                                     [ 13%]
test/test_db.py::test_connect PASSED                                     [ 13%]
test/test_db.py::test_get_uri PASSED                                     [ 13%]
test/test_db.py::test_get_nick_id PASSED                                 [ 13%]
test/test_db.py::test_get_nick_id_casemapping[MrEricPraline-mrericpraline-mRErICPraLINE] PASSED [ 14%]
test/test_db.py::test_get_nick_id_casemapping[[][]-{}{}-[}{]] PASSED     [ 14%]
test/test_db.py::test_get_nick_id_casemapping[Mr\xc9r\xefcPr\xe2lin\xe9-mr\xc9r\xefcpr\xe2lin\xe9-MR\xc9R\xefCPR\xe2LIN\xe9] PASSED [ 14%]
test/test_db.py::test_get_nick_id_migration PASSED                       [ 14%]
test/test_db.py::test_alias_nick PASSED                                  [ 14%]
test/test_db.py::test_set_nick_value[string-value] PASSED                [ 14%]
test/test_db.py::test_set_nick_value[123456789] PASSED                   [ 14%]
test/test_db.py::test_set_nick_value[unicode-v\xe4l\xfb\xe9] PASSED      [ 14%]
test/test_db.py::test_set_nick_value[value3] PASSED                      [ 14%]
test/test_db.py::test_set_nick_value_update PASSED                       [ 14%]
test/test_db.py::test_delete_nick_value PASSED                           [ 14%]
test/test_db.py::test_delete_nick_value_none PASSED                      [ 14%]
test/test_db.py::test_get_nick_value[string-value] PASSED                [ 14%]
test/test_db.py::test_get_nick_value[123456789] PASSED                   [ 14%]
test/test_db.py::test_get_nick_value[unicode-v\xe4l\xfb\xe9] PASSED      [ 15%]
test/test_db.py::test_get_nick_value[value3] PASSED                      [ 15%]
test/test_db.py::test_get_nick_value_default PASSED                      [ 15%]
test/test_db.py::test_unalias_nick PASSED                                [ 15%]
test/test_db.py::test_unalias_nick_one_or_none PASSED                    [ 15%]
test/test_db.py::test_forget_nick_group PASSED                           [ 15%]
test/test_db.py::test_merge_nick_groups PASSED                           [ 15%]
test/test_db.py::test_get_channel_slug PASSED                            [ 15%]
test/test_db.py::test_get_channel_slug_with_migration PASSED             [ 15%]
test/test_db.py::test_set_channel_value PASSED                           [ 15%]
test/test_db.py::test_delete_channel_value PASSED                        [ 15%]
test/test_db.py::test_get_channel_value PASSED                           [ 15%]
test/test_db.py::test_get_channel_value_default PASSED                   [ 15%]
test/test_db.py::test_forget_channel PASSED                              [ 16%]
test/test_db.py::test_set_plugin_value PASSED                            [ 16%]
test/test_db.py::test_delete_plugin_value PASSED                         [ 16%]
test/test_db.py::test_delete_plugin_value_none PASSED                    [ 16%]
test/test_db.py::test_get_plugin_value PASSED                            [ 16%]
test/test_db.py::test_get_plugin_value_default PASSED                    [ 16%]
test/test_db.py::test_forget_plugin PASSED                               [ 16%]
test/test_db.py::test_forget_plugin_none PASSED                          [ 16%]
test/test_db.py::test_get_nick_or_channel_value PASSED                   [ 16%]
test/test_db.py::test_get_nick_or_channel_value_identifier PASSED        [ 16%]
test/test_db.py::test_get_nick_or_channel_value_default PASSED           [ 16%]
test/test_db.py::test_get_preferred_value PASSED                         [ 16%]
test/test_db.py::test_get_preferred_value_none PASSED                    [ 16%]
test/test_formatting.py::test_color PASSED                               [ 16%]
test/test_formatting.py::test_hex_color PASSED                           [ 17%]
test/test_formatting.py::test_bold PASSED                                [ 17%]
test/test_formatting.py::test_italic PASSED                              [ 17%]
test/test_formatting.py::test_underline PASSED                           [ 17%]
test/test_formatting.py::test_strikethrough PASSED                       [ 17%]
test/test_formatting.py::test_monospace PASSED                           [ 17%]
test/test_formatting.py::test_reverse PASSED                             [ 17%]
test/test_formatting.py::test_plain_color PASSED                         [ 17%]
test/test_formatting.py::test_plain_hex_color PASSED                     [ 17%]
test/test_formatting.py::test_plain_bold PASSED                          [ 17%]
test/test_formatting.py::test_plain_italic PASSED                        [ 17%]
test/test_formatting.py::test_plain_underline PASSED                     [ 17%]
test/test_formatting.py::test_plain_strikethrough PASSED                 [ 17%]
test/test_formatting.py::test_plain_monospace PASSED                     [ 18%]
test/test_formatting.py::test_plain_reverse PASSED                       [ 18%]
test/test_formatting.py::test_plain_reset PASSED                         [ 18%]
test/test_formatting.py::test_plain_non_printing[\x00] PASSED            [ 18%]
test/test_formatting.py::test_plain_non_printing[\x01] PASSED            [ 18%]
test/test_formatting.py::test_plain_non_printing[\x02] PASSED            [ 18%]
test/test_formatting.py::test_plain_non_printing[\x03] PASSED            [ 18%]
test/test_formatting.py::test_plain_non_printing[\x04] PASSED            [ 18%]
test/test_formatting.py::test_plain_non_printing[\x05] PASSED            [ 18%]
test/test_formatting.py::test_plain_non_printing[\x06] PASSED            [ 18%]
test/test_formatting.py::test_plain_non_printing[\x07] PASSED            [ 18%]
test/test_formatting.py::test_plain_non_printing[\x08] PASSED            [ 18%]
test/test_formatting.py::test_plain_non_printing[\t] PASSED              [ 18%]
test/test_formatting.py::test_plain_non_printing[\n] PASSED              [ 18%]
test/test_formatting.py::test_plain_non_printing[\x0b] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x0c] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\r] PASSED              [ 19%]
test/test_formatting.py::test_plain_non_printing[\x0e] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x0f] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x10] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x11] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x12] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x13] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x14] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x15] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x16] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x17] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x18] PASSED            [ 19%]
test/test_formatting.py::test_plain_non_printing[\x19] PASSED            [ 20%]
test/test_formatting.py::test_plain_non_printing[\x1a] PASSED            [ 20%]
test/test_formatting.py::test_plain_non_printing[\x1b] PASSED            [ 20%]
test/test_formatting.py::test_plain_non_printing[\x1c] PASSED            [ 20%]
test/test_formatting.py::test_plain_non_printing[\x1d] PASSED            [ 20%]
test/test_formatting.py::test_plain_non_printing[\x1e] PASSED            [ 20%]
test/test_formatting.py::test_plain_non_printing[\x1f] PASSED            [ 20%]
test/test_formatting.py::test_plain_non_printing[\x7f] PASSED            [ 20%]
test/test_formatting.py::test_plain_unknown PASSED                       [ 20%]
test/test_formatting.py::test_plain_emoji PASSED                         [ 20%]
test/test_irc.py::test_safe_text_length_hostmask_unknown PASSED          [ 20%]
test/test_irc.py::test_safe_text_length PASSED                           [ 20%]
test/test_irc.py::test_on_connect PASSED                                 [ 20%]
test/test_irc.py::test_on_connect_auth_password PASSED                   [ 21%]
test/test_irc.py::test_on_connect_server_auth_password PASSED            [ 21%]
test/test_irc.py::test_on_connect_auth_password_override_server_auth PASSED [ 21%]
test/test_irc.py::test_write PASSED                                      [ 21%]
test/test_irc.py::test_write_args PASSED                                 [ 21%]
test/test_irc.py::test_write_text PASSED                                 [ 21%]
test/test_irc.py::test_write_args_text_safe PASSED                       [ 21%]
test/test_irc.py::test_write_args_many PASSED                            [ 21%]
test/test_irc.py::test_write_text_many PASSED                            [ 21%]
test/test_irc.py::test_action PASSED                                     [ 21%]
test/test_irc.py::test_join PASSED                                       [ 21%]
test/test_irc.py::test_join_password PASSED                              [ 21%]
test/test_irc.py::test_kick PASSED                                       [ 21%]
test/test_irc.py::test_kick_reason PASSED                                [ 21%]
test/test_irc.py::test_notice PASSED                                     [ 22%]
test/test_irc.py::test_part PASSED                                       [ 22%]
test/test_irc.py::test_part_reason PASSED                                [ 22%]
test/test_irc.py::test_reply PASSED                                      [ 22%]
test/test_irc.py::test_reply_notice PASSED                               [ 22%]
test/test_irc.py::test_say PASSED                                        [ 22%]
test/test_irc.py::test_say_safe PASSED                                   [ 22%]
test/test_irc.py::test_say_long_fit PASSED                               [ 22%]
test/test_irc.py::test_say_long_extra PASSED                             [ 22%]
test/test_irc.py::test_say_long_extra_multi_message PASSED               [ 22%]
test/test_irc.py::test_say_long_extra_multi_message_multibyte_recipient PASSED [ 22%]
test/test_irc.py::test_say_long_truncation_fit PASSED                    [ 22%]
test/test_irc.py::test_say_long_truncation_extra PASSED                  [ 22%]
test/test_irc.py::test_say_long_truncation_extra_multi_message PASSED    [ 22%]
test/test_irc.py::test_say_long_truncation_extra_multi_message_multibyte PASSED [ 23%]
test/test_irc.py::test_say_trailing PASSED                               [ 23%]
test/test_irc.py::test_say_long_truncation_trailing PASSED               [ 23%]
test/test_irc.py::test_say_no_repeat_protection PASSED                   [ 23%]
test/test_loader.py::test_is_limitable PASSED                            [ 23%]
test/test_loader.py::test_is_triggerable PASSED                          [ 23%]
test/test_loader.py::test_is_url_callback PASSED                         [ 23%]
test/test_loader.py::test_clean_module PASSED                            [ 23%]
test/test_loader.py::test_clean_module_idempotency PASSED                [ 23%]
test/test_loader.py::test_clean_callable_default PASSED                  [ 23%]
test/test_loader.py::test_clean_callable_command PASSED                  [ 23%]
test/test_loader.py::test_clean_callable_event PASSED                    [ 23%]
test/test_loader.py::test_clean_callable_rule PASSED                     [ 23%]
test/test_loader.py::test_clean_callable_rule_nick PASSED                [ 24%]
test/test_loader.py::test_clean_callable_rule_nickname PASSED            [ 24%]
test/test_loader.py::test_clean_callable_find_rules PASSED               [ 24%]
test/test_loader.py::test_clean_callable_search_rules PASSED             [ 24%]
test/test_loader.py::test_clean_callable_nickname_command PASSED         [ 24%]
test/test_loader.py::test_clean_callable_action_command PASSED           [ 24%]
test/test_loader.py::test_clean_callable_events PASSED                   [ 24%]
test/test_loader.py::test_clean_callable_example PASSED                  [ 24%]
test/test_loader.py::test_clean_callable_example_not_set PASSED          [ 24%]
test/test_loader.py::test_clean_callable_example_multi_commands PASSED   [ 24%]
test/test_loader.py::test_clean_callable_example_first_only PASSED       [ 24%]
test/test_loader.py::test_clean_callable_example_first_only_multi_commands PASSED [ 24%]
test/test_loader.py::test_clean_callable_example_user_help PASSED        [ 24%]
test/test_loader.py::test_clean_callable_example_user_help_multi PASSED  [ 24%]
test/test_loader.py::test_clean_callable_example_user_help_mixed PASSED  [ 25%]
test/test_loader.py::test_clean_callable_example_default_prefix PASSED   [ 25%]
test/test_loader.py::test_clean_callable_example_nickname PASSED         [ 25%]
test/test_loader.py::test_clean_callable_example_nickname_custom_prefix PASSED [ 25%]
test/test_loader.py::test_clean_callable_ctcp PASSED                     [ 25%]
test/test_loader.py::test_clean_callable_url PASSED                      [ 25%]
test/test_module.py::test_unblockable PASSED                             [ 25%]
test/test_module.py::test_interval PASSED                                [ 25%]
test/test_module.py::test_interval_args PASSED                           [ 25%]
test/test_module.py::test_interval_multiple PASSED                       [ 25%]
test/test_module.py::test_rule PASSED                                    [ 25%]
test/test_module.py::test_rule_args PASSED                               [ 25%]
test/test_module.py::test_rule_multiple PASSED                           [ 25%]
test/test_module.py::test_thread PASSED                                  [ 26%]
test/test_module.py::test_url PASSED                                     [ 26%]
test/test_module.py::test_url_args PASSED                                [ 26%]
test/test_module.py::test_url_multiple PASSED                            [ 26%]
test/test_module.py::test_echo PASSED                                    [ 26%]
test/test_module.py::test_commands PASSED                                [ 26%]
test/test_module.py::test_commands_args PASSED                           [ 26%]
test/test_module.py::test_commands_multiple PASSED                       [ 26%]
test/test_module.py::test_nickname_commands PASSED                       [ 26%]
test/test_module.py::test_nickname_commands_args PASSED                  [ 26%]
test/test_module.py::test_nickname_commands_multiple PASSED              [ 26%]
test/test_module.py::test_action_commands PASSED                         [ 26%]
test/test_module.py::test_action_commands_args PASSED                    [ 26%]
test/test_module.py::test_action_commands_multiple PASSED                [ 26%]
test/test_module.py::test_all_commands PASSED                            [ 27%]
test/test_module.py::test_priority PASSED                                [ 27%]
test/test_module.py::test_event PASSED                                   [ 27%]
test/test_module.py::test_event_args PASSED                              [ 27%]
test/test_module.py::test_event_multiple PASSED                          [ 27%]
test/test_module.py::test_intent PASSED                                  [ 27%]
test/test_module.py::test_intent_args PASSED                             [ 27%]
test/test_module.py::test_intent_multiple PASSED                         [ 27%]
test/test_module.py::test_rate PASSED                                    [ 27%]
test/test_module.py::test_rate_only_once PASSED                          [ 27%]
test/test_module.py::test_require_privmsg ERROR                          [ 27%]
test/test_module.py::test_require_chanmsg ERROR                          [ 27%]
test/test_module.py::test_require_account ERROR                          [ 27%]
test/test_module.py::test_require_privilege ERROR                        [ 27%]
test/test_module.py::test_require_admin ERROR                            [ 28%]
test/test_module.py::test_require_owner ERROR                            [ 28%]
test/test_module.py::test_example ERROR                                  [ 28%]
test/test_module.py::test_output_prefix PASSED                           [ 28%]
test/test_plugin.py::test_allow_bots PASSED                              [ 28%]
test/test_plugin.py::test_find PASSED                                    [ 28%]
test/test_plugin.py::test_find_args PASSED                               [ 28%]
test/test_plugin.py::test_find_multiple PASSED                           [ 28%]
test/test_plugin.py::test_label PASSED                                   [ 28%]
test/test_plugin.py::test_search PASSED                                  [ 28%]
test/test_plugin.py::test_search_args PASSED                             [ 28%]
test/test_plugin.py::test_search_multiple PASSED                         [ 28%]
test/test_plugin.py::test_url_lazy PASSED                                [ 28%]
test/test_plugin.py::test_url_lazy_args PASSED                           [ 29%]
test/test_plugin.py::test_url_lazy_multiple PASSED                       [ 29%]
test/test_plugin.py::test_rule_lazy PASSED                               [ 29%]
test/test_plugin.py::test_rule_lazy_args PASSED                          [ 29%]
test/test_plugin.py::test_rule_lazy_multiple PASSED                      [ 29%]
test/test_plugin.py::test_find_lazy PASSED                               [ 29%]
test/test_plugin.py::test_find_lazy_args PASSED                          [ 29%]
test/test_plugin.py::test_find_lazy_multiple PASSED                      [ 29%]
test/test_plugin.py::test_search_lazy PASSED                             [ 29%]
test/test_plugin.py::test_search_lazy_args PASSED                        [ 29%]
test/test_plugin.py::test_search_lazy_multiple PASSED                    [ 29%]
test/test_plugin.py::test_ctcp PASSED                                    [ 29%]
test/test_plugin.py::test_ctcp_empty PASSED                              [ 29%]
test/test_plugin.py::test_ctcp_direct PASSED                             [ 29%]
test/test_plugin.py::test_rate_user PASSED                               [ 30%]
test/test_plugin.py::test_rate_channel PASSED                            [ 30%]
test/test_plugin.py::test_rate_global PASSED                             [ 30%]
test/test_plugin.py::test_rate_combine_rate_decorators PASSED            [ 30%]
test/test_plugin.py::test_require_bot_privilege FAILED                   [ 30%]
test/test_plugin.py::test_require_bot_privilege_private_message FAILED   [ 30%]
test/test_plugins.py::test_plugin_load_pymod PASSED                      [ 30%]
test/test_plugins.py::test_plugin_load_pymod_bad_file_pyc PASSED         [ 30%]
test/test_plugins.py::test_plugin_load_pymod_bad_file_no_ext PASSED      [ 30%]
test/test_plugins.py::test_plugin_load_pypackage PASSED                  [ 30%]
test/test_plugins.py::test_plugin_load_pypackage_bad_dir_empty PASSED    [ 30%]
test/test_plugins.py::test_plugin_load_pypackage_bad_dir_no_init PASSED  [ 30%]
test/test_plugins.py::test_plugin_load_entry_point PASSED                [ 30%]
test/test_tools.py::test_get_sendable_message_default PASSED             [ 31%]
test/test_tools.py::test_get_sendable_message_limit PASSED               [ 31%]
test/test_tools.py::test_get_sendable_message_excess PASSED              [ 31%]
test/test_tools.py::test_get_sendable_message_excess_space PASSED        [ 31%]
test/test_tools.py::test_get_sendable_message_excess_space_limit PASSED  [ 31%]
test/test_tools.py::test_get_sendable_message_excess_bigger PASSED       [ 31%]
test/test_tools.py::test_get_sendable_message_optional PASSED            [ 31%]
test/test_tools.py::test_get_sendable_message_two_bytes PASSED           [ 31%]
test/test_tools.py::test_get_sendable_message_three_bytes PASSED         [ 31%]
test/test_tools.py::test_get_sendable_message_four_bytes PASSED          [ 31%]
test/test_tools.py::test_get_sendable_message_bigger_multibyte_whitespace PASSED [ 31%]
test/test_tools.py::test_chain_loaders PASSED                            [ 31%]
test/test_trigger.py::test_basic_pretrigger PASSED                       [ 31%]
test/test_trigger.py::test_pm_pretrigger PASSED                          [ 31%]
test/test_trigger.py::test_quit_pretrigger PASSED                        [ 32%]
test/test_trigger.py::test_join_pretrigger PASSED                        [ 32%]
test/test_trigger.py::test_tags_pretrigger PASSED                        [ 32%]
test/test_trigger.py::test_intents_pretrigger PASSED                     [ 32%]
test/test_trigger.py::test_unusual_pretrigger PASSED                     [ 32%]
test/test_trigger.py::test_ctcp_intent_pretrigger PASSED                 [ 32%]
test/test_trigger.py::test_ctcp_data_pretrigger PASSED                   [ 32%]
test/test_trigger.py::test_ctcp_action_pretrigger PASSED                 [ 32%]
test/test_trigger.py::test_ctcp_action_trigger PASSED                    [ 32%]
test/test_trigger.py::test_ircv3_extended_join_pretrigger PASSED         [ 32%]
test/test_trigger.py::test_ircv3_extended_join_trigger PASSED            [ 32%]
test/test_trigger.py::test_ircv3_intents_trigger PASSED                  [ 32%]
test/test_trigger.py::test_ircv3_account_tag_trigger PASSED              [ 32%]
test/test_trigger.py::test_ircv3_server_time_trigger PASSED              [ 32%]
test/cli/test_cli_run.py::test_build_parser_start PASSED                 [ 33%]
test/cli/test_cli_run.py::test_build_parser_start_config PASSED          [ 33%]
test/cli/test_cli_run.py::test_build_parser_start_configdir PASSED       [ 33%]
test/cli/test_cli_run.py::test_build_parser_start_daemonize PASSED       [ 33%]
test/cli/test_cli_run.py::test_build_parser_start_quiet PASSED           [ 33%]
test/cli/test_cli_run.py::test_build_parser_stop PASSED                  [ 33%]
test/cli/test_cli_run.py::test_build_parser_stop_config PASSED           [ 33%]
test/cli/test_cli_run.py::test_build_parser_stop_configdir PASSED        [ 33%]
test/cli/test_cli_run.py::test_build_parser_stop_kill PASSED             [ 33%]
test/cli/test_cli_run.py::test_build_parser_stop_quiet PASSED            [ 33%]
test/cli/test_cli_run.py::test_build_parser_restart PASSED               [ 33%]
test/cli/test_cli_run.py::test_build_parser_restart_config PASSED        [ 33%]
test/cli/test_cli_run.py::test_build_parser_restart_configdir PASSED     [ 33%]
test/cli/test_cli_run.py::test_build_parser_restart_quiet PASSED         [ 34%]
test/cli/test_cli_run.py::test_build_parser_configure PASSED             [ 34%]
test/cli/test_cli_run.py::test_build_parser_configure_config PASSED      [ 34%]
test/cli/test_cli_run.py::test_build_parser_configure_configdir PASSED   [ 34%]
test/cli/test_cli_run.py::test_build_parser_configure_modules PASSED     [ 34%]
test/cli/test_cli_run.py::test_get_configuration PASSED                  [ 34%]
test/cli/test_cli_run.py::test_get_pid_filename_default PASSED           [ 34%]
test/cli/test_cli_run.py::test_get_pid_filename_named PASSED             [ 34%]
test/cli/test_cli_run.py::test_get_pid_filename_ext_not_cfg PASSED       [ 34%]
test/cli/test_cli_run.py::test_get_running_pid PASSED                    [ 34%]
test/cli/test_cli_run.py::test_get_running_pid_not_integer PASSED        [ 34%]
test/cli/test_cli_run.py::test_get_running_pid_no_file PASSED            [ 34%]
test/cli/test_cli_utils.py::test_green PASSED                            [ 34%]
test/cli/test_cli_utils.py::test_red PASSED                              [ 34%]
test/cli/test_cli_utils.py::test_yellow PASSED                           [ 35%]
test/cli/test_cli_utils.py::test_enumerate_configs PASSED                [ 35%]
test/cli/test_cli_utils.py::test_enumerate_configs_not_a_directory PASSED [ 35%]
test/cli/test_cli_utils.py::test_enumerate_configs_extension PASSED      [ 35%]
test/cli/test_cli_utils.py::test_find_config_local PASSED                [ 35%]
test/cli/test_cli_utils.py::test_find_config_default PASSED              [ 35%]
test/cli/test_cli_utils.py::test_find_config_extension PASSED            [ 35%]
test/cli/test_cli_utils.py::test_add_common_arguments PASSED             [ 35%]
test/cli/test_cli_utils.py::test_add_common_arguments_subparser PASSED   [ 35%]
test/cli/test_cli_utils.py::test_get_many_text[items0-] PASSED           [ 35%]
test/cli/test_cli_utils.py::test_get_many_text[items1-the a element] PASSED [ 35%]
test/cli/test_cli_utils.py::test_get_many_text[items2-elements a and b] PASSED [ 35%]
test/cli/test_cli_utils.py::test_get_many_text[items3-elements a, b, and c] PASSED [ 35%]
test/cli/test_cli_utils.py::test_get_many_text[items4-elements a, b, c, and d] PASSED [ 36%]
test/cli/test_cli_utils.py::test_load_settings PASSED                    [ 36%]
test/cli/test_cli_utils.py::test_load_settings_arg_priority_over_env PASSED [ 36%]
test/cli/test_cli_utils.py::test_load_settings_default PASSED            [ 36%]
test/cli/test_cli_utils.py::test_load_settings_default_env_var PASSED    [ 36%]
test/cli/test_cli_utils.py::test_load_settings_default_not_found PASSED  [ 36%]
test/cli/test_cli_utils.py::test_load_settings_invalid PASSED            [ 36%]
test/config/test_config_types.py::test_validated_attribute PASSED        [ 36%]
test/config/test_config_types.py::test_validated_parse PASSED            [ 36%]
test/config/test_config_types.py::test_validated_parse_custom PASSED     [ 36%]
test/config/test_config_types.py::test_validated_parse_bool PASSED       [ 36%]
test/config/test_config_types.py::test_validated_parse_int PASSED        [ 36%]
test/config/test_config_types.py::test_validated_serialize PASSED        [ 36%]
test/config/test_config_types.py::test_validated_serialize_custom PASSED [ 36%]
test/config/test_config_types.py::test_validated_serialize_bool PASSED   [ 37%]
test/config/test_config_types.py::test_validated_serialize_bool_custom PASSED [ 37%]
test/config/test_config_types.py::test_boolean_attribute PASSED          [ 37%]
test/config/test_config_types.py::test_boolean_parse PASSED              [ 37%]
test/config/test_config_types.py::test_boolean_serialize PASSED          [ 37%]
test/config/test_config_types.py::test_secret_attribute PASSED           [ 37%]
test/config/test_config_types.py::test_list_attribute PASSED             [ 37%]
test/config/test_config_types.py::test_list_parse_single_value PASSED    [ 37%]
test/config/test_config_types.py::test_list_parse_new_lines PASSED       [ 37%]
test/config/test_config_types.py::test_list_parse_new_lines_no_strip PASSED [ 37%]
test/config/test_config_types.py::test_list_parse_legacy_comma PASSED    [ 37%]
test/config/test_config_types.py::test_list_parse_legacy_comma_no_strip PASSED [ 37%]
test/config/test_config_types.py::test_list_parse_new_lines_legacy_comma PASSED [ 37%]
test/config/test_config_types.py::test_list_serialize PASSED             [ 37%]
test/config/test_config_types.py::test_list_serialize_quote PASSED       [ 38%]
test/config/test_config_types.py::test_list_serialize_value_error PASSED [ 38%]
test/config/test_config_types.py::test_choice_attribute PASSED           [ 38%]
test/config/test_config_types.py::test_choice_parse PASSED               [ 38%]
test/config/test_config_types.py::test_choice_serialize PASSED           [ 38%]
test/config/test_config_types.py::test_filename_attribute PASSED         [ 38%]
test/config/test_config_types.py::test_filename_parse PASSED             [ 38%]
test/config/test_config_types.py::test_filename_parse_create PASSED      [ 38%]
test/config/test_config_types.py::test_filename_parse_directory PASSED   [ 38%]
test/config/test_config_types.py::test_filename_parse_directory_create PASSED [ 38%]
test/irc/test_irc_abstract_backends.py::test_prepare_command PASSED      [ 38%]
test/irc/test_irc_abstract_backends.py::test_prepare_command_text PASSED [ 38%]
test/irc/test_irc_abstract_backends.py::test_prepare_command_text_too_long PASSED [ 38%]
test/irc/test_irc_abstract_backends.py::test_send_command PASSED         [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_command_args PASSED    [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_command_text PASSED    [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_command_args_text PASSED [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_command_args_text_safe PASSED [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_command_args_text_many PASSED [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_ping PASSED            [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_pong PASSED            [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_nick PASSED            [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_user PASSED            [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_pass PASSED            [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_join PASSED            [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_join_secret PASSED     [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_part PASSED            [ 39%]
test/irc/test_irc_abstract_backends.py::test_send_part_text PASSED       [ 40%]
test/irc/test_irc_abstract_backends.py::test_send_quit PASSED            [ 40%]
test/irc/test_irc_abstract_backends.py::test_send_quit_text PASSED       [ 40%]
test/irc/test_irc_abstract_backends.py::test_send_quit_disconnected PASSED [ 40%]
test/irc/test_irc_abstract_backends.py::test_send_kick PASSED            [ 40%]
test/irc/test_irc_abstract_backends.py::test_send_kick_text PASSED       [ 40%]
test/irc/test_irc_abstract_backends.py::test_send_privmsg PASSED         [ 40%]
test/irc/test_irc_abstract_backends.py::test_send_privmsg_safe PASSED    [ 40%]
test/irc/test_irc_abstract_backends.py::test_send_notice PASSED          [ 40%]
test/irc/test_irc_abstract_backends.py::test_send_notice_safe PASSED     [ 40%]
test/irc/test_irc_isupport.py::test_isupport_apply PASSED                [ 40%]
test/irc/test_irc_isupport.py::test_isupport_apply_case_insensitive PASSED [ 40%]
test/irc/test_irc_isupport.py::test_isupport_removed_parameter PASSED    [ 40%]
test/irc/test_irc_isupport.py::test_isupport_get PASSED                  [ 40%]
test/irc/test_irc_isupport.py::test_isupport_getitem PASSED              [ 41%]
test/irc/test_irc_isupport.py::test_isupport_getitem_case_insensitive PASSED [ 41%]
test/irc/test_irc_isupport.py::test_isupport_getattr PASSED              [ 41%]
test/irc/test_irc_isupport.py::test_isupport_setitem PASSED              [ 41%]
test/irc/test_irc_isupport.py::test_isupport_chanlimit PASSED            [ 41%]
test/irc/test_irc_isupport.py::test_isupport_chanlimit_undefined PASSED  [ 41%]
test/irc/test_irc_isupport.py::test_isupport_chanmodes PASSED            [ 41%]
test/irc/test_irc_isupport.py::test_isupport_chanmodes_undefined PASSED  [ 41%]
test/irc/test_irc_isupport.py::test_isupport_maxlist PASSED              [ 41%]
test/irc/test_irc_isupport.py::test_isupport_maxlist_undefined PASSED    [ 41%]
test/irc/test_irc_isupport.py::test_isupport_prefix PASSED               [ 41%]
test/irc/test_irc_isupport.py::test_isupport_prefix_undefined PASSED     [ 41%]
test/irc/test_irc_isupport.py::test_isupport_targmax PASSED              [ 41%]
test/irc/test_irc_isupport.py::test_isupport_targmax_optional PASSED     [ 42%]
test/irc/test_irc_isupport.py::test_isupport_targmax_undefined PASSED    [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[AWAYLEN=50-expected0] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[CASEMAPPING=ascii-expected1] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[CHANNELLEN=31-expected2] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[CHANTYPES=#~-expected3] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[EXCEPTS=d-expected4] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[HOSTLEN=64-expected5] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[INVEX=J-expected6] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[KICKLEN=307-expected7] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[MAXTARGETS=5-expected8] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[MODES=5-expected9] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[NETWORK=Freenode-expected10] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[NICKLEN=31-expected11] PASSED [ 42%]
test/irc/test_irc_isupport.py::test_parse_parameter[SILENCE=5-expected12] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter[STATUSMSG-expected13] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter[STATUSMSG=ABCD-expected14] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter[TOPICLEN=5-expected15] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter[USERLEN=5-expected16] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter_optional[CHANTYPES-expected0] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter_optional[EXCEPTS-expected1] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter_optional[INVEX-expected2] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter_optional[MAXTARGETS-expected3] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter_optional[MODES-expected4] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter_optional[SILENCE-expected5] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter_no_value[SAFELIST-expected0] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter_single_letter_raise[EXCEPTS=ed] PASSED [ 43%]
test/irc/test_irc_isupport.py::test_parse_parameter_single_letter_raise[EXCEPTS=edoui] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_single_letter_raise[INVEX=IJ] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_single_letter_raise[INVEX=IJKLMNOP] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-AWAYLEN] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-CASEMAPPING] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-CHANLIMIT] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-CHANMODES] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-CHANNELLEN] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-CHANTYPES] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-ELIST] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-EXCEPTS] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-EXTBAN] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-HOSTLEN] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-INVEX] PASSED [ 44%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-KICKLEN] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-MAXLIST] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-MAXTARGETS] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-MODES] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-NETWORK] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-NICKLEN] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-PREFIX] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-SAFELIST] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-SILENCE] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-STATUSMSG] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-TARGMAX] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-TOPICLEN] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_removed[-USERLEN] PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_chanlimit_single PASSED [ 45%]
test/irc/test_irc_isupport.py::test_parse_parameter_chanlimit_many PASSED [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_chanlimit_limit_optional PASSED [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_chanmode PASSED      [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_chanmode_extra PASSED [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_chanmode_extra_many PASSED [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_chanmode_raise PASSED [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_elist PASSED         [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_elist_many PASSED    [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_elist_many_sorted PASSED [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_extban PASSED        [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_extban_no_prefix PASSED [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_extban_invalid PASSED [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_maxlist PASSED       [ 46%]
test/irc/test_irc_isupport.py::test_parse_parameter_maxlist_many PASSED  [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_maxlist_many_mixed PASSED [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_maxlist_many_mixed_override PASSED [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_maxlist_invalid PASSED [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_prefix PASSED        [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_prefix_invalid_format PASSED [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_prefix_order_parser PASSED [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_prefix_order_property PASSED [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_targmax PASSED       [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_targmax_optional PASSED [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_targmax_many PASSED  [ 47%]
test/irc/test_irc_isupport.py::test_parse_parameter_targmax_many_optional PASSED [ 47%]
test/irc/test_irc_modes.py::test_parse_modestring[a-result0] PASSED      [ 47%]
test/irc/test_irc_modes.py::test_parse_modestring[+a-result1] PASSED     [ 47%]
test/irc/test_irc_modes.py::test_parse_modestring[-a-result2] PASSED     [ 48%]
test/irc/test_irc_modes.py::test_parse_modestring[+a-b-result3] PASSED   [ 48%]
test/irc/test_irc_modes.py::test_parse_modestring[-a+b-result4] PASSED   [ 48%]
test/irc/test_irc_modes.py::test_parse_modestring[+ab-cd-result5] PASSED [ 48%]
test/irc/test_irc_modes.py::test_parse_modestring[+a-b+c-d-result6] PASSED [ 48%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_type[b-A] PASSED   [ 48%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_type[c-A] PASSED   [ 48%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_type[e-B] PASSED   [ 48%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_type[f-B] PASSED   [ 48%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_type[g-B] PASSED   [ 48%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_type_empty PASSED  [ 48%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_type_unknown PASSED [ 48%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[b-True-result0] PASSED [ 48%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[b-False-result1] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[c-True-result2] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[c-False-result3] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[e-True-result4] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[e-False-result5] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[f-True-result6] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[f-False-result7] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[g-True-result8] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[g-False-result9] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[i-True-result10] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[i-False-result11] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[j-True-result12] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[j-False-result13] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[k-True-result14] PASSED [ 49%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[k-False-result15] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[l-True-result16] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[l-False-result17] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[m-True-result18] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info[m-False-result19] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_empty PASSED  [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_privileges[v] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_privileges[h] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_privileges[a] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_privileges[q] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_privileges[o] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_privileges[y] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_privileges[Y] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_empty_privileges_config[v] PASSED [ 50%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_empty_privileges_config[h] PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_empty_privileges_config[a] PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_empty_privileges_config[q] PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_empty_privileges_config[o] PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_empty_privileges_config[y] PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_empty_privileges_config[Y] PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_no_param_config PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_get_mode_info_custom_privileges PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_parse_modestring_default PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_parse_modestring_single_mode PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_parse_modestring_multi_mode_add_only PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_parse_modestring_multi_mode_remove_only PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_parse_modestring_multi_mode_mixed_add_remove PASSED [ 51%]
test/irc/test_irc_modes.py::test_modemessage_parse_modestring_leftover_params PASSED [ 52%]
test/irc/test_irc_modes.py::test_modemessage_parse_modestring_ignored_modes PASSED [ 52%]
test/irc/test_irc_modes.py::test_modemessage_parse_modestring_no_params PASSED [ 52%]
test/irc/test_irc_modes.py::test_modemessage_parse_modestring_missing_params PASSED [ 52%]
test/irc/test_irc_utils.py::test_safe PASSED                             [ 52%]
test/irc/test_irc_utils.py::test_safe_empty PASSED                       [ 52%]
test/irc/test_irc_utils.py::test_safe_null PASSED                        [ 52%]
test/irc/test_irc_utils.py::test_safe_bytes PASSED                       [ 52%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[justanick-justanick!*@*] PASSED [ 52%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[just-a.host-*!*@just-a.host] PASSED [ 52%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[justauser@-*!justauser@*] PASSED [ 52%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[someuser@just-a.host-*!someuser@just-a.host] PASSED [ 52%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[someuser@dotlesshost-*!someuser@dotlesshost] PASSED [ 52%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[somenick!someuser-somenick!someuser@*] PASSED [ 52%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[somenick!someuser@-somenick!someuser@*0] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[somenick!someuser@-somenick!someuser@*1] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[full!host@mask-full!host@mask] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[full!mask@host.with.dots-full!mask@host.with.dots] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask[libera/style/cloak-*!*@libera/style/cloak] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask_invalid[mask with whitespace] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask_invalid[cloak/with whitespace] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask_invalid[nick!auser@something with whitespace] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask_invalid[nick with spaces!user@host] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask_invalid[nick!user with spaces@host] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask_invalid[two!user!names@host] PASSED [ 53%]
test/modules/test_modules_adminchannel.py::test_configureHostMask_invalid[two!user@host@names] PASSED [ 53%]
test/modules/test_modules_announce.py::test_chunks PASSED                [ 53%]
test/modules/test_modules_choose.py::test_format_safe_basic PASSED       [ 54%]
test/modules/test_modules_choose.py::test_format_safe_control PASSED     [ 54%]
test/modules/test_modules_choose.py::test_format_safe_invalid_arg PASSED [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[-] PASSED    [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[a-a] PASSED  [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[aa-aa] PASSED [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[\x02-\x02\x0f] PASSED [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[  leading space-leading space] PASSED [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[trailing space -trailing space] PASSED [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[ leading AND trailing space  -leading AND trailing space] PASSED [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[\tleading tab-leading tab] PASSED [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[trailing tab\t-trailing tab] PASSED [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[\x02  leading space inside formatting\x02-\x02  leading space inside formatting\x02\x0f] PASSED [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[\x02trailing space inside formatting  \x02-\x02trailing space inside formatting  \x02\x0f] PASSED [ 54%]
test/modules/test_modules_choose.py::test_format_safe_pairs[\x02  leading AND trailing inside formatting  \x02-\x02  leading AND trailing inside formatting  \x02\x0f] PASSED [ 55%]
test/modules/test_modules_choose.py::test_format_safe_pairs[  \x02leading space outside formatting\x02-\x02leading space outside formatting\x02\x0f] PASSED [ 55%]
test/modules/test_modules_choose.py::test_format_safe_pairs[\x02trailing space outside formatting\x02  -\x02trailing space outside formatting\x02\x0f] PASSED [ 55%]
test/modules/test_modules_choose.py::test_format_safe_pairs[  \x02  leading space inside AND outside\x02-\x02  leading space inside AND outside\x02\x0f] PASSED [ 55%]
test/modules/test_modules_choose.py::test_format_safe_pairs[\x02trailing space inside AND outside  \x02  -\x02trailing space inside AND outside  \x02\x0f] PASSED [ 55%]
test/modules/test_modules_choose.py::test_format_safe_pairs[  \x02  leading AND trailing inside AND outside  \x02  -\x02  leading AND trailing inside AND outside  \x02\x0f] PASSED [ 55%]
test/modules/test_modules_choose.py::test_format_safe_pairs[\x02unterminated bold-\x02unterminated bold\x0f] PASSED [ 55%]
test/modules/test_modules_choose.py::test_format_safe_pairs[only last word \x02bold-only last word \x02bold\x0f] PASSED [ 55%]
test/modules/test_modules_choose.py::test_format_safe_pairs[ leading space, \x03italic\x03, and \x02bold with extra spaces  -leading space, \x03italic\x03, and \x02bold with extra spaces\x0f] PASSED [ 55%]
test/modules/test_modules_choose.py::test_format_safe_future[\x02  leading space inside formatting\x02-\x02  leading space inside formatting\x02] XFAIL [ 55%]
test/modules/test_modules_choose.py::test_format_safe_future[\x02trailing space inside formatting  \x02-\x02trailing space inside formatting  \x02] XFAIL [ 55%]
test/modules/test_modules_choose.py::test_format_safe_future[\x02  leading AND trailing inside formatting  \x02-\x02  leading AND trailing inside formatting  \x02] XFAIL [ 55%]
test/modules/test_modules_choose.py::test_format_safe_future[  \x02leading space outside formatting\x02-\x02leading space outside formatting\x02] XFAIL [ 55%]
test/modules/test_modules_choose.py::test_format_safe_future[\x02trailing space outside formatting\x02  -\x02trailing space outside formatting\x02] XFAIL [ 55%]
test/modules/test_modules_choose.py::test_format_safe_future[  \x02  leading space inside AND outside\x02-\x02  leading space inside AND outside\x02] XFAIL [ 56%]
test/modules/test_modules_choose.py::test_format_safe_future[\x02trailing space inside AND outside  \x02  -\x02trailing space inside AND outside  \x02] XFAIL [ 56%]
test/modules/test_modules_choose.py::test_format_safe_future[  \x02  leading AND trailing inside AND outside  \x02  -\x02  leading AND trailing inside AND outside  \x02] XFAIL [ 56%]
test/modules/test_modules_find_updates.py::test_check_version_request_fails ERROR [ 56%]
test/modules/test_modules_isup.py::test_get_site_url[www.example.com-http://www.example.com] PASSED [ 56%]
test/modules/test_modules_isup.py::test_get_site_url[http://example.com-http://example.com] PASSED [ 56%]
test/modules/test_modules_isup.py::test_get_site_url[https://example.com-https://example.com] PASSED [ 56%]
test/modules/test_modules_isup.py::test_get_site_url[http://example.com/path-http://example.com/path] PASSED [ 56%]
test/modules/test_modules_isup.py::test_get_site_url[https://example.com/path-https://example.com/path] PASSED [ 56%]
test/modules/test_modules_isup.py::test_get_site_url[http://example.com/path?p=val-http://example.com/path?p=val] PASSED [ 56%]
test/modules/test_modules_isup.py::test_get_site_url[https://example.com/path?p=val-https://example.com/path?p=val] PASSED [ 56%]
test/modules/test_modules_isup.py::test_get_site_url[example.io-http://example.io] PASSED [ 56%]
test/modules/test_modules_isup.py::test_get_site_url[www.example.io-http://www.example.io] PASSED [ 56%]
test/modules/test_modules_isup.py::test_get_site_url_invalid[None] PASSED [ 57%]
test/modules/test_modules_isup.py::test_get_site_url_invalid[] PASSED    [ 57%]
test/modules/test_modules_isup.py::test_get_site_url_invalid[      ] PASSED [ 57%]
test/modules/test_modules_isup.py::test_get_site_url_invalid[steam://browsemedia] PASSED [ 57%]
test/modules/test_modules_isup.py::test_get_site_url_invalid[://] PASSED [ 57%]
test/modules/test_modules_isup.py::test_get_site_url_invalid[example] PASSED [ 57%]
test/modules/test_modules_isup.py::test_get_site_url_invalid[something.local] PASSED [ 57%]
test/modules/test_modules_isup.py::test_get_site_url_invalid[something.local:8080] PASSED [ 57%]
test/modules/test_modules_isup.py::test_get_site_url_invalid[lanmachine/path/to/iot.device] PASSED [ 57%]
test/modules/test_modules_isup.py::test_get_site_url_invalid[lanmachine:8080/path/to/iot.device] PASSED [ 57%]
test/modules/test_modules_isup.py::test_isup_command_ok ERROR            [ 57%]
test/modules/test_modules_isup.py::test_isup_command_http_error ERROR    [ 57%]
test/modules/test_modules_isup.py::test_isup_command_unparseable ERROR   [ 57%]
test/modules/test_modules_isup.py::test_isup_command_requests_error[ConnectionError-http://127.0.0.1:1 looks down to me (connection error).] ERROR [ 57%]
test/modules/test_modules_isup.py::test_isup_command_requests_error[ReadTimeout-https://httpbingo.org/delay/10 looks down to me (timed out waiting for reply).] ERROR [ 58%]
test/modules/test_modules_isup.py::test_isup_command_requests_error[ConnectTimeout-http://10.0.0.0 looks down to me (timed out while connecting).] ERROR [ 58%]
test/modules/test_modules_isup.py::test_isup_command_requests_error[SSLError-https://expired.badssl.com/ looks down to me (SSL error). Try using `.isupinsecure`.] ERROR [ 58%]
test/modules/test_modules_isup.py::test_isupinsecure_command ERROR       [ 58%]
test/modules/test_modules_reddit.py::test_url_matching[auto_subreddit_info-https://reddit.com/r/subname] ERROR [ 58%]
test/modules/test_modules_reddit.py::test_url_matching[auto_subreddit_info-https://reddit.com/r/subname/] ERROR [ 58%]
test/modules/test_modules_reddit.py::test_url_matching[auto_subreddit_info-https://www.reddit.com/r/subname] ERROR [ 58%]
test/modules/test_modules_reddit.py::test_url_matching[auto_subreddit_info-https://www.reddit.com/r/subname/] ERROR [ 58%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://redd.it/123456] ERROR [ 58%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://redd.it/123456/] ERROR [ 58%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/123456] ERROR [ 58%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/123456/] ERROR [ 58%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/comments/123456] ERROR [ 58%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/comments/123456/] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456/] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456?param=value] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456/?param=value] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456?param=value] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/?param=value] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/post_title_slug/234567] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/post_title_slug/234567/] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/post_title_slug/234567] ERROR [ 59%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/post_title_slug/234567/] ERROR [ 60%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/post_title_slug/234567/?context=1337] ERROR [ 60%]
test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/post_title_slug/234567/?context=1337] ERROR [ 60%]
test/modules/test_modules_reddit.py::test_url_non_matching[https://reddit.com/r/subname?param=value] ERROR [ 60%]
test/modules/test_modules_reddit.py::test_url_non_matching[https://reddit.com/r/subname/?param=value] ERROR [ 60%]
test/modules/test_modules_reddit.py::test_url_non_matching[https://www.reddit.com/r/subname?param=value] ERROR [ 60%]
test/modules/test_modules_reddit.py::test_url_non_matching[https://www.reddit.com/r/subname/?param=value] ERROR [ 60%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[1:20 message-expected0] PASSED [ 60%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[01:20 message-expected1] PASSED [ 60%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37 message-expected2] PASSED [ 60%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00 message-expected3] PASSED [ 60%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00 10 message-expected4] PASSED [ 60%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00 03-05-2019 message-expected5] PASSED [ 60%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00 03/05/2019 message-expected6] PASSED [ 60%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00 03.05.2019 message-expected7] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00 03,05,2019 message-expected8] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00 03/05-2019 message-expected9] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00 message\tanother one-expected10] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00 ( \u2022\u1d17\u2022)\u03c8( \u2022\u1d17\u2022)\u03c8( \u2022\u1d17\u2022)\u03c8( \u2022\u1d17\u2022)\u03c8( \u2022\u1d17\u2022)\u03c8( \u2022\u1d17 ^B^]^_ITS CARDBACK TIME!!!!!!!!!!!!!!!!!!!!!!!^B^]^_( \u2022\u1d17\u2022)\u03c8( \u2022\u1d17\u2022)\u03c8( \u2022\u1d17\u2022)\u03c8( \u2022\u1d17\u2022)\u03c8( \u2022\u1d17\u2022)\u03c8( \u2022\u1d17\u2022)\u03c8-expected11] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37Europe/Paris message-expected12] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00Europe/Paris message-expected13] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[1:7 message-expected14] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:7 message-expected15] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[0000:20 message-expected16] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37 2019-10-09-expected17] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37Europe/Paris 2019-10-09-expected18] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match[13:37:00Europe/Paris 2019-10-09-expected19] PASSED [ 61%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[13:37:71 message-expected0] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[13:37:60 message-expected1] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[13:71:59 message-expected2] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[13:60:59 message-expected3] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[24:30:15 message-expected4] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[71:30:15 message-expected5] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[13:37:25 2019-12-32 message-expected6] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[13:37:25 2019-11-31 message-expected7] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[13:37:25 2019-13-01 message-expected8] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[13:37:25 0000-12-32 message-expected9] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[13:37:25 2019-00-32 message-expected10] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_parse_regex_match_invalid_duration[13:37:25 2019-12-00 message-expected11] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_regex_dont_match[] PASSED   [ 62%]
test/modules/test_modules_remind.py::test_at_regex_dont_match[1 message] PASSED [ 62%]
test/modules/test_modules_remind.py::test_at_regex_dont_match[01 message] PASSED [ 63%]
test/modules/test_modules_remind.py::test_at_regex_dont_match[13h message] PASSED [ 63%]
test/modules/test_modules_remind.py::test_at_regex_dont_match[13h37 message] PASSED [ 63%]
test/modules/test_modules_remind.py::test_at_regex_dont_match[1337 message] PASSED [ 63%]
test/modules/test_modules_remind.py::test_at_regex_dont_match[:20 message] PASSED [ 63%]
test/modules/test_modules_remind.py::test_at_regex_dont_match[13:37] PASSED [ 63%]
test/modules/test_modules_remind.py::test_at_regex_dont_match[13:37Europe/Paris] PASSED [ 63%]
test/modules/test_modules_remind.py::test_at_regex_dont_match[13:37:00Europe/Paris] PASSED [ 63%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[None-None-None-120-86340-UTC] PASSED [ 63%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[None-None-None-120-86340-Europe/Paris] PASSED [ 63%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[None-None-None-120-86340-America/Chicago] PASSED [ 63%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-04-120-86340-UTC] PASSED [ 63%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-04-120-86340-Europe/Paris] PASSED [ 63%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-04-120-86340-America/Chicago] PASSED [ 63%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-4-120-86340-UTC] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-4-120-86340-Europe/Paris] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-4-120-86340-America/Chicago] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-05-2019-120-86340-UTC] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-05-2019-120-86340-Europe/Paris] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-05-2019-120-86340-America/Chicago] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-5-2019-120-86340-UTC] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-5-2019-120-86340-Europe/Paris] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-5-2019-120-86340-America/Chicago] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-05-19-120-86340-UTC] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-05-19-120-86340-Europe/Paris] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-05-19-120-86340-America/Chicago] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-5-19-120-86340-UTC] PASSED [ 64%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-5-19-120-86340-Europe/Paris] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-5-19-120-86340-America/Chicago] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-None-120-86340-UTC] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-None-120-86340-Europe/Paris] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-None-120-86340-America/Chicago] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-None-120-86340-UTC] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-None-120-86340-Europe/Paris] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-None-120-86340-America/Chicago] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[05-2019-None-120-86340-UTC] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[05-2019-None-120-86340-Europe/Paris] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[05-2019-None-120-86340-America/Chicago] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[5-2019-None-120-86340-UTC] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[5-2019-None-120-86340-Europe/Paris] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[5-2019-None-120-86340-America/Chicago] PASSED [ 65%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-05-None-120-86340-UTC] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-05-None-120-86340-Europe/Paris] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-05-None-120-86340-America/Chicago] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-5-None-120-86340-UTC] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-5-None-120-86340-Europe/Paris] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[04-5-None-120-86340-America/Chicago] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-05-None-120-86340-UTC] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-05-None-120-86340-Europe/Paris] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-05-None-120-86340-America/Chicago] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-5-None-120-86340-UTC] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-5-None-120-86340-Europe/Paris] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[4-5-None-120-86340-America/Chicago] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-03-120-86340-UTC] PASSED [ 66%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-03-120-86340-Europe/Paris] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-03-120-86340-America/Chicago] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-3-120-86340-UTC] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-3-120-86340-Europe/Paris] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-3-120-86340-America/Chicago] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[03-05-2019-120-86340-UTC] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[03-05-2019-120-86340-Europe/Paris] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[03-05-2019-120-86340-America/Chicago] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[3-5-2019-120-86340-UTC] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[3-5-2019-120-86340-Europe/Paris] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[3-5-2019-120-86340-America/Chicago] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[03-05-19-120-86340-UTC] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[03-05-19-120-86340-Europe/Paris] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[03-05-19-120-86340-America/Chicago] PASSED [ 67%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[3-5-19-120-86340-UTC] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[3-5-19-120-86340-Europe/Paris] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[3-5-19-120-86340-America/Chicago] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-05-86520-86340-UTC] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-05-86520-86340-Europe/Paris] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-05-05-86520-86340-America/Chicago] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-5-86520-86340-UTC] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-5-86520-86340-Europe/Paris] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[2019-5-5-86520-86340-America/Chicago] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[05-05-2019-86520-86340-UTC] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[05-05-2019-86520-86340-Europe/Paris] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[05-05-2019-86520-86340-America/Chicago] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[5-5-2019-86520-86340-UTC] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[5-5-2019-86520-86340-Europe/Paris] PASSED [ 68%]
test/modules/test_modules_remind.py::test_timereminder_get_duration[5-5-2019-86520-86340-America/Chicago] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_different_timezone PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[0000-00-00] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[00-00-0000] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[00-00-00] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[2019-00-00] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[2019-00-05] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[2019-03-00] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[00-00-2019] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[00-05-2019] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[03-00-2019] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[00-00-None] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[03-00-None] PASSED [ 69%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[00-03-None] PASSED [ 70%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[01-13-None] PASSED [ 70%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[01-13-2019] PASSED [ 70%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[01-13-19] PASSED [ 70%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[2019-13-01] PASSED [ 70%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[32-12-None] PASSED [ 70%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[32-12-2019] PASSED [ 70%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[32-12-19] PASSED [ 70%]
test/modules/test_modules_remind.py::test_timereminder_get_duration_error[2019-12-32] PASSED [ 70%]
test/modules/test_modules_remind.py::test_get_filename PASSED            [ 70%]
test/modules/test_modules_remind.py::test_load_database_empty PASSED     [ 70%]
test/modules/test_modules_remind.py::test_load_database PASSED           [ 70%]
test/modules/test_modules_remind.py::test_load_database_tabs PASSED      [ 70%]
test/modules/test_modules_remind.py::test_load_database_weirdo PASSED    [ 70%]
test/modules/test_modules_remind.py::test_load_database_irc_formatting PASSED [ 71%]
test/modules/test_modules_remind.py::test_load_multiple_reminders_same_timestamp PASSED [ 71%]
test/modules/test_modules_remind.py::test_load_multiple_reminders_same_timestamp_microseconds_ignored PASSED [ 71%]
test/modules/test_modules_remind.py::test_dump_database PASSED           [ 71%]
test/modules/test_modules_tell.py::test_load_reminders_empty PASSED      [ 71%]
test/modules/test_modules_tell.py::test_load_reminders_one_tellee PASSED [ 71%]
test/modules/test_modules_tell.py::test_load_reminders_multiple_tellees PASSED [ 71%]
test/modules/test_modules_tell.py::test_load_reminders_irc_formatting PASSED [ 71%]
test/modules/test_modules_tell.py::test_dump_reminders_empty PASSED      [ 71%]
test/modules/test_modules_tell.py::test_dump_reminders_one_tellee PASSED [ 71%]
test/modules/test_modules_tell.py::test_dump_reminders_multiple_tellees PASSED [ 71%]
test/modules/test_modules_tell.py::test_nick_match_tellee PASSED         [ 71%]
test/modules/test_modules_tell.py::test_nick_match_tellee_wildcards PASSED [ 71%]
test/modules/test_modules_tell.py::test_get_reminders PASSED             [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_basic PASSED  [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_control PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_invalid_arg PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[-] PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[a-a] PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[aa-aa] PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[  leading space-leading space] PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[trailing space -trailing space ] PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[ leading AND trailing space  -leading AND trailing space  ] PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[\tleading tab-leading tab] PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[trailing tab\t-trailing tab\t] PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[\x02  leading space inside formatting\x02-\x02  leading space inside formatting\x02] PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[\x02trailing space inside formatting  \x02-\x02trailing space inside formatting  \x02] PASSED [ 72%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[\x02  leading AND trailing inside formatting  \x02-\x02  leading AND trailing inside formatting  \x02] PASSED [ 73%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[  \x02leading space outside formatting\x02-\x02leading space outside formatting\x02] PASSED [ 73%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[\x02trailing space outside formatting\x02  -\x02trailing space outside formatting\x02  ] PASSED [ 73%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[  \x02  leading space inside AND outside\x02-\x02  leading space inside AND outside\x02] PASSED [ 73%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[\x02trailing space inside AND outside  \x02  -\x02trailing space inside AND outside  \x02  ] PASSED [ 73%]
test/modules/test_modules_tell.py::test_format_safe_lstrip_pairs[  \x02  leading AND trailing inside AND outside  \x02  -\x02  leading AND trailing inside AND outside  \x02  ] PASSED [ 73%]
test/modules/test_modules_url.py::test_find_title_invalid[http://.example.com/] PASSED [ 73%]
test/modules/test_modules_url.py::test_find_title_invalid[http://example..com/] PASSED [ 73%]
test/modules/test_modules_url.py::test_find_title_invalid[http://?] PASSED [ 73%]
test/modules/test_modules_url.py::test_check_callbacks PASSED            [ 73%]
test/modules/test_modules_url.py::test_url_triggers_rules_and_auto_title PASSED [ 73%]
test/plugins/test_plugins_handlers.py::test_get_label_pymodule PASSED    [ 73%]
test/plugins/test_plugins_handlers.py::test_get_label_pyfile PASSED      [ 73%]
test/plugins/test_plugins_handlers.py::test_get_label_pyfile_loaded PASSED [ 73%]
test/plugins/test_plugins_handlers.py::test_get_label_entrypoint FAILED  [ 74%]
test/plugins/test_plugins_rules.py::test_manager_rule PASSED             [ 74%]
test/plugins/test_plugins_rules.py::test_manager_find PASSED             [ 74%]
test/plugins/test_plugins_rules.py::test_manager_search PASSED           [ 74%]
test/plugins/test_plugins_rules.py::test_manager_command PASSED          [ 74%]
test/plugins/test_plugins_rules.py::test_manager_nick_command PASSED     [ 74%]
test/plugins/test_plugins_rules.py::test_manager_action_command PASSED   [ 74%]
test/plugins/test_plugins_rules.py::test_manager_rule_and_command PASSED [ 74%]
test/plugins/test_plugins_rules.py::test_manager_url_callback PASSED     [ 74%]
test/plugins/test_plugins_rules.py::test_manager_unregister_plugin PASSED [ 74%]
test/plugins/test_plugins_rules.py::test_manager_unregister_plugin_url_callbacks PASSED [ 74%]
test/plugins/test_plugins_rules.py::test_manager_unregister_plugin_unknown PASSED [ 74%]
test/plugins/test_plugins_rules.py::test_manager_rule_trigger_on_event PASSED [ 74%]
test/plugins/test_plugins_rules.py::test_manager_has_command PASSED      [ 75%]
test/plugins/test_plugins_rules.py::test_manager_has_command_aliases PASSED [ 75%]
test/plugins/test_plugins_rules.py::test_manager_has_nick_command PASSED [ 75%]
test/plugins/test_plugins_rules.py::test_manager_has_nick_command_aliases PASSED [ 75%]
test/plugins/test_plugins_rules.py::test_manager_has_action_command PASSED [ 75%]
test/plugins/test_plugins_rules.py::test_manager_has_action_command_aliases PASSED [ 75%]
test/plugins/test_plugins_rules.py::test_rulemetrics PASSED              [ 75%]
test/plugins/test_plugins_rules.py::test_rule_str PASSED                 [ 75%]
test/plugins/test_plugins_rules.py::test_rule_str_no_plugin PASSED       [ 75%]
test/plugins/test_plugins_rules.py::test_rule_str_no_label PASSED        [ 75%]
test/plugins/test_plugins_rules.py::test_rule_str_no_plugin_no_label PASSED [ 75%]
test/plugins/test_plugins_rules.py::test_rule_get_rule_label PASSED      [ 75%]
test/plugins/test_plugins_rules.py::test_rule_get_rule_label_undefined PASSED [ 75%]
test/plugins/test_plugins_rules.py::test_rule_get_rule_label_handler PASSED [ 75%]
test/plugins/test_plugins_rules.py::test_rule_get_plugin_name PASSED     [ 76%]
test/plugins/test_plugins_rules.py::test_rule_get_usages PASSED          [ 76%]
test/plugins/test_plugins_rules.py::test_rule_get_test_parameters PASSED [ 76%]
test/plugins/test_plugins_rules.py::test_rule_get_doc PASSED             [ 76%]
test/plugins/test_plugins_rules.py::test_rule_get_priority PASSED        [ 76%]
test/plugins/test_plugins_rules.py::test_rule_get_output_prefix PASSED   [ 76%]
test/plugins/test_plugins_rules.py::test_rule_match PASSED               [ 76%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_group_match PASSED [ 76%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_action PASSED [ 76%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_bot_tag PASSED [ 76%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo PASSED  [ 76%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[True-True-True-True-True] PASSED [ 76%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[True-True-True-False-False] PASSED [ 76%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[True-True-False-True-True] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[True-True-False-False-True] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[True-False-True-True-True] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[True-False-True-False-False] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[True-False-False-True-False] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[True-False-False-False-False] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[False-True-True-True-True] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[False-True-True-False-False] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[False-True-False-True-True] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[False-True-False-False-True] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[False-False-True-True-True] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[False-False-True-False-False] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[False-False-False-True-True] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_privmsg_echo_and_bot_tag[False-False-False-False-True] PASSED [ 77%]
test/plugins/test_plugins_rules.py::test_rule_match_join PASSED          [ 78%]
test/plugins/test_plugins_rules.py::test_rule_match_event PASSED         [ 78%]
test/plugins/test_plugins_rules.py::test_rule_match_ctcp PASSED          [ 78%]
test/plugins/test_plugins_rules.py::test_rule_echo_message PASSED        [ 78%]
test/plugins/test_plugins_rules.py::test_rule_is_threaded PASSED         [ 78%]
test/plugins/test_plugins_rules.py::test_rule_unblockable PASSED         [ 78%]
test/plugins/test_plugins_rules.py::test_rule_parse_wildcard PASSED      [ 78%]
test/plugins/test_plugins_rules.py::test_rule_parse_starts_with PASSED   [ 78%]
test/plugins/test_plugins_rules.py::test_rule_parse_pattern PASSED       [ 78%]
test/plugins/test_plugins_rules.py::test_rule_execute PASSED             [ 78%]
test/plugins/test_plugins_rules.py::test_rule_from_callable PASSED       [ 78%]
test/plugins/test_plugins_rules.py::test_rule_from_callable_nick_placeholder PASSED [ 78%]
test/plugins/test_plugins_rules.py::test_rule_from_callable_nickname_placeholder PASSED [ 78%]
test/plugins/test_plugins_rules.py::test_rule_from_callable_lazy PASSED  [ 78%]
test/plugins/test_plugins_rules.py::test_rule_from_callable_invalid PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_rule_from_callable_lazy_invalid PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_rule_from_callable_lazy_invalid_no_regex PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable PASSED     [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_label PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_priority PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_event PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_ctcp_intent PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_allow_echo PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_threaded PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_unblockable PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_rate_limit PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_rate_limit_user PASSED [ 79%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_rate_limit_channel PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_rate_limit_server PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_examples PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_examples_test PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_examples_help PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_kwargs_from_callable_examples_doc PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_rule_rate_limit PASSED          [ 80%]
test/plugins/test_plugins_rules.py::test_rule_rate_limit_no_limit PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_rule_rate_limit_ignore_rate_limit PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_rule_rate_limit_messages PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_rule_rate_limit_messages_default PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_rule_rate_limit_messages_default_mixed PASSED [ 80%]
test/plugins/test_plugins_rules.py::test_command_str PASSED              [ 80%]
test/plugins/test_plugins_rules.py::test_command_str_subcommand PASSED   [ 80%]
test/plugins/test_plugins_rules.py::test_command_str_no_plugin PASSED    [ 81%]
test/plugins/test_plugins_rules.py::test_command_str_alias PASSED        [ 81%]
test/plugins/test_plugins_rules.py::test_command_get_rule_label PASSED   [ 81%]
test/plugins/test_plugins_rules.py::test_command_get_rule_label_subcommand PASSED [ 81%]
test/plugins/test_plugins_rules.py::test_command_get_usages PASSED       [ 81%]
test/plugins/test_plugins_rules.py::test_command_get_doc PASSED          [ 81%]
test/plugins/test_plugins_rules.py::test_command_has_alias PASSED        [ 81%]
test/plugins/test_plugins_rules.py::test_command_match PASSED            [ 81%]
test/plugins/test_plugins_rules.py::test_command_match_invalid_prefix PASSED [ 81%]
test/plugins/test_plugins_rules.py::test_command_match_aliases PASSED    [ 81%]
test/plugins/test_plugins_rules.py::test_command_match_subcommand PASSED [ 81%]
test/plugins/test_plugins_rules.py::test_command_match_subcommand_args PASSED [ 81%]
test/plugins/test_plugins_rules.py::test_command_match_subcommand_aliases PASSED [ 81%]
test/plugins/test_plugins_rules.py::test_command_from_callable PASSED    [ 81%]
test/plugins/test_plugins_rules.py::test_command_from_callable_subcommand PASSED [ 82%]
test/plugins/test_plugins_rules.py::test_command_from_callable_subcommand_aliases PASSED [ 82%]
test/plugins/test_plugins_rules.py::test_command_from_callable_regex_pattern PASSED [ 82%]
test/plugins/test_plugins_rules.py::test_command_from_callable_invalid PASSED [ 82%]
test/plugins/test_plugins_rules.py::test_command_escape_name PASSED      [ 82%]
test/plugins/test_plugins_rules.py::test_nick_command_str PASSED         [ 82%]
test/plugins/test_plugins_rules.py::test_nick_command_str_no_plugin PASSED [ 82%]
test/plugins/test_plugins_rules.py::test_nick_command_str_alias PASSED   [ 82%]
test/plugins/test_plugins_rules.py::test_nick_command_str_nick_alias PASSED [ 82%]
test/plugins/test_plugins_rules.py::test_nick_command_str_alias_and_nick_alias PASSED [ 82%]
test/plugins/test_plugins_rules.py::test_nick_command_get_rule_label PASSED [ 82%]
test/plugins/test_plugins_rules.py::test_nick_command_get_usages PASSED  [ 82%]
test/plugins/test_plugins_rules.py::test_nick_command_get_doc PASSED     [ 82%]
test/plugins/test_plugins_rules.py::test_nick_command_match PASSED       [ 83%]
test/plugins/test_plugins_rules.py::test_nick_command_match_args PASSED  [ 83%]
test/plugins/test_plugins_rules.py::test_nick_command_has_alias PASSED   [ 83%]
test/plugins/test_plugins_rules.py::test_nick_command_from_callable_invalid PASSED [ 83%]
test/plugins/test_plugins_rules.py::test_nick_command_from_callable PASSED [ 83%]
test/plugins/test_plugins_rules.py::test_nick_command_from_callable_regex_pattern PASSED [ 83%]
test/plugins/test_plugins_rules.py::test_action_command_str PASSED       [ 83%]
test/plugins/test_plugins_rules.py::test_action_command_str_no_plugin PASSED [ 83%]
test/plugins/test_plugins_rules.py::test_action_command_str_alias PASSED [ 83%]
test/plugins/test_plugins_rules.py::test_action_command_get_rule_label PASSED [ 83%]
test/plugins/test_plugins_rules.py::test_action_command_match PASSED     [ 83%]
test/plugins/test_plugins_rules.py::test_action_command_match_args PASSED [ 83%]
test/plugins/test_plugins_rules.py::test_action_command_has_alias PASSED [ 83%]
test/plugins/test_plugins_rules.py::test_action_command_match_ctcp PASSED [ 83%]
test/plugins/test_plugins_rules.py::test_action_command_from_callable_invalid PASSED [ 84%]
test/plugins/test_plugins_rules.py::test_action_command_from_callable PASSED [ 84%]
test/plugins/test_plugins_rules.py::test_action_command_from_callable_regex_pattern PASSED [ 84%]
test/plugins/test_plugins_rules.py::test_find_rule_str PASSED            [ 84%]
test/plugins/test_plugins_rules.py::test_find_rule_str_no_plugin PASSED  [ 84%]
test/plugins/test_plugins_rules.py::test_find_str_no_label PASSED        [ 84%]
test/plugins/test_plugins_rules.py::test_find_str_no_plugin_label PASSED [ 84%]
test/plugins/test_plugins_rules.py::test_find_rule_parse_pattern PASSED  [ 84%]
test/plugins/test_plugins_rules.py::test_find_rule_from_callable PASSED  [ 84%]
test/plugins/test_plugins_rules.py::test_search_rule_str PASSED          [ 84%]
test/plugins/test_plugins_rules.py::test_search_rule_str_no_plugin PASSED [ 84%]
test/plugins/test_plugins_rules.py::test_search_str_no_label PASSED      [ 84%]
test/plugins/test_plugins_rules.py::test_search_str_no_plugin_label PASSED [ 84%]
test/plugins/test_plugins_rules.py::test_search_rule_parse_pattern PASSED [ 85%]
test/plugins/test_plugins_rules.py::test_search_rule_from_callable PASSED [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_str PASSED         [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_str_no_plugin PASSED [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_str_no_label PASSED [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_str_no_plugin_label PASSED [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_parse PASSED       [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_match PASSED       [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_execute PASSED     [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_match_filter_intent PASSED [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_from_callable PASSED [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_from_callable_no_match_parameter PASSED [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_from_callable_lazy PASSED [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_from_callable_invalid PASSED [ 85%]
test/plugins/test_plugins_rules.py::test_url_callback_from_callable_lazy_invalid PASSED [ 86%]
test/tests/test_tests_mocks.py::test_backend_irc_send PASSED             [ 86%]
test/tests/test_tests_mocks.py::test_backend_clear_message_sent PASSED   [ 86%]
test/tools/test_tools_identifiers.py::test_ascii_lower[abcd-abcd] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_ascii_lower[ABCD-abcd] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_ascii_lower[abc[]d-abc[]d] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_ascii_lower[abc\\d-abc\\d] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_ascii_lower[abc~d-abc~d] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_ascii_lower[[A]B\\C~D-[a]b\\c~d] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_ascii_lower[\xd9N\xcf\xc7\xd4D\xc9-\xd9n\xcf\xc7\xd4d\xc9] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_rfc1459_lower[abcd-abcd] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_rfc1459_lower[ABCD-abcd] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_rfc1459_lower[abc[]d-abc{}d] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_rfc1459_lower[abc\\d-abc|d] PASSED [ 86%]
test/tools/test_tools_identifiers.py::test_rfc1459_lower[abc~d-abc^d] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_rfc1459_lower[[A]B\\C~D-{a}b|c^d] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_rfc1459_lower[\xd9N\xcf\xc7\xd4D\xc9-\xd9n\xcf\xc7\xd4d\xc9] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_rfc1459_strict_lower[abcd-abcd] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_rfc1459_strict_lower[ABCD-abcd] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_rfc1459_strict_lower[abc[]d-abc{}d] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_rfc1459_strict_lower[abc\\d-abc|d] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_rfc1459_strict_lower[abc~d-abc~d] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_rfc1459_strict_lower[[A]B\\C~D-{a}b|c~d] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_rfc1459_strict_lower[\xd9N\xcf\xc7\xd4D\xc9-\xd9n\xcf\xc7\xd4d\xc9] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_identifier_repr PASSED        [ 87%]
test/tools/test_tools_identifiers.py::test_identifier_default_casemapping[abcd-abcd-abcde-abc] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_identifier_default_casemapping[ABCD-abcd-ABCDE-abc] PASSED [ 87%]
test/tools/test_tools_identifiers.py::test_identifier_default_casemapping[abc[]d-abc{}d-abc[]de-abc{}] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_default_casemapping[abc\\d-abc|d-abc\\de-abc|] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_default_casemapping[abc~d-abc^d-abc~de-abc^] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_default_casemapping[[A]B\\C~D-{a}b|c^d-[A]B\\C~DE-{a}b|c^] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_ascii_casemapping[abcd-abcd] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_ascii_casemapping[ABCD-abcd] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_ascii_casemapping[abc[]d-abc[]d] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_ascii_casemapping[abc\\d-abc\\d] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_ascii_casemapping[abc~d-abc~d] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_ascii_casemapping[[A]B\\C~D-[a]b\\c~d] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_ascii_casemapping[\xd9N\xcf\xc7\xd4D\xc9-\xd9n\xcf\xc7\xd4d\xc9] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_casemapping[abcd-abcd] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_casemapping[ABCD-abcd] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_casemapping[abc[]d-abc{}d] PASSED [ 88%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_casemapping[abc\\d-abc|d] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_casemapping[abc~d-abc^d] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_casemapping[[A]B\\C~D-{a}b|c^d] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_casemapping[\xd9N\xcf\xc7\xd4D\xc9-\xd9n\xcf\xc7\xd4d\xc9] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_strict_casemapping[abcd-abcd] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_strict_casemapping[ABCD-abcd] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_strict_casemapping[abc[]d-abc{}d] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_strict_casemapping[abc\\d-abc|d] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_strict_casemapping[abc~d-abc~d] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_strict_casemapping[[A]B\\C~D-{a}b|c~d] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_rfc1459_strict_casemapping[\xd9N\xcf\xc7\xd4D\xc9-\xd9n\xcf\xc7\xd4d\xc9] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_compare_invalid[None] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_compare_invalid[0] PASSED [ 89%]
test/tools/test_tools_identifiers.py::test_identifier_compare_invalid[10] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_compare_invalid[3.14] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_compare_invalid[wrong_type4] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick[Exirel-chantypes0] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick[@Exirel-chantypes1] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick[+Exirel-chantypes2] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick[!Exirel-chantypes3] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick[&Exirel-chantypes4] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick_channel[#Exirel-chantypes0] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick_channel[+Exirel-chantypes1] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick_channel[!Exirel-chantypes2] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick_channel[&Exirel-chantypes3] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick_channel[@Exirel-chantypes4] PASSED [ 90%]
test/tools/test_tools_identifiers.py::test_identifier_is_nick_empty PASSED [ 90%]
test/tools/test_tools_jobs.py::test_jobscheduler_stop PASSED             [ 91%]
test/tools/test_tools_jobs.py::test_job_is_ready_to_run PASSED           [ 91%]
test/tools/test_tools_jobs.py::test_job_str PASSED                       [ 91%]
test/tools/test_tools_jobs.py::test_job_str_intervals PASSED             [ 91%]
test/tools/test_tools_jobs.py::test_job_str_handler PASSED               [ 91%]
test/tools/test_tools_jobs.py::test_job_str_handler_plugin PASSED        [ 91%]
test/tools/test_tools_jobs.py::test_job_str_label PASSED                 [ 91%]
test/tools/test_tools_jobs.py::test_job_str_label_plugin PASSED          [ 91%]
test/tools/test_tools_jobs.py::test_job_str_label_plugin_intervals PASSED [ 91%]
test/tools/test_tools_jobs.py::test_job_next PASSED                      [ 91%]
test/tools/test_tools_jobs.py::test_job_next_many PASSED                 [ 91%]
test/tools/test_tools_jobs.py::test_job_from_callable PASSED             [ 91%]
test/tools/test_tools_jobs.py::test_job_with PASSED                      [ 91%]
test/tools/test_tools_jobs.py::test_job_with_exception PASSED            [ 91%]
test/tools/test_tools_memories.py::test_sopel_identifier_memory_none PASSED [ 92%]
test/tools/test_tools_memories.py::test_sopel_identifier_memory_str PASSED [ 92%]
test/tools/test_tools_memories.py::test_sopel_identifier_memory_id PASSED [ 92%]
test/tools/test_tools_memories.py::test_sopel_identifier_memory_channel_str PASSED [ 92%]
test/tools/test_tools_target.py::test_channel PASSED                     [ 92%]
test/tools/test_tools_target.py::test_channel_add_user PASSED            [ 92%]
test/tools/test_tools_target.py::test_channel_add_user_voiced PASSED     [ 92%]
test/tools/test_tools_target.py::test_channel_add_user_multi_privileges PASSED [ 92%]
test/tools/test_tools_target.py::test_channel_add_user_replace PASSED    [ 92%]
test/tools/test_tools_target.py::test_channel_has_privilege PASSED       [ 92%]
test/tools/test_tools_target.py::test_channel_is_priv_level_unknown_user PASSED [ 92%]
test/tools/test_tools_target.py::test_channel_is_priv_level_unprivileged_user PASSED [ 92%]
test/tools/test_tools_target.py::test_channel_is_priv_level_voiced_user PASSED [ 92%]
test/tools/test_tools_target.py::test_channel_is_priv_level_halfop_user PASSED [ 93%]
test/tools/test_tools_target.py::test_channel_is_priv_level_op_user PASSED [ 93%]
test/tools/test_tools_target.py::test_channel_is_priv_level_admin_user PASSED [ 93%]
test/tools/test_tools_target.py::test_channel_is_priv_level_owner_user PASSED [ 93%]
test/tools/test_tools_target.py::test_channel_is_priv_level_oper_user PASSED [ 93%]
test/tools/test_tools_time.py::test_validate_timezone PASSED             [ 93%]
test/tools/test_tools_time.py::test_validate_timezone_none PASSED        [ 93%]
test/tools/test_tools_time.py::test_validate_timezone_invalid PASSED     [ 93%]
test/tools/test_tools_time.py::test_validate_format PASSED               [ 93%]
test/tools/test_tools_time.py::test_validate_format_none PASSED          [ 93%]
test/tools/test_tools_time.py::test_format_time[time_arg0-2021-07-04 - 17:07:06 +0000] PASSED [ 93%]
test/tools/test_tools_time.py::test_format_time[time_arg1-2021-07-04 - 17:07:06 +0000] PASSED [ 93%]
test/tools/test_tools_time.py::test_format_time[time_arg2-2021-07-04 - 17:07:06 +0000] PASSED [ 93%]
test/tools/test_tools_time.py::test_seconds_to_human PASSED              [ 93%]
test/tools/test_tools_time.py::test_seconds_to_human_timedelta PASSED    [ 94%]
test/tools/test_tools_time.py::test_seconds_to_human_granularity PASSED  [ 94%]
test/tools/test_tools_time.py::test_seconds_to_split PASSED              [ 94%]
test/tools/test_tools_time.py::test_get_time_unit PASSED                 [ 94%]
test/tools/test_tools_web.py::test_quote[C\xfa_Chulainn-C%C3%BA_Chulainn] PASSED [ 94%]
test/tools/test_tools_web.py::test_quote[Q\u0131zmeydan-Q%C4%B1zmeydan] PASSED [ 94%]
test/tools/test_tools_web.py::test_quote[G\xfcn\u0259\u015fli,_Saatly-G%C3%BCn%C9%99%C5%9Fli%2C_Saatly] PASSED [ 94%]
test/tools/test_tools_web.py::test_quote[Rozst\u0119pniewo-Rozst%C4%99pniewo] PASSED [ 94%]
test/tools/test_tools_web.py::test_quote[Two Blank Spaces-Two%20Blank%20Spaces] PASSED [ 94%]
test/tools/test_tools_web.py::test_quote[with+plus+signs-with%2Bplus%2Bsigns] PASSED [ 94%]
test/tools/test_tools_web.py::test_quote[Exclamatory!-Exclamatory%21] PASSED [ 94%]
test/tools/test_tools_web.py::test_quote[either/or-either/or] PASSED     [ 94%]
test/tools/test_tools_web.py::test_quote[questioning...?-questioning...%3F] PASSED [ 94%]
test/tools/test_tools_web.py::test_quote[100%-100%25] PASSED             [ 95%]
test/tools/test_tools_web.py::test_search_urls PASSED                    [ 95%]
test/tools/test_tools_web.py::test_search_urls_with_text PASSED          [ 95%]
test/tools/test_tools_web.py::test_search_urls_multiple_urls PASSED      [ 95%]
test/tools/test_tools_web.py::test_search_urls_multiple_urls_with_text PASSED [ 95%]
test/tools/test_tools_web.py::test_search_urls_multiple_urls_unique PASSED [ 95%]
test/tools/test_tools_web.py::test_search_urls_multiple_urls_unique_keep_ordering PASSED [ 95%]
test/tools/test_tools_web.py::test_search_urls_exclusion_char PASSED     [ 95%]
test/tools/test_tools_web.py::test_search_urls_exclusion_char_with_text PASSED [ 95%]
test/tools/test_tools_web.py::test_search_urls_exclusion_char_only_once PASSED [ 95%]
test/tools/test_tools_web.py::test_search_urls_default_schemes PASSED    [ 95%]
test/tools/test_tools_web.py::test_search_urls_defined_schemes[http] PASSED [ 95%]
test/tools/test_tools_web.py::test_search_urls_defined_schemes[https] PASSED [ 95%]
test/tools/test_tools_web.py::test_search_urls_defined_schemes[ftp] PASSED [ 95%]
test/tools/test_tools_web.py::test_search_urls_defined_schemes[steam] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_char[.] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_char[,] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_char[?] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_char[!] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_char['] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_char["] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_char[:] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_char[;] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_enclosing[(-)] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_enclosing[[-]] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_enclosing[{-}] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_remove_trailing_enclosing[<->] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[(-)-.] PASSED [ 96%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[(-)-,] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[(-)-?] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[(-)-!] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[(-)-'] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[(-)-"] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[(-)-:] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[(-)-;] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[[-]-.] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[[-]-,] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[[-]-?] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[[-]-!] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[[-]-'] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[[-]-"] PASSED [ 97%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[[-]-:] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[[-]-;] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[{-}-.] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[{-}-,] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[{-}-?] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[{-}-!] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[{-}-'] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[{-}-"] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[{-}-:] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[{-}-;] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[<->-.] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[<->-,] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[<->-?] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[<->-!] PASSED [ 98%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[<->-'] PASSED [ 99%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[<->-"] PASSED [ 99%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[<->-:] PASSED [ 99%]
test/tools/test_tools_web.py::test_trim_url_trailing_char_and_enclosing[<->-;] PASSED [ 99%]
test/tools/test_tools_web.py::test_unquote[C%C3%BA_Chulainn-C\xfa_Chulainn] PASSED [ 99%]
test/tools/test_tools_web.py::test_unquote[Q%C4%B1zmeydan-Q\u0131zmeydan] PASSED [ 99%]
test/tools/test_tools_web.py::test_unquote[G%C3%BCn%C9%99%C5%9Fli%2C_Saatly-G\xfcn\u0259\u015fli,_Saatly] PASSED [ 99%]
test/tools/test_tools_web.py::test_unquote[Rozst%C4%99pniewo-Rozst\u0119pniewo] PASSED [ 99%]
test/tools/test_tools_web.py::test_unquote[Two%20Blank%20Spaces-Two Blank Spaces] PASSED [ 99%]
test/tools/test_tools_web.py::test_unquote[with%2Bplus%2Bsigns-with+plus+signs] PASSED [ 99%]
test/tools/test_tools_web.py::test_unquote[Exclamatory%21-Exclamatory!] PASSED [ 99%]
test/tools/test_tools_web.py::test_unquote[either/or-either/or] PASSED   [ 99%]
test/tools/test_tools_web.py::test_unquote[questioning...%3F-questioning...?] PASSED [ 99%]
test/tools/test_tools_web.py::test_unquote[100%25-100%] PASSED           [100%]

==================================== ERRORS ====================================
____________________ ERROR at setup of test_bot_mixed_modes ____________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
________________ ERROR at setup of test_bot_mixed_mode_removal _________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_________________ ERROR at setup of test_bot_mixed_mode_types __________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
___________________ ERROR at setup of test_bot_unknown_mode ____________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_________________ ERROR at setup of test_bot_unknown_priv_mode _________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
__________________ ERROR at setup of test_bot_extra_mode_args __________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_______________ ERROR at setup of test_handle_rpl_channelmodeis ________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
____________ ERROR at setup of test_handle_rpl_channelmodeis_clear _____________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
______________________ ERROR at setup of test_mode_colon _______________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
__________ ERROR at setup of test_execute_perform_raise_not_connected __________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_____________ ERROR at setup of test_execute_perform_send_commands _____________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
___________ ERROR at setup of test_execute_perform_replaces_nickname ___________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
____________________ ERROR at setup of test_handle_isupport ____________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
______________ ERROR at setup of test_handle_isupport_casemapping ______________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_______________ ERROR at setup of test_handle_isupport_chantypes _______________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
______________ ERROR at setup of test_handle_isupport_bot_mode[] _______________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_____________ ERROR at setup of test_handle_isupport_bot_mode[Rw] ______________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_________ ERROR at setup of test_handle_isupport_bot_mode_override[B] __________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
________ ERROR at setup of test_handle_isupport_bot_mode_override[RBw] _________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
________________ ERROR at setup of test_handle_isupport_namesx _________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
________________ ERROR at setup of test_handle_isupport_uhnames ________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_______ ERROR at setup of test_handle_isupport_namesx_with_multi_prefix ________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
___________________ ERROR at setup of test_handle_rpl_myinfo ___________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_____________________ ERROR at setup of test_recv_chghost ______________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_________________ ERROR at setup of test_recv_chghost_invalid __________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_______________________ ERROR at setup of test_join_time _______________________
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
______ ERROR at setup of test_handle_rpl_namreply_with_malformed_uhnames _______
test/test_coretasks.py:31: in mockbot
    return botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
____________________ ERROR at setup of test_require_privmsg ____________________
test/test_module.py:32: in bot
    mockbot = botfactory.preloaded(settings)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
____________________ ERROR at setup of test_require_chanmsg ____________________
test/test_module.py:32: in bot
    mockbot = botfactory.preloaded(settings)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
____________________ ERROR at setup of test_require_account ____________________
test/test_module.py:32: in bot
    mockbot = botfactory.preloaded(settings)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
___________________ ERROR at setup of test_require_privilege ___________________
test/test_module.py:32: in bot
    mockbot = botfactory.preloaded(settings)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_____________________ ERROR at setup of test_require_admin _____________________
test/test_module.py:32: in bot
    mockbot = botfactory.preloaded(settings)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_____________________ ERROR at setup of test_require_owner _____________________
test/test_module.py:32: in bot
    mockbot = botfactory.preloaded(settings)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
________________________ ERROR at setup of test_example ________________________
test/test_module.py:32: in bot
    mockbot = botfactory.preloaded(settings)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
______________ ERROR at setup of test_check_version_request_fails ______________
file /home/snoopjedi/repos/sopel-src/test/modules/test_modules_find_updates.py, line 26
  def test_check_version_request_fails(mockbot, requests_mock):
E       fixture 'requests_mock' not found
>       available fixtures: anyio_backend, anyio_backend_name, anyio_backend_options, botfactory, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, configfactory, cov, doctest_namespace, ircfactory, mockbot, monkeypatch, no_cover, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory, triggerfactory, userfactory, vcr_cassette_dir
>       use 'pytest --fixtures [testpath]' for help on them.

/home/snoopjedi/repos/sopel-src/test/modules/test_modules_find_updates.py:26
____________________ ERROR at setup of test_isup_command_ok ____________________
test/modules/test_modules_isup.py:67: in bot
    return botfactory.preloaded(settings, ['isup'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
________________ ERROR at setup of test_isup_command_http_error ________________
test/modules/test_modules_isup.py:67: in bot
    return botfactory.preloaded(settings, ['isup'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_______________ ERROR at setup of test_isup_command_unparseable ________________
test/modules/test_modules_isup.py:67: in bot
    return botfactory.preloaded(settings, ['isup'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_isup_command_requests_error[ConnectionError-http://127.0.0.1:1 looks down to me (connection error).] _
test/modules/test_modules_isup.py:67: in bot
    return botfactory.preloaded(settings, ['isup'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_isup_command_requests_error[ReadTimeout-https://httpbingo.org/delay/10 looks down to me (timed out waiting for reply).] _
test/modules/test_modules_isup.py:67: in bot
    return botfactory.preloaded(settings, ['isup'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_isup_command_requests_error[ConnectTimeout-http://10.0.0.0 looks down to me (timed out while connecting).] _
test/modules/test_modules_isup.py:67: in bot
    return botfactory.preloaded(settings, ['isup'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_isup_command_requests_error[SSLError-https://expired.badssl.com/ looks down to me (SSL error). Try using `.isupinsecure`.] _
test/modules/test_modules_isup.py:67: in bot
    return botfactory.preloaded(settings, ['isup'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_________________ ERROR at setup of test_isupinsecure_command __________________
test/modules/test_modules_isup.py:67: in bot
    return botfactory.preloaded(settings, ['isup'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[auto_subreddit_info-https://reddit.com/r/subname] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[auto_subreddit_info-https://reddit.com/r/subname/] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[auto_subreddit_info-https://www.reddit.com/r/subname] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[auto_subreddit_info-https://www.reddit.com/r/subname/] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://redd.it/123456] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://redd.it/123456/] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/123456] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/123456/] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/comments/123456] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/comments/123456/] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456/] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456?param=value] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456/?param=value] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456?param=value] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/?param=value] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/post_title_slug/234567] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/post_title_slug/234567/] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/post_title_slug/234567] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/post_title_slug/234567/] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/post_title_slug/234567/?context=1337] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/post_title_slug/234567/?context=1337] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_non_matching[https://reddit.com/r/subname?param=value] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_non_matching[https://reddit.com/r/subname/?param=value] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_non_matching[https://www.reddit.com/r/subname?param=value] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_ ERROR at setup of test_url_non_matching[https://www.reddit.com/r/subname/?param=value] _
test/modules/test_modules_reddit.py:22: in bot
    return botfactory.preloaded(settings, ['reddit'])
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
=================================== FAILURES ===================================
_____________________________ test_example_duck_0 ______________________________
sopel/tests/pytest_plugin.py:141: in test
    raise AssertionError(message)
E   AssertionError: Output does not match the regex:
E   Pattern: https?:\/\/.*sopel.*
E   Output: No results found for 'sopel.chat irc bot'.
_____________________________ test_example_duck_1 ______________________________
sopel/tests/pytest_plugin.py:141: in test
    raise AssertionError(message)
E   AssertionError: Output does not match the regex:
E   Pattern: https?:\/\/grandorder\.wiki\/C%C3%BA_Chulainn.*
E   Output: No results found for 'site:grandorder.wiki chulainn alter'.
_________________________ test_example_title_command_0 _________________________
sopel/modules/url.py:375: in process_urls
    ips = [ip_address(parsed_url.hostname)]
/usr/lib/python3.8/ipaddress.py:53: in ip_address
    raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
E   ValueError: 'www.google.com' does not appear to be an IPv4 or IPv6 address

During handling of the above exception, another exception occurred:
sopel/tests/pytest_plugin.py:112: in test
    tested_func(wrapper, test_trigger)
sopel/modules/url.py:260: in title_command
    for url, title, domain, tinyurl, dispatched in process_urls(
sopel/modules/url.py:377: in process_urls
    ips = [ip_address(ip) for ip in dns.resolver.resolve(parsed_url.hostname)]
E   AttributeError: module 'dns.resolver' has no attribute 'resolve'
___________________ test_has_channel_privilege_no_privilege ____________________
test/test_bot.py:975: in test_has_channel_privilege_no_privilege
    sopel = botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_______________________ test_has_channel_privilege_voice _______________________
test/test_bot.py:1006: in test_has_channel_privilege_voice
    sopel = botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
______________________ test_has_channel_privilege_halfop _______________________
test/test_bot.py:1029: in test_has_channel_privilege_halfop
    sopel = botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
________________________ test_has_channel_privilege_op _________________________
test/test_bot.py:1052: in test_has_channel_privilege_op
    sopel = botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_______________________ test_has_channel_privilege_admin _______________________
test/test_bot.py:1075: in test_has_channel_privilege_admin
    sopel = botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_______________________ test_has_channel_privilege_owner _______________________
test/test_bot.py:1098: in test_has_channel_privilege_owner
    sopel = botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
_____________________ test_has_channel_privilege_operator ______________________
test/test_bot.py:1121: in test_has_channel_privilege_operator
    sopel = botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
________________________________ test_user_quit ________________________________
test/test_bot.py:1394: in test_user_quit
    mockbot: bot.Sopel = botfactory.preloaded(tmpconfig)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
__________________________ test_require_bot_privilege __________________________
test/test_plugin.py:375: in test_require_bot_privilege
    mockbot = botfactory.preloaded(settings)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
__________________ test_require_bot_privilege_private_message __________________
test/test_plugin.py:428: in test_require_bot_privilege_private_message
    mockbot = botfactory.preloaded(settings)
sopel/tests/factories.py:55: in preloaded
    usable_plugins = plugins.get_usable_plugins(settings)
sopel/plugins/__init__.py:225: in get_usable_plugins
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:225: in <genexpr>
    plugins_info = collections.OrderedDict(
sopel/plugins/__init__.py:185: in enumerate_plugins
    for plugin in all_plugins:
sopel/plugins/__init__.py:110: in find_entry_point_plugins
    for entry_point in importlib_metadata.entry_points(group=group):
E   TypeError: entry_points() got an unexpected keyword argument 'group'
__________________________ test_get_label_entrypoint ___________________________
test/plugins/test_plugins_handlers.py:79: in test_get_label_entrypoint
    meta = plugin.get_meta_description()
sopel/plugins/handlers.py:603: in get_meta_description
    data = super().get_meta_description()
sopel/plugins/handlers.py:302: in get_meta_description
    'version': self.get_version(),
sopel/plugins/handlers.py:578: in get_version
    version = importlib_metadata.version(self._module.__package__)
/usr/lib/python3/dist-packages/importlib_metadata/__init__.py:553: in version
    return distribution(distribution_name).version
/usr/lib/python3/dist-packages/importlib_metadata/__init__.py:526: in distribution
    return Distribution.from_name(distribution_name)
/usr/lib/python3/dist-packages/importlib_metadata/__init__.py:194: in from_name
    raise PackageNotFoundError(name)
E   importlib_metadata.PackageNotFoundError
=============================== warnings summary ===============================
sopel/plugin.py:1568
  /home/snoopjedi/repos/sopel-src/sopel/plugin.py:1568: PytestUnknownMarkWarning: Unknown pytest.mark.vcr - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
    test = pytest.mark.vcr(test)

-- Docs: https://docs.pytest.org/en/stable/warnings.html
=========================== short test summary info ============================
FAILED sopel/modules/search.py::test_example_duck_0 - AssertionError: Output ...
FAILED sopel/modules/search.py::test_example_duck_1 - AssertionError: Output ...
FAILED sopel/modules/url.py::test_example_title_command_0 - AttributeError: m...
FAILED test/test_bot.py::test_has_channel_privilege_no_privilege - TypeError:...
FAILED test/test_bot.py::test_has_channel_privilege_voice - TypeError: entry_...
FAILED test/test_bot.py::test_has_channel_privilege_halfop - TypeError: entry...
FAILED test/test_bot.py::test_has_channel_privilege_op - TypeError: entry_poi...
FAILED test/test_bot.py::test_has_channel_privilege_admin - TypeError: entry_...
FAILED test/test_bot.py::test_has_channel_privilege_owner - TypeError: entry_...
FAILED test/test_bot.py::test_has_channel_privilege_operator - TypeError: ent...
FAILED test/test_bot.py::test_user_quit - TypeError: entry_points() got an un...
FAILED test/test_plugin.py::test_require_bot_privilege - TypeError: entry_poi...
FAILED test/test_plugin.py::test_require_bot_privilege_private_message - Type...
FAILED test/plugins/test_plugins_handlers.py::test_get_label_entrypoint - imp...
ERROR test/test_coretasks.py::test_bot_mixed_modes - TypeError: entry_points(...
ERROR test/test_coretasks.py::test_bot_mixed_mode_removal - TypeError: entry_...
ERROR test/test_coretasks.py::test_bot_mixed_mode_types - TypeError: entry_po...
ERROR test/test_coretasks.py::test_bot_unknown_mode - TypeError: entry_points...
ERROR test/test_coretasks.py::test_bot_unknown_priv_mode - TypeError: entry_p...
ERROR test/test_coretasks.py::test_bot_extra_mode_args - TypeError: entry_poi...
ERROR test/test_coretasks.py::test_handle_rpl_channelmodeis - TypeError: entr...
ERROR test/test_coretasks.py::test_handle_rpl_channelmodeis_clear - TypeError...
ERROR test/test_coretasks.py::test_mode_colon - TypeError: entry_points() got...
ERROR test/test_coretasks.py::test_execute_perform_raise_not_connected - Type...
ERROR test/test_coretasks.py::test_execute_perform_send_commands - TypeError:...
ERROR test/test_coretasks.py::test_execute_perform_replaces_nickname - TypeEr...
ERROR test/test_coretasks.py::test_handle_isupport - TypeError: entry_points(...
ERROR test/test_coretasks.py::test_handle_isupport_casemapping - TypeError: e...
ERROR test/test_coretasks.py::test_handle_isupport_chantypes - TypeError: ent...
ERROR test/test_coretasks.py::test_handle_isupport_bot_mode[] - TypeError: en...
ERROR test/test_coretasks.py::test_handle_isupport_bot_mode[Rw] - TypeError: ...
ERROR test/test_coretasks.py::test_handle_isupport_bot_mode_override[B] - Typ...
ERROR test/test_coretasks.py::test_handle_isupport_bot_mode_override[RBw] - T...
ERROR test/test_coretasks.py::test_handle_isupport_namesx - TypeError: entry_...
ERROR test/test_coretasks.py::test_handle_isupport_uhnames - TypeError: entry...
ERROR test/test_coretasks.py::test_handle_isupport_namesx_with_multi_prefix
ERROR test/test_coretasks.py::test_handle_rpl_myinfo - TypeError: entry_point...
ERROR test/test_coretasks.py::test_recv_chghost - TypeError: entry_points() g...
ERROR test/test_coretasks.py::test_recv_chghost_invalid - TypeError: entry_po...
ERROR test/test_coretasks.py::test_join_time - TypeError: entry_points() got ...
ERROR test/test_coretasks.py::test_handle_rpl_namreply_with_malformed_uhnames
ERROR test/test_module.py::test_require_privmsg - TypeError: entry_points() g...
ERROR test/test_module.py::test_require_chanmsg - TypeError: entry_points() g...
ERROR test/test_module.py::test_require_account - TypeError: entry_points() g...
ERROR test/test_module.py::test_require_privilege - TypeError: entry_points()...
ERROR test/test_module.py::test_require_admin - TypeError: entry_points() got...
ERROR test/test_module.py::test_require_owner - TypeError: entry_points() got...
ERROR test/test_module.py::test_example - TypeError: entry_points() got an un...
ERROR test/modules/test_modules_find_updates.py::test_check_version_request_fails
ERROR test/modules/test_modules_isup.py::test_isup_command_ok - TypeError: en...
ERROR test/modules/test_modules_isup.py::test_isup_command_http_error - TypeE...
ERROR test/modules/test_modules_isup.py::test_isup_command_unparseable - Type...
ERROR test/modules/test_modules_isup.py::test_isup_command_requests_error[ConnectionError-http://127.0.0.1:1 looks down to me (connection error).]
ERROR test/modules/test_modules_isup.py::test_isup_command_requests_error[ReadTimeout-https://httpbingo.org/delay/10 looks down to me (timed out waiting for reply).]
ERROR test/modules/test_modules_isup.py::test_isup_command_requests_error[ConnectTimeout-http://10.0.0.0 looks down to me (timed out while connecting).]
ERROR test/modules/test_modules_isup.py::test_isup_command_requests_error[SSLError-https://expired.badssl.com/ looks down to me (SSL error). Try using `.isupinsecure`.]
ERROR test/modules/test_modules_isup.py::test_isupinsecure_command - TypeErro...
ERROR test/modules/test_modules_reddit.py::test_url_matching[auto_subreddit_info-https://reddit.com/r/subname]
ERROR test/modules/test_modules_reddit.py::test_url_matching[auto_subreddit_info-https://reddit.com/r/subname/]
ERROR test/modules/test_modules_reddit.py::test_url_matching[auto_subreddit_info-https://www.reddit.com/r/subname]
ERROR test/modules/test_modules_reddit.py::test_url_matching[auto_subreddit_info-https://www.reddit.com/r/subname/]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://redd.it/123456]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://redd.it/123456/]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/123456]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/123456/]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/comments/123456]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/comments/123456/]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456/]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456?param=value]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/comments/123456/?param=value]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456?param=value]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/?param=value]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/post_title_slug/234567]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/post_title_slug/234567/]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/post_title_slug/234567]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/post_title_slug/234567/]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://reddit.com/r/subname/comments/123456/post_title_slug/234567/?context=1337]
ERROR test/modules/test_modules_reddit.py::test_url_matching[post_or_comment_info-https://www.reddit.com/r/subname/comments/123456/post_title_slug/234567/?context=1337]
ERROR test/modules/test_modules_reddit.py::test_url_non_matching[https://reddit.com/r/subname?param=value]
ERROR test/modules/test_modules_reddit.py::test_url_non_matching[https://reddit.com/r/subname/?param=value]
ERROR test/modules/test_modules_reddit.py::test_url_non_matching[https://www.reddit.com/r/subname?param=value]
ERROR test/modules/test_modules_reddit.py::test_url_non_matching[https://www.reddit.com/r/subname/?param=value]
====== 14 failed, 1266 passed, 8 xfailed, 1 warning, 73 errors in 42.44s =======
/home/snoopjedi/.local/lib/python3.8/site-packages/_pytest/pathlib.py:80: PytestWarning: (rm_rf) error removing /tmp/pytest-of-snoopjedi/garbage-1ff2f8ce-81e9-47f2-934c-f62f1e8e25ac/test_safe_delete_no_perms0
<class 'OSError'>: [Errno 39] Directory not empty: 'test_safe_delete_no_perms0'
  warnings.warn(
/home/snoopjedi/.local/lib/python3.8/site-packages/_pytest/pathlib.py:80: PytestWarning: (rm_rf) error removing /tmp/pytest-of-snoopjedi/garbage-1ff2f8ce-81e9-47f2-934c-f62f1e8e25ac/test_safe_set_no_perms0
<class 'OSError'>: [Errno 39] Directory not empty: 'test_safe_set_no_perms0'
  warnings.warn(
/home/snoopjedi/.local/lib/python3.8/site-packages/_pytest/pathlib.py:80: PytestWarning: (rm_rf) error removing /tmp/pytest-of-snoopjedi/garbage-1ff2f8ce-81e9-47f2-934c-f62f1e8e25ac/test_rmtree_errorhandler_rerai0
<class 'OSError'>: [Errno 39] Directory not empty: 'test_rmtree_errorhandler_rerai0'
  warnings.warn(
/home/snoopjedi/.local/lib/python3.8/site-packages/_pytest/pathlib.py:80: PytestWarning: (rm_rf) error removing /tmp/pytest-of-snoopjedi/garbage-1ff2f8ce-81e9-47f2-934c-f62f1e8e25ac/test_rmtree_errorhandler_reado0
<class 'OSError'>: [Errno 39] Directory not empty: 'test_rmtree_errorhandler_reado0'
  warnings.warn(
/home/snoopjedi/.local/lib/python3.8/site-packages/_pytest/pathlib.py:80: PytestWarning: (rm_rf) error removing /tmp/pytest-of-snoopjedi/garbage-1ff2f8ce-81e9-47f2-934c-f62f1e8e25ac/test_safe_get_no_perms0
<class 'OSError'>: [Errno 39] Directory not empty: 'test_safe_get_no_perms0'
  warnings.warn(
/home/snoopjedi/.local/lib/python3.8/site-packages/_pytest/pathlib.py:80: PytestWarning: (rm_rf) error removing /tmp/pytest-of-snoopjedi/garbage-1ff2f8ce-81e9-47f2-934c-f62f1e8e25ac
<class 'OSError'>: [Errno 39] Directory not empty: '/tmp/pytest-of-snoopjedi/garbage-1ff2f8ce-81e9-47f2-934c-f62f1e8e25ac'
  warnings.warn(
make: *** [Makefile:13: test] Error 1

@dgw
Copy link
Member

dgw commented Aug 6, 2022

Ah, there are dev-only requirements (not needed at runtime) in dev-requirements.txt, which includes pytest and relevant plugins, among other niceties. The CONTRIBUTING.md file is getting an overhaul as part of #2328, including but not limited to clearer guidance on setting up the environment to run/test directly from source. Hopefully that will be finalized soon. 🙂

At present, my recommended way to get started from scratch is (from the top level of the sopel repo:

pip install -U -r requirements.txt -r dev-requirements.txt -e .

That should make sure you have the necessary versions of everything. If you still have problems with the tests after that, maybe try collaboratively debugging on IRC with whoever is around tomorrow (me, Exirel, etc.).

sopel/modules/seen.py Outdated Show resolved Hide resolved
@SnoopJ
Copy link
Contributor Author

SnoopJ commented Aug 6, 2022

Ah, there are dev-only requirements (not needed at runtime) in dev-requirements.txt, which includes pytest and relevant plugins, among other niceties.

D'oh! That's the very obvious thing I'd missed. make qa passes in full with the proper environment. Thanks for pointing out what should probably have been obvious (the dangers of working on a PR late at night, perhaps...)

The CONTRIBUTING.md file is getting an overhaul as part of #2328, including but not limited to clearer guidance on setting up the environment to run/test directly from source. Hopefully that will be finalized soon. 🙂

Sounds good, I can stop making a fool of myself with QA on each PR 😅

sopel/modules/seen.py Outdated Show resolved Hide resolved
Copy link
Contributor

@Exirel Exirel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better than nothing. I'm sure this will piss off people using Channel Logging, but it's still better than replying with errors for every message. So yeah, that's good to me.

@dgw dgw added this to the 8.0.0 milestone Sep 3, 2022
@dgw dgw added the Tweak label Sep 3, 2022
@dgw
Copy link
Member

dgw commented Sep 3, 2022

@SnoopJeDi Can you squash, and remove the "fixes" notation?

@SnoopJ SnoopJ force-pushed the bugfix/2305_database-error-cooldown branch from ef0a3d0 to c83da4a Compare September 3, 2022 03:36
@SnoopJ SnoopJ changed the title seen: catch database write errors (fixes #2305) seen: catch database write errors Sep 3, 2022
Co-authored-by: Florian Strzelecki <florian.strzelecki@gmail.com>
@SnoopJ SnoopJ force-pushed the bugfix/2305_database-error-cooldown branch from c83da4a to fbfb8e0 Compare September 3, 2022 20:28
@dgw dgw merged commit eff60e9 into sopel-irc:master Sep 3, 2022
@SnoopJ SnoopJ deleted the bugfix/2305_database-error-cooldown branch October 12, 2022 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants