From ef7d0fbccba1879292fcb9fb41a4a4d325612b9a Mon Sep 17 00:00:00 2001 From: Bastien GAUTHIER Date: Wed, 4 Oct 2023 17:27:14 +0200 Subject: [PATCH 1/9] Make _parse_size robust to already parsed values (needed for unpickling a folium Map) --- branca/utilities.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/branca/utilities.py b/branca/utilities.py index 922fab2..2f63d76 100644 --- a/branca/utilities.py +++ b/branca/utilities.py @@ -414,6 +414,9 @@ def _parse_size(value): raise ValueError( f"Cannot parse {value!r}, it should be a number followed by a unit.", ) + elif isinstance(value, tuple) and isinstance(value[0], (int, float)) and isinstance(value[1], str): + # value had been already parsed + return value else: raise TypeError( f"Cannot parse {value!r}, it should be a number or a string containing a number and a unit.", From 39a930294157d4da5113b53caa2a8332ffe68b78 Mon Sep 17 00:00:00 2001 From: Bastien GAUTHIER Date: Thu, 12 Oct 2023 13:56:18 +0200 Subject: [PATCH 2/9] Add the _template_str to recover all the Elements --- branca/element.py | 86 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/branca/element.py b/branca/element.py index f618ced..d3d7123 100644 --- a/branca/element.py +++ b/branca/element.py @@ -44,12 +44,12 @@ class Element: If no template is provided, you can also provide a filename. """ - - _template = Template( + _template_str = ( "{% for name, element in this._children.items() %}\n" " {{element.render(**kwargs)}}" - "{% endfor %}", + "{% endfor %}" ) + _template = Template(_template_str) def __init__(self, template=None, template_name=None): self._name = "Element" @@ -57,11 +57,13 @@ def __init__(self, template=None, template_name=None): self._env = ENV self._children = OrderedDict() self._parent = None + self.template = template + self.template_name = template_name - if template is not None: - self._template = Template(template) - elif template_name is not None: - self._template = ENV.get_template(template_name) + if self.template is not None: + self._template = Template(self.template) + elif self.template_name is not None: + self._template = ENV.get_template(self.template_name) def __getstate__(self): """Modify object state when pickling the object. @@ -71,11 +73,20 @@ def __getstate__(self): """ state: dict = self.__dict__.copy() state["_env"] = None + state["_template"] = None return state def __setstate__(self, state: dict): """Re-add ._env attribute when unpickling""" state["_env"] = ENV + + state["_template"] = Template(self._template_str) + + if state["template"] is not None: + state["_template"] = Template(state["template"]) + elif state["template_name"] is not None: + state["_template"] = ENV.get_template(state["template_name"] ) + self.__dict__.update(state) def get_name(self): @@ -222,13 +233,14 @@ class JavascriptLink(Link): """ - _template = Template( + _template_str = ( '{% if kwargs.get("embedded",False) %}' "" "{% else %}" '' - "{% endif %}", + "{% endif %}" ) + _template = Template(_template_str) def __init__(self, url, download=False): super().__init__() @@ -238,6 +250,10 @@ def __init__(self, url, download=False): if download: self.get_code() + def __setstate__(self, state: dict): + """Re-add ._env attribute when unpickling""" + super().__setstate__(state) + self._template = Template(self._template_str) class CssLink(Link): """Create a CssLink object based on a url. @@ -250,14 +266,14 @@ class CssLink(Link): Whether the target document shall be loaded right now. """ - - _template = Template( + _template_str = ( '{% if kwargs.get("embedded",False) %}' "" "{% else %}" '' - "{% endif %}", + "{% endif %}" ) + _template = Template(_template_str) def __init__(self, url, download=False): super().__init__() @@ -267,6 +283,10 @@ def __init__(self, url, download=False): if download: self.get_code() + def __setstate__(self, state: dict): + """Re-add ._env attribute when unpickling""" + super().__setstate__(state) + self._template = Template(self._template_str) class Figure(Element): """Create a Figure object, to plot things into it. @@ -291,7 +311,7 @@ class Figure(Element): width="600px", height="300px". """ - _template = Template( + _template_str = ( "\n" "\n" "\n" @@ -304,8 +324,9 @@ class Figure(Element): "\n" - "\n", + "\n" ) + _template = Template(_template_str) def __init__( self, @@ -341,6 +362,11 @@ def __init__( name="meta_http", ) + def __setstate__(self, state: dict): + """Re-add ._env attribute when unpickling""" + super().__setstate__(state) + self._template = Template(self._template_str) + def to_dict(self, depth=-1, **kwargs): """Returns a dict representation of the object.""" out = super().to_dict(depth=depth, **kwargs) @@ -437,12 +463,12 @@ class Html(Element): The height of the output div element. Ex: 120 , '80%' """ - - _template = Template( + _template_str = ( '
' # noqa - "{% if this.script %}{{this.data}}{% else %}{{this.data|e}}{% endif %}
", - ) # noqa + "{% if this.script %}{{this.data}}{% else %}{{this.data|e}}{% endif %}" + ) + _template = Template(_template_str) def __init__(self, data, script=False, width="100%", height="100%"): super().__init__() @@ -453,6 +479,11 @@ def __init__(self, data, script=False, width="100%", height="100%"): self.width = _parse_size(width) self.height = _parse_size(height) + def __setstate__(self, state: dict): + """Re-add ._env attribute when unpickling""" + super().__setstate__(state) + self._template = Template(self._template_str) + class Div(Figure): """Create a Div to be embedded in a Figure. @@ -472,7 +503,7 @@ class Div(Figure): Usual values are 'relative', 'absolute', 'fixed', 'static'. """ - _template = Template( + _template_str = ( "{% macro header(this, kwargs) %}" "" @@ -288,6 +291,7 @@ def __setstate__(self, state: dict): super().__setstate__(state) self._template = Template(self._template_str) + class Figure(Element): """Create a Figure object, to plot things into it. @@ -463,6 +467,7 @@ class Html(Element): The height of the output div element. Ex: 120 , '80%' """ + _template_str = ( '
' # noqa @@ -683,6 +688,7 @@ class MacroElement(Element): {% endmacro %} """ + _template_str = "" _template = Template(_template_str) diff --git a/branca/utilities.py b/branca/utilities.py index 2f63d76..c054306 100644 --- a/branca/utilities.py +++ b/branca/utilities.py @@ -414,7 +414,11 @@ def _parse_size(value): raise ValueError( f"Cannot parse {value!r}, it should be a number followed by a unit.", ) - elif isinstance(value, tuple) and isinstance(value[0], (int, float)) and isinstance(value[1], str): + elif ( + isinstance(value, tuple) + and isinstance(value[0], (int, float)) + and isinstance(value[1], str) + ): # value had been already parsed return value else: From f7806afb7a5cdd9acf6816f3017677f9448ff6d3 Mon Sep 17 00:00:00 2001 From: Bastien GAUTHIER Date: Thu, 12 Oct 2023 16:21:02 +0200 Subject: [PATCH 4/9] __setstate__ simplification --- branca/colormap.py | 5 +++++ branca/element.py | 28 ---------------------------- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/branca/colormap.py b/branca/colormap.py index d7cef7f..980dd8d 100644 --- a/branca/colormap.py +++ b/branca/colormap.py @@ -92,6 +92,11 @@ def __init__(self, vmin=0.0, vmax=1.0, caption="", max_labels=10): self.width = 450 self.height = 40 + def __setstate__(self, state: dict): + """Re-add ._template attribute when unpickling""" + super().__setstate__(state) + self._template = ENV.get_template("color_scale.js") + def render(self, **kwargs): """Renders the HTML representation of the element.""" self.color_domain = [ diff --git a/branca/element.py b/branca/element.py index d3d7123..640e132 100644 --- a/branca/element.py +++ b/branca/element.py @@ -250,10 +250,6 @@ def __init__(self, url, download=False): if download: self.get_code() - def __setstate__(self, state: dict): - """Re-add ._env attribute when unpickling""" - super().__setstate__(state) - self._template = Template(self._template_str) class CssLink(Link): """Create a CssLink object based on a url. @@ -283,10 +279,6 @@ def __init__(self, url, download=False): if download: self.get_code() - def __setstate__(self, state: dict): - """Re-add ._env attribute when unpickling""" - super().__setstate__(state) - self._template = Template(self._template_str) class Figure(Element): """Create a Figure object, to plot things into it. @@ -362,11 +354,6 @@ def __init__( name="meta_http", ) - def __setstate__(self, state: dict): - """Re-add ._env attribute when unpickling""" - super().__setstate__(state) - self._template = Template(self._template_str) - def to_dict(self, depth=-1, **kwargs): """Returns a dict representation of the object.""" out = super().to_dict(depth=depth, **kwargs) @@ -479,11 +466,6 @@ def __init__(self, data, script=False, width="100%", height="100%"): self.width = _parse_size(width) self.height = _parse_size(height) - def __setstate__(self, state: dict): - """Re-add ._env attribute when unpickling""" - super().__setstate__(state) - self._template = Template(self._template_str) - class Div(Figure): """Create a Div to be embedded in a Figure. @@ -549,11 +531,6 @@ def __init__( self.html._parent = self self.script._parent = self - def __setstate__(self, state: dict): - """Re-add ._env attribute when unpickling""" - super().__setstate__(state) - self._template = Template(self._template_str) - def get_root(self): """Returns the root of the elements tree.""" return self @@ -690,11 +667,6 @@ def __init__(self): super().__init__() self._name = "MacroElement" - def __setstate__(self, state: dict): - """Re-add ._env attribute when unpickling""" - super().__setstate__(state) - self._template = Template(self._template_str) - def render(self, **kwargs): """Renders the HTML representation of the element.""" figure = self.get_root() From 2a22fe77f48df89cbf65af279611b79b17456ffe Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 12 Oct 2023 14:21:25 +0000 Subject: [PATCH 5/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- branca/element.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/branca/element.py b/branca/element.py index 6d76409..051305d 100644 --- a/branca/element.py +++ b/branca/element.py @@ -252,7 +252,6 @@ def __init__(self, url, download=False): self.get_code() - class CssLink(Link): """Create a CssLink object based on a url. @@ -283,7 +282,6 @@ def __init__(self, url, download=False): self.get_code() - class Figure(Element): """Create a Figure object, to plot things into it. From 7e9a5d54fc6f55ee44d7e47d5e07533774b6f844 Mon Sep 17 00:00:00 2001 From: Bastien GAUTHIER Date: Fri, 13 Oct 2023 11:06:56 +0200 Subject: [PATCH 6/9] More change cleaning, keep only the Element change --- branca/colormap.py | 5 ----- branca/element.py | 41 ++++++++++++++++------------------------- branca/utilities.py | 7 ------- 3 files changed, 16 insertions(+), 37 deletions(-) diff --git a/branca/colormap.py b/branca/colormap.py index 980dd8d..d7cef7f 100644 --- a/branca/colormap.py +++ b/branca/colormap.py @@ -92,11 +92,6 @@ def __init__(self, vmin=0.0, vmax=1.0, caption="", max_labels=10): self.width = 450 self.height = 40 - def __setstate__(self, state: dict): - """Re-add ._template attribute when unpickling""" - super().__setstate__(state) - self._template = ENV.get_template("color_scale.js") - def render(self, **kwargs): """Renders the HTML representation of the element.""" self.color_domain = [ diff --git a/branca/element.py b/branca/element.py index 6d76409..b74f7fd 100644 --- a/branca/element.py +++ b/branca/element.py @@ -45,12 +45,11 @@ class Element: """ - _template_str = ( + _template = Template( "{% for name, element in this._children.items() %}\n" " {{element.render(**kwargs)}}" - "{% endfor %}" + "{% endfor %}", ) - _template = Template(_template_str) def __init__(self, template=None, template_name=None): self._name = "Element" @@ -81,7 +80,7 @@ def __setstate__(self, state: dict): """Re-add ._env attribute when unpickling""" state["_env"] = ENV - state["_template"] = Template(self._template_str) + state["_template"] = self._template if state["template"] is not None: state["_template"] = Template(state["template"]) @@ -234,14 +233,13 @@ class JavascriptLink(Link): """ - _template_str = ( + _template = Template( '{% if kwargs.get("embedded",False) %}' "" "{% else %}" '' - "{% endif %}" + "{% endif %}", ) - _template = Template(_template_str) def __init__(self, url, download=False): super().__init__() @@ -252,7 +250,6 @@ def __init__(self, url, download=False): self.get_code() - class CssLink(Link): """Create a CssLink object based on a url. @@ -265,14 +262,13 @@ class CssLink(Link): """ - _template_str = ( + _template = Template( '{% if kwargs.get("embedded",False) %}' "" "{% else %}" '' - "{% endif %}" + "{% endif %}", ) - _template = Template(_template_str) def __init__(self, url, download=False): super().__init__() @@ -283,7 +279,6 @@ def __init__(self, url, download=False): self.get_code() - class Figure(Element): """Create a Figure object, to plot things into it. @@ -307,7 +302,7 @@ class Figure(Element): width="600px", height="300px". """ - _template_str = ( + _template = Template( "\n" "\n" "\n" @@ -320,9 +315,8 @@ class Figure(Element): "\n" - "\n" + "\n", ) - _template = Template(_template_str) def __init__( self, @@ -455,12 +449,11 @@ class Html(Element): Ex: 120 , '80%' """ - _template_str = ( + _template = Template( '
' # noqa - "{% if this.script %}{{this.data}}{% else %}{{this.data|e}}{% endif %}
" - ) - _template = Template(_template_str) + "{% if this.script %}{{this.data}}{% else %}{{this.data|e}}{% endif %}
", + ) # noqa def __init__(self, data, script=False, width="100%", height="100%"): super().__init__() @@ -490,7 +483,7 @@ class Div(Figure): Usual values are 'relative', 'absolute', 'fixed', 'static'. """ - _template_str = ( + _template = Template( "{% macro header(this, kwargs) %}" "