summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG5
-rw-r--r--bs4/formatter.py2
-rw-r--r--bs4/tests/test_tree.py17
3 files changed, 24 insertions, 0 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 2758e62..5f32a57 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+= Unreleased
+
+* Fixed an unhandled exception when formatting a Tag that had been
+ decomposed.[bug=1857767]
+
= 4.8.2 (20191224)
* Added Python docstrings to all public methods of the most commonly
diff --git a/bs4/formatter.py b/bs4/formatter.py
index 09d15e7..9a692ec 100644
--- a/bs4/formatter.py
+++ b/bs4/formatter.py
@@ -108,6 +108,8 @@ class Formatter(EntitySubstitution):
behavior consistent between Python 2 and Python 3, and preserves
backwards compatibility with older versions of Beautiful Soup.
"""
+ if tag.attrs is None:
+ return []
return sorted(tag.attrs.items())
diff --git a/bs4/tests/test_tree.py b/bs4/tests/test_tree.py
index 7d8da01..3251e0e 100644
--- a/bs4/tests/test_tree.py
+++ b/bs4/tests/test_tree.py
@@ -1777,6 +1777,23 @@ class TestEncoding(SoupTest):
class TestFormatter(SoupTest):
+ def test_default_attributes(self):
+ # Test the default behavior of Formatter.attributes().
+ formatter = Formatter()
+ tag = Tag(name="tag")
+ tag['b'] = 1
+ tag['a'] = 2
+
+ # Attributes come out sorted by name. In Python 3, attributes
+ # normally come out of a dictionary in the order they were
+ # added.
+ self.assertEquals([('a', 2), ('b', 1)], formatter.attributes(tag))
+
+ # This works even if Tag.attrs is None, though this shouldn't
+ # normally happen.
+ tag.attrs = None
+ self.assertEquals([], formatter.attributes(tag))
+
def test_sort_attributes(self):
# Test the ability to override Formatter.attributes() to,
# e.g., disable the normal sorting of attributes.