Merge ~chrispitude/beautifulsoup:new-tag-allow-text into beautifulsoup:master

Proposed by Chris Papademetrious
Status: Merged
Merge reported by: Leonard Richardson
Merged at revision: b3e3474bdf663cb7bb0bdbfce0a73f2d0a9c6f8d
Proposed branch: ~chrispitude/beautifulsoup:new-tag-allow-text
Merge into: beautifulsoup:master
Diff against target: 68 lines (+9/-8)
3 files modified
bs4/__init__.py (+6/-2)
bs4/tests/test_soup.py (+2/-1)
doc/source/index.rst (+1/-5)
Reviewer Review Type Date Requested Status
Leonard Richardson Pending
Review via email: mp+457198@code.launchpad.net

Commit message

allow string text specification in new_tag()

Description of the change

This change allows new text to be specified in the new_tag() method:

>>> title = soup.new_tag('title', 'My Title Text', ...)

or, alternatively as a named argument:

>>> title = soup.new_tag('title', string='My Title Text', ...)

This, together with the `return-inserted-element` merge request, allows much easier element creation and insertion like this:

>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup('<html/>')
>>> html = soup.find('html')
>>> #
>>> head = html.insert(0, soup.new_tag('head'))
>>> title = head.append(soup.new_tag('title', 'My Title Text'))
>>> meta = head.append(soup.new_tag('meta', charset='UTF-8'))
>>> #
>>> print(html) # manually prettified
<html>
 <head>
  <title>My Title Text</title>
  <meta charset="UTF-8"/>
 </head>
</html>

To post a comment you must log in.
Revision history for this message
Leonard Richardson (leonardr) wrote :

This looks good for the next feature release. The only change I plan to make is to move 'string' to the end of the argument list to maintain backwards compatibility. Otherwise existing code that uses positional arguments (like the tree builder code you had to change) will break.

b3e3474... by Chris Papademetrious

allow string text specification in new_tag()

Signed-off-by: Chris Papademetrious <email address hidden>

Revision history for this message
Chris Papademetrious (chrispitude) wrote :

Thanks Leonard! I force-pushed an update to restore the original new_tag() argument list order. It also reverts the test modifications and updates the documentation example.

Revision history for this message
Leonard Richardson (leonardr) wrote (last edit ):

Merged into the 4.13 branch. I made a minor change to handle the case where the empty string was passed in.

Revision history for this message
Chris Papademetrious (chrispitude) wrote :

Thank you!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/bs4/__init__.py b/bs4/__init__.py
index 3d2ab09..3cb8561 100644
--- a/bs4/__init__.py
+++ b/bs4/__init__.py
@@ -498,7 +498,7 @@ class BeautifulSoup(Tag):
498 self.pushTag(self)498 self.pushTag(self)
499499
500 def new_tag(self, name, namespace=None, nsprefix=None, attrs={},500 def new_tag(self, name, namespace=None, nsprefix=None, attrs={},
501 sourceline=None, sourcepos=None, **kwattrs):501 sourceline=None, sourcepos=None, string=None, **kwattrs):
502 """Create a new Tag associated with this BeautifulSoup object.502 """Create a new Tag associated with this BeautifulSoup object.
503503
504 :param name: The name of the new Tag.504 :param name: The name of the new Tag.
@@ -511,14 +511,18 @@ class BeautifulSoup(Tag):
511 (purportedly) found in its source document.511 (purportedly) found in its source document.
512 :param sourcepos: The character position within `sourceline` where this512 :param sourcepos: The character position within `sourceline` where this
513 tag was (purportedly) found.513 tag was (purportedly) found.
514 :param string: Text content for the new Tag, if any.
514 :param kwattrs: Keyword arguments for the new Tag's attribute values.515 :param kwattrs: Keyword arguments for the new Tag's attribute values.
515516
516 """517 """
517 kwattrs.update(attrs)518 kwattrs.update(attrs)
518 return self.element_classes.get(Tag, Tag)(519 tag = self.element_classes.get(Tag, Tag)(
519 None, self.builder, name, namespace, nsprefix, kwattrs,520 None, self.builder, name, namespace, nsprefix, kwattrs,
520 sourceline=sourceline, sourcepos=sourcepos521 sourceline=sourceline, sourcepos=sourcepos
521 )522 )
523 if string:
524 tag.string = string
525 return tag
522526
523 def string_container(self, base_class=None):527 def string_container(self, base_class=None):
524 container = base_class or NavigableString528 container = base_class or NavigableString
diff --git a/bs4/tests/test_soup.py b/bs4/tests/test_soup.py
index 28013b8..3639c28 100644
--- a/bs4/tests/test_soup.py
+++ b/bs4/tests/test_soup.py
@@ -390,9 +390,10 @@ class TestNewTag(SoupTest):
390 """Test the BeautifulSoup.new_tag() method."""390 """Test the BeautifulSoup.new_tag() method."""
391 def test_new_tag(self):391 def test_new_tag(self):
392 soup = self.soup("")392 soup = self.soup("")
393 new_tag = soup.new_tag("foo", bar="baz", attrs={"name": "a name"})393 new_tag = soup.new_tag("foo", string="txt", bar="baz", attrs={"name": "a name"})
394 assert isinstance(new_tag, Tag)394 assert isinstance(new_tag, Tag)
395 assert "foo" == new_tag.name395 assert "foo" == new_tag.name
396 assert new_tag.string == "txt"
396 assert dict(bar="baz", name="a name") == new_tag.attrs397 assert dict(bar="baz", name="a name") == new_tag.attrs
397 assert None == new_tag.parent398 assert None == new_tag.parent
398399
diff --git a/doc/source/index.rst b/doc/source/index.rst
index aedfdfc..106dfc8 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -2035,13 +2035,9 @@ call the factory method ``BeautifulSoup.new_tag()``::
2035 soup = BeautifulSoup("<b></b>", 'html.parser')2035 soup = BeautifulSoup("<b></b>", 'html.parser')
2036 original_tag = soup.b2036 original_tag = soup.b
20372037
2038 new_tag = soup.new_tag("a", href="http://www.example.com")2038 new_tag = soup.new_tag("a", string="Link text.", href="http://www.example.com")
2039 original_tag.append(new_tag)2039 original_tag.append(new_tag)
2040 original_tag2040 original_tag
2041 # <b><a href="http://www.example.com"></a></b>
2042
2043 new_tag.string = "Link text."
2044 original_tag
2045 # <b><a href="http://www.example.com">Link text.</a></b>2041 # <b><a href="http://www.example.com">Link text.</a></b>
20462042
2047Only the first argument, the tag name, is required.2043Only the first argument, the tag name, is required.

Subscribers

People subscribed via source and target branches