diff options
Diffstat (limited to 'bs4/element.py')
-rw-r--r-- | bs4/element.py | 43 |
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) |