<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">For more background, see the short article on "mutable and immutable objects in Python"  <a href="https://www.geeksforgeeks.org/mutable-vs-immutable-objects-in-python/" class="">https://www.geeksforgeeks.org/mutable-vs-immutable-objects-in-python/</a><div class="">and follow the rule: only use immutable values as default value for function and method arguments (in Python None is immutable, and it's a singleton, there is only one None)<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On May 12, 2020, at 9:25 PM, <a href="mailto:vmarchetti@kshell.com" class="">vmarchetti@kshell.com</a> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">This is an unfortunate and common bug that occurs in Python.<div class=""><br class=""></div><div class="">In the definition of the class Scene (around line 8795 of x3d.py) is this definition of the __init__ function for Scene:</div><div class=""><br class=""></div><div class=""><div class="">    def __init__(self, children=list()):</div><div class="">        self.children = children</div><div class=""><br class=""></div><div class="">This code is read once when the x3d.py module is loaded, and it creates a class-level default value for the children argument.</div><div class="">If you ever use the default value by calling Scene() {with no parameter}, this class-level instance of list is modified, and this SAME INSTANCE of list</div><div class="">if used for any further calls of Scene()</div><div class=""><br class=""></div><div class="">The way to avoid this is to define the __init__ function this way:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>def __init__(self, children=None):</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>if children is None:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                      </span>self.children = list() # creates a new empty list for each Scene instance</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>else:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>self.children = children</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Vince Marchetti</div><div class=""><br class=""></div><div class=""><br class=""><blockquote type="cite" class=""><div class="">On May 12, 2020, at 5:59 PM, Andreas Plesch <<a href="mailto:andreasplesch@gmail.com" class="">andreasplesch@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">I discovered a simple workaround. Always pass a children parameter, even if empty.</div><br class=""><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, May 12, 2020 at 5:16 PM Andreas Plesch <<a href="mailto:andreasplesch@gmail.com" class="">andreasplesch@gmail.com</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="">Hi,<br class=""><br class="">after some debugging I discovered another issue with x3d.py. It can be boiled down t o a few lines of code:<br class=""><br class=""><font face="monospace" class="">import x3d.x3d as x<br class=""><br class="">my_scene = x.Scene()<br class="">group = x.Group()<br class="">my_scene.children.append(group)<br class="">print(my_scene.XML())<br class=""><br class="">=> output<br class="">=> <Scene><br class="">=>  <Group/><br class="">=> </Scene><br class=""><br class="">my_other_scene = x.Scene()<br class="">print(my_other_scene.XML())<br class=""><br class="">=> output<br class="">=> <Scene><br class="">=>  <Group/><br class="">=> </Scene><br class=""><br class=""></font>I think my_other_scene should be empty but remembers the content of the first scene.<div class="">Can you reproduce that ?</div><div class="">On the other hand this works (in a new session):</div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">my_scene = x.Scene( children = [x.Group()] )<br class="">print(my_scene.XML())<br class=""><br class="">=> output<br class="">=> <Scene><br class="">=>  <Group/><br class="">=> </Scene><br class=""><br class="">my_other_scene = x.Scene()<br class="">print(my_other_scene.XML()) </font> <br class=""></div><div class=""><br class=""></div><div class=""><font face="monospace" class="">=> output<br class="">=> <Scene><br class="">=> </Scene></font><br class=""></div><div class=""><br class="">-- <br class="">Andreas Plesch<br class="">Waltham, MA 02453</div></div>
</blockquote></div><br clear="all" class=""><div class=""><br class=""></div>-- <br class=""><div dir="ltr" class="gmail_signature"><div dir="ltr" class=""><div class="">Andreas Plesch<br class="">Waltham, MA 02453</div></div></div>
_______________________________________________<br class="">x3d-public mailing list<br class=""><a href="mailto:x3d-public@web3d.org" class="">x3d-public@web3d.org</a><br class=""><a href="http://web3d.org/mailman/listinfo/x3d-public_web3d.org" class="">http://web3d.org/mailman/listinfo/x3d-public_web3d.org</a><br class=""></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">x3d-public mailing list<br class=""><a href="mailto:x3d-public@web3d.org" class="">x3d-public@web3d.org</a><br class="">http://web3d.org/mailman/listinfo/x3d-public_web3d.org<br class=""></div></blockquote></div><br class=""></div></body></html>