From 73b2ac8d0681be38b822d010f48fde14d5a1f2f6 Mon Sep 17 00:00:00 2001 From: dgw Date: Sat, 9 Dec 2023 15:27:57 -0600 Subject: [PATCH 1/3] bot: `search_url_callbacks()` is a public shim now Actual implementation lives in a private method that can be called internally without raising a deprecation warning. --- sopel/bot.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sopel/bot.py b/sopel/bot.py index 11b5c25c2..5b16e1e74 100644 --- a/sopel/bot.py +++ b/sopel/bot.py @@ -1255,6 +1255,10 @@ def search_url_callbacks(self, url): .. __: https://docs.python.org/3.11/library/re.html#match-objects """ + return self._search_url_callbacks_impl(url) + + def _search_url_callbacks_impl(self, url): + # actual implementation, usable internally without warnings for regex, function in self._url_callbacks.items(): match = regex.search(url) if match: From 39ef1b252be35341afe2abae45f631b91ccc37e4 Mon Sep 17 00:00:00 2001 From: dgw Date: Sat, 9 Dec 2023 15:29:26 -0600 Subject: [PATCH 2/3] coretasks, url: use private `bot.search_url_callbacks()` implementation Core/builtin code bypasses the deprecation warning that will start in Sopel 8.1 this way (the public method isn't being removed until 9.0). --- sopel/builtins/url.py | 5 +++-- sopel/coretasks.py | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sopel/builtins/url.py b/sopel/builtins/url.py index 7383e0211..140dfce9d 100644 --- a/sopel/builtins/url.py +++ b/sopel/builtins/url.py @@ -502,8 +502,9 @@ def check_callbacks(bot: SopelWrapper, url: str, use_excludes: bool = True) -> b ) return ( excluded or - any(bot.search_url_callbacks(url)) or - bot.rules.check_url_callback(bot, url) + bot.rules.check_url_callback(bot, url) or + # don't do this in YOUR plugins + any(bot._search_url_callbacks_impl(url)) ) diff --git a/sopel/coretasks.py b/sopel/coretasks.py index f10ebdbe2..30434dc28 100644 --- a/sopel/coretasks.py +++ b/sopel/coretasks.py @@ -1608,6 +1608,8 @@ def track_topic(bot, trigger): LOGGER.info("Channel's topic updated: %s", channel) +# TODO: This needs to go away with the rest of the obsolete manually-registered- +# URL-callback system in Sopel 9.0 @plugin.rule(r'(?u).*(.+://\S+).*') def handle_url_callbacks(bot, trigger): """Dispatch callbacks on URLs @@ -1618,7 +1620,7 @@ def handle_url_callbacks(bot, trigger): # find URLs in the trigger for url in trigger.urls: # find callbacks for said URL - for function, match in bot.search_url_callbacks(url): + for function, match in bot._search_url_callbacks_impl(url): # trigger callback defined by the `@url` decorator if hasattr(function, 'url_regex'): # bake the `match` argument in before passing the callback on From 6b7f64d9d73b6f2dc4129870ef0db6b01a987b18 Mon Sep 17 00:00:00 2001 From: dgw Date: Sat, 9 Dec 2023 15:30:58 -0600 Subject: [PATCH 3/3] test: bypass deprecation warning in `bot.search_url_callbacks()` tests --- test/test_bot.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/test/test_bot.py b/test/test_bot.py index 964878bee..8f320e05e 100644 --- a/test/test_bot.py +++ b/test/test_bot.py @@ -1307,7 +1307,7 @@ def url_handler(*args, **kwargs): return None sopel.register_url_callback(r'https://example\.com', url_handler) - results = list(sopel.search_url_callbacks('https://example.com')) + results = list(sopel._search_url_callbacks_impl('https://example.com')) assert len(results) == 1, 'Expected 1 handler; found %d' % len(results) assert url_handler in results[0], 'Once registered, handler must be found' @@ -1320,11 +1320,11 @@ def url_handler(*args, **kwargs): return None sopel.register_url_callback(r'https://(www\.)?example\.com', url_handler) - results = list(sopel.search_url_callbacks('https://example.com')) + results = list(sopel._search_url_callbacks_impl('https://example.com')) assert len(results) == 1, 'Expected 1 handler; found %d' % len(results) assert url_handler in results[0], 'Once registered, handler must be found' - results = list(sopel.search_url_callbacks('https://www.example.com')) + results = list(sopel._search_url_callbacks_impl('https://www.example.com')) assert len(results) == 1, 'Regex pattern must match both URLs' assert url_handler in results[0] @@ -1338,11 +1338,11 @@ def url_handler(*args, **kwargs): return None sopel.register_url_callback(url_regex, url_handler) - results = list(sopel.search_url_callbacks('https://example.com')) + results = list(sopel._search_url_callbacks_impl('https://example.com')) assert len(results) == 1, 'Expected 1 handler; found %d' % len(results) assert url_handler in results[0], 'Once registered, handler must be found' - results = list(sopel.search_url_callbacks('https://www.example.com')) + results = list(sopel._search_url_callbacks_impl('https://www.example.com')) assert len(results) == 1, 'Regex pattern must match both URLs' assert url_handler in results[0] @@ -1350,7 +1350,7 @@ def url_handler(*args, **kwargs): def test_search_url_callbacks_not_found(tmpconfig): """Test search_url_callbacks when pattern does not match.""" sopel = bot.Sopel(tmpconfig, daemon=False) - results = sopel.search_url_callbacks('https://example.com') + results = sopel._search_url_callbacks_impl('https://example.com') assert not list(results), 'No handler registered; must return an empty list' def url_handler(*args, **kwargs): @@ -1358,7 +1358,7 @@ def url_handler(*args, **kwargs): sopel.register_url_callback(r'https://(www\.)?example\.com', url_handler) - results = sopel.search_url_callbacks('https://not-example.com') + results = sopel._search_url_callbacks_impl('https://not-example.com') assert not list(results), 'URL must not match any pattern' @@ -1375,12 +1375,12 @@ def url_handler_replacement(*args, **kwargs): sopel = bot.Sopel(tmpconfig, daemon=False) sopel.register_url_callback(test_pattern, url_handler) - results = list(sopel.search_url_callbacks('https://www.example.com')) + results = list(sopel._search_url_callbacks_impl('https://www.example.com')) assert url_handler in results[0] sopel.register_url_callback(test_pattern, url_handler_replacement) - results = list(sopel.search_url_callbacks('https://www.example.com')) + results = list(sopel._search_url_callbacks_impl('https://www.example.com')) assert len(results) == 1, 'There must be one and only one callback' assert url_handler_replacement in results[0], ( 'Handler must have been replaced') @@ -1397,13 +1397,13 @@ def url_handler(*args, **kwargs): # now register a pattern, make sure it still work sopel.register_url_callback(test_pattern, url_handler) - assert list(sopel.search_url_callbacks('https://www.example.com')) + assert list(sopel._search_url_callbacks_impl('https://www.example.com')) # unregister this pattern sopel.unregister_url_callback(test_pattern, url_handler) # now it is not possible to find a callback for this pattern - results = list(sopel.search_url_callbacks('https://www.example.com')) + results = list(sopel._search_url_callbacks_impl('https://www.example.com')) assert not results, 'Unregistered URL callback must not work anymore' @@ -1430,13 +1430,13 @@ def url_handler(*args, **kwargs): # now register a pattern, make sure it still work sopel.register_url_callback(test_pattern, url_handler) - assert list(sopel.search_url_callbacks('https://www.example.com')) + assert list(sopel._search_url_callbacks_impl('https://www.example.com')) # unregister another pattern (that doesn't exist) sopel.unregister_url_callback(r'http://localhost', url_handler) # the existing pattern still work - assert list(sopel.search_url_callbacks('https://www.example.com')) + assert list(sopel._search_url_callbacks_impl('https://www.example.com')) def test_unregister_url_callback_compiled_pattern(tmpconfig): @@ -1451,12 +1451,12 @@ def url_handler(*args, **kwargs): # now register a pattern, make sure it still work sopel.register_url_callback(test_pattern, url_handler) - assert list(sopel.search_url_callbacks('https://www.example.com')) + assert list(sopel._search_url_callbacks_impl('https://www.example.com')) # unregister using the compiled version sopel.unregister_url_callback(url_regex, url_handler) - assert not list(sopel.search_url_callbacks('https://www.example.com')) + assert not list(sopel._search_url_callbacks_impl('https://www.example.com')) def test_multiple_url_callback(tmpconfig): @@ -1474,7 +1474,7 @@ def url_handler_global(*args, **kwargs): sopel.register_url_callback(test_pattern_example, url_handler) sopel.register_url_callback(test_pattern_global, url_handler_global) - results = list(sopel.search_url_callbacks('https://example.com')) + results = list(sopel._search_url_callbacks_impl('https://example.com')) assert len(results) == 2 handlers = [result[0] for result in results] @@ -1484,7 +1484,7 @@ def url_handler_global(*args, **kwargs): # now unregister one of them: the other must still work sopel.unregister_url_callback(test_pattern_example, url_handler) - results = list(sopel.search_url_callbacks('https://example.com')) + results = list(sopel._search_url_callbacks_impl('https://example.com')) assert len(results) == 1, 'Exactly one handler must remain' assert url_handler_global in results[0], 'Wrong remaining handler' @@ -1504,7 +1504,7 @@ def url_handler(*args, **kwargs): # register a callback manually sopel.memory['url_callbacks'][re.compile(test_pattern)] = url_handler - results = list(sopel.search_url_callbacks("https://www.example.com")) + results = list(sopel._search_url_callbacks_impl("https://www.example.com")) assert not results, "Manually registered callback must not be found"