summaryrefslogtreecommitdiff
path: root/bs4
diff options
context:
space:
mode:
Diffstat (limited to 'bs4')
-rw-r--r--bs4/element.py15
-rw-r--r--bs4/tests/test_tree.py31
2 files changed, 39 insertions, 7 deletions
diff --git a/bs4/element.py b/bs4/element.py
index 3428e21..e7867a9 100644
--- a/bs4/element.py
+++ b/bs4/element.py
@@ -296,25 +296,26 @@ class PageElement(object):
getText = get_text
text = property(get_text)
- def replace_with(self, replace_with):
- """Replace this PageElement with another one, keeping the rest of the
- tree the same.
+ def replace_with(self, *args):
+ """Replace this PageElement with one or more PageElements, keeping the
+ rest of the tree the same.
- :param replace_with: A PageElement.
+ :param args: One or more PageElements.
:return: `self`, no longer part of the tree.
"""
if self.parent is None:
raise ValueError(
"Cannot replace one element with another when the "
"element to be replaced is not part of a tree.")
- if replace_with is self:
+ if len(args) == 1 and args[0] is self:
return
- if replace_with is self.parent:
+ if any(x is self.parent for x in args):
raise ValueError("Cannot replace a Tag with its parent.")
old_parent = self.parent
my_index = self.parent.index(self)
self.extract(_self_index=my_index)
- old_parent.insert(my_index, replace_with)
+ for idx, replace_with in enumerate(args, start=my_index):
+ old_parent.insert(idx, replace_with)
return self
replaceWith = replace_with # BS3
diff --git a/bs4/tests/test_tree.py b/bs4/tests/test_tree.py
index 875befe..26004ce 100644
--- a/bs4/tests/test_tree.py
+++ b/bs4/tests/test_tree.py
@@ -1130,6 +1130,37 @@ class TestTreeModification(SoupTest):
self.assertEqual(no.next_element, "no")
self.assertEqual(no.next_sibling, " business")
+ def test_replace_with_errors(self):
+ # Can't replace a tag that's not part of a tree.
+ a_tag = Tag(name="a")
+ self.assertRaises(ValueError, a_tag.replace_with, "won't work")
+
+ # Can't replace a tag with its parent.
+ a_tag = self.soup("<a><b></b></a>").a
+ self.assertRaises(ValueError, a_tag.b.replace_with, a_tag)
+
+ # Or with a list that includes its parent.
+ self.assertRaises(ValueError, a_tag.b.replace_with,
+ "string1", a_tag, "string2")
+
+ def test_replace_with_multiple(self):
+ data = "<a><b></b><c></c></a>"
+ soup = self.soup(data)
+ d_tag = soup.new_tag("d")
+ d_tag.string = "Text In D Tag"
+ e_tag = soup.new_tag("e")
+ f_tag = soup.new_tag("f")
+ a_string = "Random Text"
+ soup.c.replace_with(d_tag, e_tag, a_string, f_tag)
+ self.assertEqual(
+ "<a><b></b><d>Text In D Tag</d><e></e>Random Text<f></f></a>",
+ soup.decode()
+ )
+ assert soup.b.next_element == d_tag
+ assert d_tag.string.next_element==e_tag
+ assert e_tag.next_element.string == a_string
+ assert e_tag.next_element.next_element == f_tag
+
def test_replace_first_child(self):
data = "<a><b></b><c></c></a>"
soup = self.soup(data)