[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. |