77import  enum 
88import  traceback 
99import  warnings 
10+ import  weakref 
1011
1112from  ansys .dpf .core .mapping_types  import  types 
1213from  ansys .dpf .core  import  server  as  server_module 
@@ -64,16 +65,17 @@ class DataTree:
6465
6566    Notes 
6667    ----- 
67-     Class available with server's version starting at 4.0. 
68+     Class available with server's version starting at 4.0 (Ansys 2022R2) . 
6869    """ 
6970
7071    def  __init__ (self , data = None , data_tree = None , server = None ):
7172        # __set_attr__ method has been overridden, self._common_keys is used to list the "real" 
7273        # names used as its class attributes 
7374        self ._common_keys  =  ["_common_keys" , "_server" , "_internal_obj" , "_owner_data_tree" ,
74-                              "_dict" , "_api_instance" , "_deleter_func" ]
75+                              "_dict" , "_api_instance" , "_deleter_func" , "_holds_server_instance" ,
76+                              "_server_instance" , "_holds_server" ]
7577        # step 1: get server 
76-         self ._server  =  server_module .get_or_create_server (server )
78+         self ._server_instance  =  server_module .get_or_create_server (server )
7779
7880        if  data_tree  is  None  and  not  self ._server .meet_version ("4.0" ):
7981            raise  errors .DpfVersionNotSupported ("4.0" )
@@ -98,6 +100,24 @@ def __init__(self, data=None, data_tree=None, server=None):
98100        if  data :
99101            self .add (data )
100102
103+         self ._holds_server_instance  =  True 
104+ 
105+     @property  
106+     def  _holds_server (self ):
107+         return  self ._holds_server_instance 
108+ 
109+     @property  
110+     def  _server (self ):
111+         if  isinstance (self ._server_instance , weakref .ref ):
112+             return  self ._server_instance ()
113+         return  self ._server_instance 
114+ 
115+     @_holds_server .setter  
116+     def  _holds_server (self , value ):
117+         self ._holds_server_instance  =  value 
118+         if  value  is  False  and  not  isinstance (self ._server_instance , weakref .ref ):
119+             self ._server_instance  =  weakref .ref (self ._server_instance )
120+ 
101121    @property  
102122    def  _api (self ) ->  dpf_data_tree_abstract_api .DpfDataTreeAbstractAPI :
103123        if  not  self ._api_instance :
@@ -124,6 +144,7 @@ def add(self, *args, **kwargs):
124144        >>> data_tree.add(id=3, qualities=["nice", "funny"], name="George") 
125145
126146        """ 
147+ 
127148        def  add_data (self , key , value ):
128149            if  isinstance (value , str ):
129150                self ._api .dpf_data_tree_set_string_attribute (self , key , value , len (value ))
@@ -159,6 +180,7 @@ def add_data(self, key, value):
159180            else :
160181                raise  TypeError (f"{ type (value [0 ]).__name__ }  
161182                                "use lists, int, float, strings or DataTree." )
183+ 
162184        for  entry  in  args :
163185            for  key , value  in  entry .items ():
164186                add_data (self , key , value )
@@ -468,9 +490,10 @@ def __del__(self):
468490
469491class  _LocalDataTree (DataTree ):
470492    def  __init__ (self , data_tree ):
471-         self ._common_keys  =  ["_owner_data_tree" , "_dict" , "_common_keys" ]
493+         self ._common_keys  =  ["_owner_data_tree" , "_dict" , "_common_keys" ,  "_is_exited" ]
472494        self ._owner_data_tree  =  data_tree 
473495        self .__cache_data__ ()
496+         self ._is_exited  =  False 
474497
475498    def  add (self , * args , ** kwargs ):
476499        """ 
@@ -514,6 +537,6 @@ def __exit__(self, type_to_use, value, tb):
514537            print (tb )
515538
516539    def  __del__ (self ):
517-         if  not  hasattr ( self ,  "_is_exited" )  or   not   self ._is_exited :
540+         if  not  self ._is_exited :
518541            self ._is_exited  =  True 
519542            self .release_data ()
0 commit comments