summaryrefslogtreecommitdiff
path: root/bs4/element.py
diff options
context:
space:
mode:
Diffstat (limited to 'bs4/element.py')
-rw-r--r--bs4/element.py43
1 files changed, 28 insertions, 15 deletions
diff --git a/bs4/element.py b/bs4/element.py
index 018f2b3..e75d326 100644
--- a/bs4/element.py
+++ b/bs4/element.py
@@ -966,7 +966,7 @@ class NavigableString(str, PageElement):
return type(self)(self)
def __copy__(self):
- return self.__deepcopy__()
+ return self.__deepcopy__({})
def __getnewargs__(self):
return (str(self),)
@@ -1312,21 +1312,11 @@ class Tag(PageElement):
parserClass = _alias("parser_class") # BS3
- def __deepcopy__(self, recursive=True):
+ def __deepcopy__(self, memo, recursive=True):
"""A deepcopy of a Tag is a new Tag, unconnected to the parse tree.
Its contents are a copy of the old Tag's contents.
"""
- clone = type(self)(
- None, self.builder, self.name, self.namespace,
- self.prefix, self.attrs, is_xml=self._is_xml,
- sourceline=self.sourceline, sourcepos=self.sourcepos,
- can_be_empty_element=self.can_be_empty_element,
- cdata_list_attributes=self.cdata_list_attributes,
- preserve_whitespace_tags=self.preserve_whitespace_tags,
- interesting_string_types=self.interesting_string_types
- )
- for attr in ('can_be_empty_element', 'hidden'):
- setattr(clone, attr, getattr(self, attr))
+ clone = self._clone()
if recursive:
# Clone this tag's descendants recursively, but without
@@ -1338,7 +1328,9 @@ class Tag(PageElement):
# just closed.
tag_stack.pop()
else:
- descendant_clone = element.__copy__(recursive=False)
+ descendant_clone = element.__deepcopy__(
+ memo, recursive=False
+ )
# Add to its parent's .contents
tag_stack[-1].append(descendant_clone)
@@ -1349,8 +1341,29 @@ class Tag(PageElement):
return clone
def __copy__(self):
- return self.__deepcopy__()
+ # A copy of a Tag must always be a deep copy, because the
+ # Tag's children can only have one parent at a time.
+ return self.__deepcopy__({})
+
+ def _clone(self):
+ """Create a new Tag just like this one, but with no
+ contents and unattached to any parse tree.
+ This is the first step in the deepcopy process.
+ """
+ clone = type(self)(
+ None, self.builder, self.name, self.namespace,
+ self.prefix, self.attrs, is_xml=self._is_xml,
+ sourceline=self.sourceline, sourcepos=self.sourcepos,
+ can_be_empty_element=self.can_be_empty_element,
+ cdata_list_attributes=self.cdata_list_attributes,
+ preserve_whitespace_tags=self.preserve_whitespace_tags,
+ interesting_string_types=self.interesting_string_types
+ )
+ for attr in ('can_be_empty_element', 'hidden'):
+ setattr(clone, attr, getattr(self, attr))
+ return clone
+
@property
def is_empty_element(self):
"""Is this tag an empty-element tag? (aka a self-closing tag)