@@ -619,21 +619,34 @@ def virtual_function(
619619        if  return_type  not  in DataType .values :
620620            return_type  =  self .create_converter (return_type )
621621
622-         def  fget (ptr ):
623-             """Return the virtual function.""" 
624-             # Create the virtual function 
625-             func  =  ptr .make_virtual_function (
626-                 index ,
627-                 convention ,
628-                 args ,
629-                 return_type 
630-             )
622+         class  fget (object ):
623+             def  __set_name__ (fget_self , owner , name ):
624+                 fget_self .name  =  name 
625+ 
626+             def  __get__ (fget_self , obj , cls = None ):
627+                 """Return the virtual function.""" 
628+                 if  obj  is  None :
629+                     return  fget_self 
630+ 
631+                 # Create the virtual function 
632+                 func  =  obj .make_virtual_function (
633+                     index ,
634+                     convention ,
635+                     args ,
636+                     return_type 
637+                 )
638+ 
639+                 # Wrap it using MemberFunction, so we don't have to pass the this 
640+                 # pointer anymore 
641+                 func  =  MemberFunction (self , return_type , func , obj )
642+                 func .__doc__  =  doc 
631643
632-             # Wrap it using MemberFunction, so we don't have to pass the this 
633-             # pointer anymore 
634-             return  MemberFunction (self , return_type , func , ptr )
644+                 # Set the MemberFunction as an attribute to the instance. 
645+                 setattr (obj , fget_self .name , func )
635646
636-         return  property (fget , None , None , doc )
647+                 return  func 
648+ 
649+         return  fget ()
637650
638651    def  function (
639652            self , identifier , args = (), return_type = DataType .VOID ,
@@ -646,34 +659,48 @@ def function(
646659        if  return_type  not  in DataType .values :
647660            return_type  =  self .create_converter (return_type )
648661
662+         # Store the function cache 
663+         func  =  None 
664+ 
649665        class  fget (object ):
666+             def  __set_name__ (fget_self , owner , name ):
667+                 fget_self .name  =  name 
668+ 
650669            def  __get__ (fget_self , obj , cls = None ):
670+                 nonlocal  func 
651671                if  cls  is  None :
652672                    if  obj  is  None :
653673                        return  fget_self 
654674                    else :
655675                        cls  =  obj .__class__ 
656676
657-                 if  cls ._binary  is  None :
658-                     raise  ValueError ('_binary was not specified.' )
677+                 if  func  is  None :
678+                     if  cls ._binary  is  None :
679+                         raise  ValueError ('_binary was not specified.' )
659680
660-                 # Create a binary object 
661-                 binary  =  find_binary (cls ._binary , cls ._srv_check )
681+                      # Create a binary object 
682+                      binary  =  find_binary (cls ._binary , cls ._srv_check )
662683
663-                 # Create the function object 
664-                 func  =  binary [identifier ].make_function (
665-                     convention ,
666-                     args ,
667-                     return_type 
668-                 )
684+                     # Create the function object and cache it 
685+                     func  =  binary [identifier ].make_function (
686+                         convention ,
687+                         args ,
688+                         return_type 
689+                     )
690+                     func .__doc__  =  doc 
669691
670692                # Called with a this pointer? 
671693                if  obj  is  not None :
672-                     # Wrap the function using MemberFunction, so we don't have 
673-                     # to pass the this pointer anymore 
674-                     func  =  MemberFunction (self , return_type , func , obj )
694+                     # Wrap the function using MemberFunction, 
695+                     # so we don't have to pass the this pointer anymore 
696+                     m_func  =  MemberFunction (self , return_type , func , obj )
697+                     m_func .__doc__  =  doc 
698+ 
699+                     # Set the MemberFunction as an attribute to the instance. 
700+                     setattr (obj , fget_self .name , m_func )
701+ 
702+                     return  m_func 
675703
676-                 func .__doc__  =  doc 
677704                return  func 
678705
679706        return  fget ()
0 commit comments