summaryrefslogtreecommitdiff
path: root/bs4
diff options
context:
space:
mode:
authorLeonard Richardson <leonardr@segfault.org>2023-02-07 10:37:50 -0500
committerLeonard Richardson <leonardr@segfault.org>2023-02-07 10:37:50 -0500
commit7eedde44d45f99340bcf98384dfb11295ffcebdd (patch)
treea1398bc82bb843b90631aa2941787a37e0e5ab98 /bs4
parent6d70cafddd4a265feec5a30cc5b302fd6fbaeb83 (diff)
Removed Soup Sieve fallback method, added documentation.
Diffstat (limited to 'bs4')
-rw-r--r--bs4/css.py24
-rw-r--r--bs4/tests/test_css.py19
2 files changed, 12 insertions, 31 deletions
diff --git a/bs4/css.py b/bs4/css.py
index 8b76139..b237051 100644
--- a/bs4/css.py
+++ b/bs4/css.py
@@ -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()