diff --git a/branca/element.py b/branca/element.py index a1e005a..9b68033 100644 --- a/branca/element.py +++ b/branca/element.py @@ -11,6 +11,7 @@ import warnings from binascii import hexlify from collections import OrderedDict +from copy import copy from html import escape from os import urandom from pathlib import Path @@ -88,6 +89,14 @@ def __setstate__(self, state: dict): self.__dict__.update(state) + def clone(self): + """creates a new copy of an element, but with a unique identifier + and without the prior version's relationship to a parent object""" + clone = copy(self) + clone._id = hexlify(urandom(16)).decode() + clone._parent = None + return clone + def get_name(self) -> str: """Returns a string representation of the object. This string has to be unique and to be a python and @@ -142,7 +151,25 @@ def add_child( name: Optional[str] = None, index: Optional[int] = None, ) -> "Element": - """Add a child.""" + """Add a child and modify the child with a pointer to its parent.""" + + if child._parent is not None: + warnings.warn( + f"""The code added\n {child.get_name()} as a child of + {self.get_name()} which + overwrote an existing pointer to a parent object, {child._parent.get_name()}, + but leaves the parent object pointing to the child. + Branca is designed so each object will have no more than + one parent. Consider replacing the object with object.clone() + so that each object has only one parent. Otherwise, actions may + fail. For example, adding an icon object to a map + only adds one valid icon to the map regardless of how many times + the code adds that icon object. This behavior is documented at: + https://github.com/python-visualization/folium/issues/1885 + """, + category=UserWarning, + stacklevel=2, + ) if name is None: name = child.get_name() if index is None: