summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeonard Richardson <leonardr@segfault.org>2021-10-24 13:26:39 -0400
committerLeonard Richardson <leonardr@segfault.org>2021-10-24 13:26:39 -0400
commitdd8aa7237b88569c99e85b300b0cf537aeaebfbd (patch)
treea6923b9558dab70df4de12ccbef0e0612ad909a6
parentf7ec284182f3e78974fcdc7b62c88a5c3a6dbbbd (diff)
Used a warning to formally deprecate the 'text' argument in favor of 'string'.
-rw-r--r--CHANGELOG3
-rw-r--r--bs4/__init__.py12
-rw-r--r--bs4/element.py33
-rw-r--r--bs4/tests/__init__.py6
-rw-r--r--bs4/tests/test_navigablestring.py4
-rw-r--r--bs4/tests/test_tree.py23
6 files changed, 58 insertions, 23 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 3747d19..e3f9167 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -23,7 +23,8 @@ Python 2 was revision 605.
methods was renamed to the more accurate "string." But this supposed
"renaming" didn't make it into important places like the method
signatures or the docstrings. That's corrected in this
- version. ("text" still works, but don't use it.) [bug=1947038]
+ version. "text" still works, but will give a deprecation
+ warning. [bug=1947038]
= 4.10.0 (20210907)
diff --git a/bs4/__init__.py b/bs4/__init__.py
index 2a436d3..2cdfed5 100644
--- a/bs4/__init__.py
+++ b/bs4/__init__.py
@@ -207,10 +207,10 @@ class BeautifulSoup(Tag):
if old_name in kwargs:
warnings.warn(
'The "%s" argument to the BeautifulSoup constructor '
- 'has been renamed to "%s."' % (old_name, new_name))
- value = kwargs[old_name]
- del kwargs[old_name]
- return value
+ 'has been renamed to "%s."' % (old_name, new_name),
+ DeprecationWarning
+ )
+ return kwargs.pop(old_name)
return None
parse_only = parse_only or deprecated_argument(
@@ -782,7 +782,9 @@ class BeautifulStoneSoup(BeautifulSoup):
kwargs['features'] = 'xml'
warnings.warn(
'The BeautifulStoneSoup class is deprecated. Instead of using '
- 'it, pass features="xml" into the BeautifulSoup constructor.')
+ 'it, pass features="xml" into the BeautifulSoup constructor.',
+ DeprecationWarning
+ )
super(BeautifulStoneSoup, self).__init__(*args, **kwargs)
diff --git a/bs4/element.py b/bs4/element.py
index 418b3e4..3383621 100644
--- a/bs4/element.py
+++ b/bs4/element.py
@@ -781,6 +781,10 @@ class PageElement(object):
if string is None and 'text' in kwargs:
string = kwargs.pop('text')
+ warnings.warn(
+ "The 'text' argument to find()-type methods is deprecated. Use 'string' instead.",
+ DeprecationWarning
+ )
if isinstance(name, SoupStrainer):
strainer = name
@@ -1548,7 +1552,8 @@ class Tag(PageElement):
warnings.warn(
'.%(name)sTag is deprecated, use .find("%(name)s") instead. If you really were looking for a tag called %(name)sTag, use .find("%(name)sTag")' % dict(
name=tag_name
- )
+ ),
+ DeprecationWarning
)
return self.find(tag_name)
# We special case contents to avoid recursion.
@@ -1974,8 +1979,10 @@ class Tag(PageElement):
has_key() is gone in Python 3, anyway.
"""
- warnings.warn('has_key is deprecated. Use has_attr("%s") instead.' % (
- key))
+ warnings.warn(
+ 'has_key is deprecated. Use has_attr("%s") instead.' % key,
+ DeprecationWarning
+ )
return self.has_attr(key)
# Next, a couple classes to represent queries and their results.
@@ -2003,6 +2010,11 @@ class SoupStrainer(object):
"""
if string is None and 'text' in kwargs:
string = kwargs.pop('text')
+ warnings.warn(
+ "The 'text' argument to the SoupStrainer constructor is deprecated. Use 'string' instead.",
+ DeprecationWarning
+ )
+
self.name = self._normalize_search_value(name)
if not isinstance(attrs, dict):
# Treat a non-dict value for attrs as a search for the 'class'
@@ -2027,7 +2039,10 @@ class SoupStrainer(object):
normalized_attrs[key] = self._normalize_search_value(value)
self.attrs = normalized_attrs
- self.text = self._normalize_search_value(string)
+ self.string = self._normalize_search_value(string)
+
+ # DEPRECATED but just in case someone is checking this.
+ self.text = self.string
def _normalize_search_value(self, value):
# Leave it alone if it's a Unicode string, a callable, a
@@ -2061,8 +2076,8 @@ class SoupStrainer(object):
def __str__(self):
"""A human-readable representation of this SoupStrainer."""
- if self.text:
- return self.text
+ if self.string:
+ return self.string
else:
return "%s|%s" % (self.name, self.attrs)
@@ -2122,7 +2137,7 @@ class SoupStrainer(object):
found = markup
else:
found = markup_name
- if found and self.text and not self._matches(found.string, self.text):
+ if found and self.string and not self._matches(found.string, self.string):
found = None
return found
@@ -2150,12 +2165,12 @@ class SoupStrainer(object):
# If it's a Tag, make sure its name or attributes match.
# Don't bother with Tags if we're searching for text.
elif isinstance(markup, Tag):
- if not self.text or self.name or self.attrs:
+ if not self.string or self.name or self.attrs:
found = self.search_tag(markup)
# If it's text, make sure the text matches.
elif isinstance(markup, NavigableString) or \
isinstance(markup, str):
- if not self.name and not self.attrs and self._matches(markup, self.text):
+ if not self.name and not self.attrs and self._matches(markup, self.string):
found = markup
else:
raise Exception(
diff --git a/bs4/tests/__init__.py b/bs4/tests/__init__.py
index 5147f0e..224c9d8 100644
--- a/bs4/tests/__init__.py
+++ b/bs4/tests/__init__.py
@@ -510,13 +510,13 @@ Hello, world!
self.assert_soup(markup)
soup = self.soup(markup)
- comment = soup.find(text="foobar")
+ comment = soup.find(string="foobar")
assert comment.__class__ == Comment
# The comment is properly integrated into the tree.
- foo = soup.find(text="foo")
+ foo = soup.find(string="foo")
assert comment == foo.next_element
- baz = soup.find(text="baz")
+ baz = soup.find(string="baz")
assert comment == baz.previous_element
def test_preserved_whitespace_in_pre_and_textarea(self):
diff --git a/bs4/tests/test_navigablestring.py b/bs4/tests/test_navigablestring.py
index 649acc0..e4c179e 100644
--- a/bs4/tests/test_navigablestring.py
+++ b/bs4/tests/test_navigablestring.py
@@ -64,7 +64,7 @@ class TestNavigableStringSubclasses(SoupTest):
cdata = CData("foo")
soup.insert(1, cdata)
assert str(soup) == "<![CDATA[foo]]>"
- assert soup.find(text="foo") == "foo"
+ assert soup.find(string="foo") == "foo"
assert soup.contents[0] == "foo"
def test_cdata_is_never_formatted(self):
@@ -103,7 +103,7 @@ class TestNavigableStringSubclasses(SoupTest):
"<div>text</div><script>text</script><style>text</style>"
)
assert [NavigableString, Script, Stylesheet] == [
- x.__class__ for x in soup.find_all(text=True)
+ x.__class__ for x in soup.find_all(string=True)
]
# The TemplateString is a little unusual because it's generally found
diff --git a/bs4/tests/test_tree.py b/bs4/tests/test_tree.py
index 9d3ac4a..bfd6826 100644
--- a/bs4/tests/test_tree.py
+++ b/bs4/tests/test_tree.py
@@ -76,9 +76,7 @@ class TestFindAll(SoupTest):
# Exact match.
assert soup.find_all(string="bar") == ["bar"]
- # 'text' is a deprecated alias for 'string'.
- assert soup.find_all(text="bar") == ["bar"]
-
+
# Match any of a number of strings.
assert soup.find_all(string=["Foo", "bar"]) == ["Foo", "bar"]
# Match a regular expression.
@@ -1271,3 +1269,22 @@ class TestTreeModification(SoupTest):
soup.a.string = cdata
assert isinstance(soup.a.string, CData)
+
+class TestDeprecatedArguments(SoupTest):
+
+ def test_find_type_method_string(self):
+ soup = self.soup("<a>some</a><b>markup</b>")
+ with warnings.catch_warnings(record=True) as w:
+ [result] = soup.find_all(text='markup')
+ assert result == 'markup'
+ assert result.parent.name == 'b'
+ msg = str(w[0].message)
+ assert msg == "The 'text' argument to find()-type methods is deprecated. Use 'string' instead."
+
+ def test_soupstrainer_constructor_string(self):
+ with warnings.catch_warnings(record=True) as w:
+ strainer = SoupStrainer(text="text")
+ assert strainer.text == 'text'
+ msg = str(w[0].message)
+ assert msg == "The 'text' argument to the SoupStrainer constructor is deprecated. Use 'string' instead."
+