[x3d-public] x3d.py problem

vmarchetti at kshell.com vmarchetti at kshell.com
Tue May 12 18:46:31 PDT 2020


For more background, see the short article on "mutable and immutable objects in Python"  https://www.geeksforgeeks.org/mutable-vs-immutable-objects-in-python/ <https://www.geeksforgeeks.org/mutable-vs-immutable-objects-in-python/>
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)

> On May 12, 2020, at 9:25 PM, vmarchetti at kshell.com wrote:
> 
> This is an unfortunate and common bug that occurs in Python.
> 
> In the definition of the class Scene (around line 8795 of x3d.py) is this definition of the __init__ function for Scene:
> 
>     def __init__(self, children=list()):
>         self.children = children
> 
> This code is read once when the x3d.py module is loaded, and it creates a class-level default value for the children argument.
> 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
> if used for any further calls of Scene()
> 
> The way to avoid this is to define the __init__ function this way:
> 
> 	def __init__(self, children=None):
> 		if children is None:
> 			self.children = list() # creates a new empty list for each Scene instance
> 		else:
> 			self.children = children
> 
> 
> Vince Marchetti
> 
> 
>> On May 12, 2020, at 5:59 PM, Andreas Plesch <andreasplesch at gmail.com <mailto:andreasplesch at gmail.com>> wrote:
>> 
>> I discovered a simple workaround. Always pass a children parameter, even if empty.
>> 
>> On Tue, May 12, 2020 at 5:16 PM Andreas Plesch <andreasplesch at gmail.com <mailto:andreasplesch at gmail.com>> wrote:
>> Hi,
>> 
>> after some debugging I discovered another issue with x3d.py. It can be boiled down t o a few lines of code:
>> 
>> import x3d.x3d as x
>> 
>> my_scene = x.Scene()
>> group = x.Group()
>> my_scene.children.append(group)
>> print(my_scene.XML())
>> 
>> => output
>> => <Scene>
>> =>  <Group/>
>> => </Scene>
>> 
>> my_other_scene = x.Scene()
>> print(my_other_scene.XML())
>> 
>> => output
>> => <Scene>
>> =>  <Group/>
>> => </Scene>
>> 
>> I think my_other_scene should be empty but remembers the content of the first scene.
>> Can you reproduce that ?
>> On the other hand this works (in a new session):
>> 
>> my_scene = x.Scene( children = [x.Group()] )
>> print(my_scene.XML())
>> 
>> => output
>> => <Scene>
>> =>  <Group/>
>> => </Scene>
>> 
>> my_other_scene = x.Scene()
>> print(my_other_scene.XML())  
>> 
>> => output
>> => <Scene>
>> => </Scene>
>> 
>> -- 
>> Andreas Plesch
>> Waltham, MA 02453
>> 
>> 
>> -- 
>> Andreas Plesch
>> Waltham, MA 02453
>> _______________________________________________
>> x3d-public mailing list
>> x3d-public at web3d.org <mailto:x3d-public at web3d.org>
>> http://web3d.org/mailman/listinfo/x3d-public_web3d.org
> 
> _______________________________________________
> x3d-public mailing list
> x3d-public at web3d.org
> http://web3d.org/mailman/listinfo/x3d-public_web3d.org

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20200512/bfbeebe7/attachment.html>


More information about the x3d-public mailing list