From 821bee430a59adc23b93b286d7cda1b606d7f80a Mon Sep 17 00:00:00 2001 From: Rob Letzler Date: Wed, 8 Jan 2025 23:23:29 -0500 Subject: [PATCH] code fix --- branca/element.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/branca/element.py b/branca/element.py index a1e005a..e2d2a3a 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 @@ -69,6 +70,9 @@ def __init__( elif template_name is not None: self._template = ENV.get_template(template_name) + + + def __getstate__(self) -> dict: """Modify object state when pickling the object. @@ -88,6 +92,12 @@ def __setstate__(self, state: dict): self.__dict__.update(state) + def clone(): + """creates a new copy of an element, but with a unique identifier""" + clone = copy(self) + clone._id = hexlify(urandom(16)).decode() + 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 @@ -143,6 +153,23 @@ def add_child( index: Optional[int] = None, ) -> "Element": """Add a child.""" + + # replace the proposed child with a clone of the proposed child because + # add_child 1) overwrites any existing value in the child._parent field + # and 2) does not do anything to remove the child from the list of children of the prior parent + # leading to inconsistency and to problems like the fact that adding the same icon to a map twice fails, as + # documented in https://github.com/python-visualization/folium/issues/1885 + # Creating a clone leads to internally consistent behavior if the + # child already has a parent, although existing code of the form: + # my_map.add_child(myElement) + # my_other_map.add_child(myElement) + # myElement.change + # will now have surprising new behavior + + if child._parent is not None: + child = child.clone() + + if name is None: name = child.get_name() if index is None: @@ -152,6 +179,7 @@ def add_child( items.insert(int(index), (name, child)) self._children = OrderedDict(items) child._parent = self + assert child._parent is not None return self def add_to(