[pygccxml-commit] SF.net SVN: pygccxml: [958] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
|
From: <rom...@us...> - 2007-03-25 09:54:14
|
Revision: 958
http://svn.sourceforge.net/pygccxml/?rev=958&view=rev
Author: roman_yakovenko
Date: 2007-03-25 02:54:13 -0700 (Sun, 25 Mar 2007)
Log Message:
-----------
another attempt to solve "transfer ownership" problem
Modified Paths:
--------------
pyplusplus_dev/pyplusplus/code_creators/calldef.py
pyplusplus_dev/pyplusplus/code_creators/class_declaration.py
pyplusplus_dev/pyplusplus/code_creators/smart_pointers.py
pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py
pyplusplus_dev/pyplusplus/module_creator/creator.py
pyplusplus_dev/unittests/data/transfer_ownership_to_be_exported.hpp
pyplusplus_dev/unittests/indexing_suites2_tester.py
pyplusplus_dev/unittests/transfer_ownership_tester.py
Added Paths:
-----------
pyplusplus_dev/unittests/data/transfer_ownership_old_to_be_exported.hpp
pyplusplus_dev/unittests/transfer_ownership_old_tester.py
Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py
===================================================================
--- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2007-03-21 22:51:36 UTC (rev 957)
+++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2007-03-25 09:54:13 UTC (rev 958)
@@ -862,8 +862,9 @@
result.append( self.parent.wrapper_alias )
result.append( '(' )
args = []
- if not self.target_configuration.boost_python_has_wrapper_held_type:
- args.append( 'PyObject*' )
+ if not self.target_configuration.boost_python_has_wrapper_held_type \
+ or self.declaration.parent.require_self_reference:
+ args.append( 'PyObject* self' )
args_decl = self.args_declaration()
if args_decl:
args.append( args_decl )
@@ -905,17 +906,18 @@
"""
Creates wrapper class constructor from wrapped class instance.
"""
- def __init__( self, class_inst ):
+ def __init__( self, constructor ):
code_creator.code_creator_t.__init__( self )
- declaration_based.declaration_based_t.__init__( self, declaration=class_inst )
+ declaration_based.declaration_based_t.__init__( self, declaration=constructor )
def _create_declaration(self):
result = []
- result.append( self.parent.wrapper_alias )
+ result.append( self.parent.declaration.wrapper_alias )
result.append( '(' )
- if not self.target_configuration.boost_python_has_wrapper_held_type:
- result.append( 'PyObject*, ' )
- declarated = declarations.declarated_t( self.declaration )
+ if not self.target_configuration.boost_python_has_wrapper_held_type \
+ or self.declaration.parent.require_self_reference:
+ result.append( 'PyObject* self, ' )
+ declarated = declarations.declarated_t( self.declaration.parent )
const_decl = declarations.const_t( declarated )
const_ref_decl = declarations.reference_t( const_decl )
identifier = algorithm.create_identifier( self, const_ref_decl.decl_string )
@@ -933,7 +935,7 @@
answer.append( ': ' + self._create_constructor_call() )
answer.append( ' , ' + self.parent.boost_wrapper_identifier + '(){' )
answer.append( self.indent( '// copy constructor' ) )
- answer.append( self.indent( self.declaration.copy_constructor_body ) )
+ answer.append( self.indent( self.parent.declaration.copy_constructor_body ) )
answer.append( '}' )
return os.linesep.join( answer )
@@ -943,22 +945,23 @@
"""
Creates wrapper for compiler generated null constructor.
"""
- def __init__( self, class_inst ):
+ def __init__( self, constructor ):
code_creator.code_creator_t.__init__( self )
- declaration_based.declaration_based_t.__init__( self, declaration=class_inst )
-
+ declaration_based.declaration_based_t.__init__( self, declaration=constructor )
+
def _create_constructor_call( self ):
return algorithm.create_identifier( self, self.parent.declaration.decl_string ) + '()'
def _create_impl(self):
- answer = [ self.parent.wrapper_alias + '(' ]
- if not self.target_configuration.boost_python_has_wrapper_held_type:
- answer[0] = answer[0] + 'PyObject*'
+ answer = [ self.parent.declaration.wrapper_alias + '(' ]
+ if not self.target_configuration.boost_python_has_wrapper_held_type \
+ or self.declaration.parent.require_self_reference:
+ answer[0] = answer[0] + 'PyObject* self'
answer[0] = answer[0] + ')'
answer.append( ': ' + self._create_constructor_call() )
answer.append( ' , ' + self.parent.boost_wrapper_identifier + '(){' )
answer.append( self.indent( '// null constructor' ) )
- answer.append( self.indent( self.declaration.null_constructor_body ) )
+ answer.append( self.indent( self.parent.declaration.null_constructor_body ) )
answer.append( '}' )
return os.linesep.join( answer )
Modified: pyplusplus_dev/pyplusplus/code_creators/class_declaration.py
===================================================================
--- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2007-03-21 22:51:36 UTC (rev 957)
+++ pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2007-03-25 09:54:13 UTC (rev 958)
@@ -178,11 +178,17 @@
held_type = self._generated_held_type()
if self.wrapper:
- if not self.target_configuration.boost_python_has_wrapper_held_type:
+ if not self.target_configuration.boost_python_has_wrapper_held_type \
+ or self.declaration.require_self_reference:
args.append( algorithm.create_identifier( self, self.declaration.decl_string ) )
- args.append( self.wrapper.full_name )
+ if self.declaration.require_self_reference:
+ if not held_type:
+ args.append( self.wrapper.full_name )
+ else:
+ args.append( self.wrapper.full_name )
else:
args.append( algorithm.create_identifier( self, self.declaration.decl_string ) )
+
bases = self._generate_bases(base_creators)
if bases:
args.append( bases )
Modified: pyplusplus_dev/pyplusplus/code_creators/smart_pointers.py
===================================================================
--- pyplusplus_dev/pyplusplus/code_creators/smart_pointers.py 2007-03-21 22:51:36 UTC (rev 957)
+++ pyplusplus_dev/pyplusplus/code_creators/smart_pointers.py 2007-03-25 09:54:13 UTC (rev 958)
@@ -67,7 +67,8 @@
and self.class_creator.held_type \
and isinstance( self.class_creator.held_type, held_type_t ) \
and self.class_creator.held_type.smart_ptr == self.smart_ptr \
- and self.target_configuration.boost_python_has_wrapper_held_type:
+ and self.target_configuration.boost_python_has_wrapper_held_type \
+ and not self.class_creator.declaration.require_self_reference:
return '' #boost.python does it automaticly
rptp = algorithm.create_identifier( self, '::boost::python::register_ptr_to_python' )
held_type = held_type_t(self.smart_ptr).create( self )
Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py
===================================================================
--- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2007-03-21 22:51:36 UTC (rev 957)
+++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2007-03-25 09:54:13 UTC (rev 958)
@@ -194,7 +194,8 @@
self._exception_translation_code = None
self._properties = []
self._redefined_funcs = None
-
+ self._require_self_reference = False
+
def _get_redefine_operators( self ):
return self._redefine_operators
def _set_redefine_operators( self, new_value ):
@@ -528,3 +529,10 @@
if self.member_operators( is_assign, allow_empty=True, recursive=False ):
return impl_details.GAEUS_VALUES.ALWAYS_TRUE
return super(class_t, self).guess_always_expose_using_scope_value()
+
+ def _get_require_self_reference(self):
+ return self._require_self_reference
+ def _set_require_self_reference(self, require_self_reference):
+ self._require_self_reference = require_self_reference
+ require_self_reference = property( _get_require_self_reference, _set_require_self_reference
+ , doc="boolean, if True the first argument to the constructor will be reference to self object" )
Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py
===================================================================
--- pyplusplus_dev/pyplusplus/module_creator/creator.py 2007-03-21 22:51:36 UTC (rev 957)
+++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2007-03-25 09:54:13 UTC (rev 958)
@@ -626,12 +626,12 @@
#~ #to construct wrapper from wrapped classe
copy_constr = self.curr_decl.constructor( lambda c: c.is_copy_constructor, recursive=False )
if not self.curr_decl.noncopyable and copy_constr.is_artificial:
- copy_constr = code_creators.copy_constructor_wrapper_t( class_inst=self.curr_decl )
- wrapper.adopt_creator( copy_constr )
+ cccc = code_creators.copy_constructor_wrapper_t( constructor=copy_constr )
+ wrapper.adopt_creator( cccc )
null_constr = declarations.find_trivial_constructor(self.curr_decl)
if null_constr and null_constr.is_artificial:
#this constructor is not going to be exposed
- tcons = code_creators.null_constructor_wrapper_t( class_inst=self.curr_decl )
+ tcons = code_creators.null_constructor_wrapper_t( constructor=null_constr )
wrapper.adopt_creator( tcons )
exposed = self.expose_overloaded_mem_fun_using_macro( cls_decl, cls_cc )
Added: pyplusplus_dev/unittests/data/transfer_ownership_old_to_be_exported.hpp
===================================================================
--- pyplusplus_dev/unittests/data/transfer_ownership_old_to_be_exported.hpp (rev 0)
+++ pyplusplus_dev/unittests/data/transfer_ownership_old_to_be_exported.hpp 2007-03-25 09:54:13 UTC (rev 958)
@@ -0,0 +1,9 @@
+#ifndef __transfer_ownership_old_to_be_exported_hpp__
+#define __transfer_ownership_old_to_be_exported_hpp__
+
+#include <iostream>
+
+#include "transfer_ownership_to_be_exported.hpp"
+
+
+#endif//__transfer_ownership_old_to_be_exported_hpp__
Modified: pyplusplus_dev/unittests/data/transfer_ownership_to_be_exported.hpp
===================================================================
--- pyplusplus_dev/unittests/data/transfer_ownership_to_be_exported.hpp 2007-03-21 22:51:36 UTC (rev 957)
+++ pyplusplus_dev/unittests/data/transfer_ownership_to_be_exported.hpp 2007-03-25 09:54:13 UTC (rev 958)
@@ -8,7 +8,7 @@
notify();
}
protected:
- virtual void notify() = 0;
+ virtual void notify(){};
};
struct do_nothing_t : event_t{
@@ -22,6 +22,10 @@
m_event = event;
};
+ const event_t* get_event(){
+ return m_event;
+ }
+
void run() {
m_event->invoke();
delete m_event;
Modified: pyplusplus_dev/unittests/indexing_suites2_tester.py
===================================================================
--- pyplusplus_dev/unittests/indexing_suites2_tester.py 2007-03-21 22:51:36 UTC (rev 957)
+++ pyplusplus_dev/unittests/indexing_suites2_tester.py 2007-03-25 09:54:13 UTC (rev 958)
@@ -54,6 +54,8 @@
self.failUnless( kv.key == "x" and kv.value == "y" )
for k, v in name2value:
self.failUnless( k == "x" and v == "y" )
+ for k, v in name2value.iteritems():
+ self.failUnless( k == "x" and v == "y" )
items_ptr = module.items_ptr_t()
items_ptr.append( item )
Added: pyplusplus_dev/unittests/transfer_ownership_old_tester.py
===================================================================
--- pyplusplus_dev/unittests/transfer_ownership_old_tester.py (rev 0)
+++ pyplusplus_dev/unittests/transfer_ownership_old_tester.py 2007-03-25 09:54:13 UTC (rev 958)
@@ -0,0 +1,128 @@
+# Copyright 2004 Roman Yakovenko.
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import os
+import sys
+import unittest
+import fundamental_tester_base
+from pyplusplus import code_creators
+from pyplusplus.module_builder import call_policies
+from pyplusplus import function_transformers as ft
+
+decref_code = \
+"""
+virtual ~%(cls)s(){
+ Py_DECREF( boost::python::detail::wrapper_base_::get_owner(*this) );
+// if (this->m_pyobj) {
+// Py_DECREF(this->m_pyobj);
+// this->m_pyobj = 0;
+// }
+}
+"""
+
+incref_code = \
+"""
+//if( !this->m_pyobj) {
+ //this->m_pyobj = boost::python::detail::wrapper_base_::get_owner(*this);
+ std::cout << "py owner id: " << (int)(boost::python::detail::wrapper_base_::get_owner(*this));
+ //Py_INCREF(this->m_pyobj);
+//}
+"""
+
+impl_conv_code = \
+"""
+boost::python::implicitly_convertible< std::auto_ptr< %(from)s >, std::auto_ptr< %(to)s > >();
+"""
+
+register_sptr = \
+"""
+boost::python::register_ptr_to_python< %s >();
+"""
+
+class tester_t(fundamental_tester_base.fundamental_tester_base_t):
+ EXTENSION_NAME = 'transfer_ownership_old'
+
+ def __init__( self, *args ):
+ fundamental_tester_base.fundamental_tester_base_t.__init__(
+ self
+ , tester_t.EXTENSION_NAME
+ , *args )
+
+ def customize( self, mb ):
+ event_clss = mb.classes( lambda cls: cls.name in ( 'event_t', 'do_nothing_t' ) )
+ for cls in event_clss:
+ cls.require_self_reference = True
+ cls.set_constructors_body( 'Py_INCREF(self); std::cout<< "self: " << (int)(self) << "\\n" << (int)( boost::python::detail::wrapper_base_::get_owner(*this));' )
+ cls.add_wrapper_code( decref_code % { 'cls' : cls.wrapper_alias } )
+ #~ cls.add_wrapper_code( 'PyObject* m_pyobj;' )
+ #~ cls.set_constructors_body( 'm_pyobj=0;' )
+ cls.mem_fun( 'notify' ).add_override_precall_code( incref_code )
+ #~ cls.mem_fun( 'notify' ).add_default_precall_code( incref_code )
+
+ cls.held_type = 'std::auto_ptr< %s >' % cls.wrapper_alias
+ cls.add_registration_code( register_sptr % 'std::auto_ptr< %s >' % cls.decl_string, False )
+ cls.add_registration_code( register_sptr % 'std::auto_ptr< %s >' % cls.wrapper_alias, False )
+ #~ cls.held_type = 'std::auto_ptr< %s >' % cls.decl_string
+ cls.add_registration_code( impl_conv_code % { 'from' : cls.wrapper_alias
+ , 'to' : cls.decl_string }
+ , False)
+ for base in cls.recursive_bases:
+ if base.access_type == 'public':
+ cls.add_registration_code( #from class to its base
+ impl_conv_code % { 'from' : cls.decl_string
+ , 'to' : base.related_class.decl_string }
+ , False)
+
+ cls.add_registration_code( #from wrapper to clas base class
+ impl_conv_code % { 'from' : cls.wrapper_alias
+ , 'to' : base.related_class.decl_string }
+ , False)
+
+ simulator = mb.class_( 'simulator_t' )
+ simulator.mem_fun( 'get_event' ).call_policies \
+ = call_policies.return_internal_reference()
+ schedule = mb.mem_fun( 'schedule' )
+ schedule.add_transformation( ft.transfer_ownership(0), alias='schedule' )
+
+ def run_tests( self, module):
+ class py_event_t( module.event_t ):
+ def __init__( self, container ):
+ module.event_t.__init__( self )
+ self.container = container
+
+ def notify( self ):
+ print 'notify'
+ self.container.append( 1 )
+
+ print 'test started'
+ notify_data = []
+ simulator = module.simulator_t()
+ print 'simulator created'
+ event = py_event_t( notify_data )
+ print 'py_event_t created: ', id( event )
+ simulator.schedule( event )
+ print 'event was shceduled'
+ print 'event refcount: ', sys.getrefcount( event )
+ print 'simulator refcount: ', sys.getrefcount( simulator )
+ #del event
+ print 'event was deleted'
+ event = simulator.get_event()
+ print 'event was restored via saved reference in simulator: ', id( event )
+ print 'event refcount: ', sys.getrefcount( simulator.get_event() )
+ #print 'call event.notify(): ', simulator.get_event().notify()
+ print 'call simulator.run()'
+ simulator.run()
+ self.failUnless( notify_data[0] == 1 )
+
+def create_suite():
+ suite = unittest.TestSuite()
+ suite.addTest( unittest.makeSuite(tester_t))
+ return suite
+
+def run_suite():
+ unittest.TextTestRunner(verbosity=2).run( create_suite() )
+
+if __name__ == "__main__":
+ run_suite()
Modified: pyplusplus_dev/unittests/transfer_ownership_tester.py
===================================================================
--- pyplusplus_dev/unittests/transfer_ownership_tester.py 2007-03-21 22:51:36 UTC (rev 957)
+++ pyplusplus_dev/unittests/transfer_ownership_tester.py 2007-03-25 09:54:13 UTC (rev 958)
@@ -9,6 +9,7 @@
import fundamental_tester_base
from pyplusplus import code_creators
from pyplusplus import function_transformers as ft
+from pyplusplus.module_builder import call_policies
decref_code = \
"""
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|