diff --git a/pyquery/pyquery.py b/pyquery/pyquery.py index fbd322d..e0385d3 100644 --- a/pyquery/pyquery.py +++ b/pyquery/pyquery.py @@ -1300,6 +1300,10 @@ def after(self, value): if i > 0: root = deepcopy(list(root)) parent = tag.getparent() + if parent is None: + raise ValueError( + 'Cannot add a sibling after an element without a ' + 'parent') index = parent.index(tag) + 1 parent[index:index] = root root = parent[index:len(root)] @@ -1324,12 +1328,20 @@ def before(self, value): previous.tail += root_text else: parent = tag.getparent() + if parent is None: + raise ValueError( + 'Cannot add a sibling before an element without ' + 'a parent') if not parent.text: parent.text = '' parent.text += root_text if i > 0: root = deepcopy(list(root)) parent = tag.getparent() + if parent is None: + raise ValueError( + 'Cannot add a sibling before an element without a ' + 'parent') index = parent.index(tag) parent[index:index] = root root = parent[index:len(root)] diff --git a/tests/test_pyquery.py b/tests/test_pyquery.py index cc1ef2a..c8a5448 100644 --- a/tests/test_pyquery.py +++ b/tests/test_pyquery.py @@ -534,6 +534,31 @@ def test_class(self): d.removeClass('xx') assert 'class' not in str(d), str(d) + def test_replace_with_on_child(self): + # documented working case: replace_with on a child found via + # .find(), which has a parent + doc = pq("
") + node = pq("") + child = doc.find('div') + child.replace_with(node) + assert str(doc) == '' + + def test_replace_with_on_parentless_root_raises(self): + # calling replace_with() (which uses before() internally) on an + # element with no parent should raise a clear error instead of + # an AttributeError + doc = pq("
") + node = pq("") + self.assertRaises(ValueError, doc.replace_with, node) + + def test_before_on_parentless_root_raises(self): + doc = pq("
") + self.assertRaises(ValueError, doc.before, '') + + def test_after_on_parentless_root_raises(self): + doc = pq("
") + self.assertRaises(ValueError, doc.after, '') + def test_val_for_inputs(self): d = pq(self.html2) self.assertIsNone(d('input[name="none"]').val())