diff options
author | Leonard Richardson <leonardr@segfault.org> | 2023-02-07 10:37:50 -0500 |
---|---|---|
committer | Leonard Richardson <leonardr@segfault.org> | 2023-02-07 10:37:50 -0500 |
commit | 7eedde44d45f99340bcf98384dfb11295ffcebdd (patch) | |
tree | a1398bc82bb843b90631aa2941787a37e0e5ab98 /bs4 | |
parent | 6d70cafddd4a265feec5a30cc5b302fd6fbaeb83 (diff) |
Removed Soup Sieve fallback method, added documentation.
Diffstat (limited to 'bs4')
-rw-r--r-- | bs4/css.py | 24 | ||||
-rw-r--r-- | bs4/tests/test_css.py | 19 |
2 files changed, 12 insertions, 31 deletions
@@ -33,6 +33,8 @@ class CSS(object): :param tag: All CSS selectors will use this as their starting point. + :param api: A plug-in replacement for the soupsieve module, + designed mainly for use in tests. """ if api is None: raise NotImplementedError( @@ -63,9 +65,9 @@ class CSS(object): """Normalize a list of results to a Resultset. A ResultSet is more consistent with the rest of Beautiful - Soup, and ResultSet.__getattr__ has a helpful error message if - you try to treat a list of results as a single result (a - common mistake). + Soup's API, and ResultSet.__getattr__ has a helpful error + message if you try to treat a list of results as a single + result (a common mistake). """ # Import here to avoid circular import from bs4.element import ResultSet @@ -249,19 +251,3 @@ class CSS(object): select, self.tag, self._ns(namespaces), flags, **kwargs ) ) - - def __getattr__(self, __name): - """Catch-all method that has a chance of giving access to future - methods to be added to Soup Sieve without needing a Beautiful Soup - API change. - - Basically, if you call tag.css.somemethod(selector), this code will - turn that into soupsieve.somemethod(selector, tag). - """ - attr = getattr(self.api, __name) - if callable(attr): - return ( - lambda pattern, *args, __tag=self.tag, __attr=attr, **kwargs: - attr(pattern, __tag, *args, **kwargs) - ) - return attr diff --git a/bs4/tests/test_css.py b/bs4/tests/test_css.py index a6c17de..cf73831 100644 --- a/bs4/tests/test_css.py +++ b/bs4/tests/test_css.py @@ -474,25 +474,20 @@ class TestCSSSelectors(SoupTest): assert m(".foo#bar") == '\\.foo\\#bar' assert m("()[]{}") == '\\(\\)\\[\\]\\{\\}' assert m(".foo") == self.soup.css.escape(".foo") - - def test_fallback(self): + + def test_api_replacement(self): + # You can pass in another object to act as a drop-in + # replacement for the soupsieve module. class Mock(): attribute = "value" pass mock_soupsieve = Mock() - mock_soupsieve.some_other_method = MagicMock() + mock_soupsieve.escape = MagicMock() # If an unknown method turns out to be present in Soup Sieve, # we may still be able to call it. css = CSS(self.soup, api=mock_soupsieve) - css.some_other_method("selector", 1, flags=0) - mock_soupsieve.some_other_method.assert_called_with( + css.escape("identifier") + mock_soupsieve.escape.assert_called_with( "selector", self.soup, 1, flags=0 ) - - # If the attribute is not callable, getattr is a passthrough. - assert mock_soupsieve.attribute == "value" - - # If the method just isn't there, too bad. - with pytest.raises(AttributeError): - mock_soupsieve.no_such_method() |