Thread: [pygccxml-commit] SF.net SVN: pygccxml: [1259] pyplusplus_dev (Page 5)
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-02-25 07:25:25
|
Revision: 1259 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1259&view=rev Author: roman_yakovenko Date: 2008-02-24 23:25:27 -0800 (Sun, 24 Feb 2008) Log Message: ----------- adding new test case Modified Paths: -------------- pyplusplus_dev/docs/history/history.rest pyplusplus_dev/unittests/data/override_bug_to_be_exported.hpp pyplusplus_dev/unittests/override_bug_tester.py Modified: pyplusplus_dev/docs/history/history.rest =================================================================== --- pyplusplus_dev/docs/history/history.rest 2008-02-24 15:07:30 UTC (rev 1258) +++ pyplusplus_dev/docs/history/history.rest 2008-02-25 07:25:27 UTC (rev 1259) @@ -34,6 +34,99 @@ 3. Users always changed the name of the projects. I saw at least 6 different names. +----------- +Version SVN +----------- + +1. The algorithm, which calculates what member functions should be redefined in derived + class wrappers was improved. For example: + + .. code-block:: C++ + + struct A{ + virtual void foo() {} + }; + + class B: public A{ + }; + + Previous version of `Py++`_ didn't generate wrapper for class ``B``, even + though ``B`` inherits ``A``'s virtual function. Now if you have the following + Python code: + + .. code-block:: Python + + class C(B): + def __init__( self ): + B.__init__(self) + def foo(self): + print "C.foo" + + then when ``foo`` is invoked on this instance on the C++ side of things, the + Python code won't be executed as the wrapper is missing. + + If you use "function transformation" functionality, than it is possible the + generated code will not compile. Consider next example: + + .. code-block:: C++ + + struct A{ + virtual void foo(int& i) {/*do smth*/} + }; + + class B: public A{ + virtual void foo(int& i) {/*do smth else*/} + }; + + The `Py++`_ code: + + .. code-block:: Python + + from pyplusplus import module_builder + from pyplusplus import function_transformers as FT + + mb = module_builder_t( ... ) + foo = mb.mem_funs( 'foo' ) + foo.add_transformation( FT.output(0) ) + + The generated code of wrapper class, for class ``B``, will contain next code: + + .. code-block:: C++ + + virtual void foo() { + ... + } + + static boost::python::tuple default_foo( ::B & inst ){ + ... + } + + virtual void foo() { + ... + } + + static boost::python::tuple default_foo( ::B & inst ){ + ... + } + + Yes, the functions will be defined twice! In the previous version, the functions + were also defined twice but in the different classes. It was unclear, what + function will be called in this or that situation. + + If you have such situation, I suggest you to give aliases to the functions: + + .. code-block:: Python + + + from pyplusplus import module_builder + from pyplusplus import function_transformers as FT + + mb = module_builder_t( ... ) + for f in mb.mem_funs( 'foo' ) + foo.add_transformation( FT.output(0), alias=f.name + '_' + f.parent.name ) + + + ------------- Version 0.9.5 ------------- Modified: pyplusplus_dev/unittests/data/override_bug_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/override_bug_to_be_exported.hpp 2008-02-24 15:07:30 UTC (rev 1258) +++ pyplusplus_dev/unittests/data/override_bug_to_be_exported.hpp 2008-02-25 07:25:27 UTC (rev 1259) @@ -60,6 +60,18 @@ } +class AA +{ + public: + virtual void do_smth(int& i) const { i = 'a' ;} + virtual ~AA(){} +}; + +class BB: public AA +{ + virtual void do_smth(int& i) const { i = 'b' ;} +}; + } #endif//__final_classes_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/override_bug_tester.py =================================================================== --- pyplusplus_dev/unittests/override_bug_tester.py 2008-02-24 15:07:30 UTC (rev 1258) +++ pyplusplus_dev/unittests/override_bug_tester.py 2008-02-25 07:25:27 UTC (rev 1259) @@ -7,6 +7,7 @@ import sys import unittest import fundamental_tester_base +from pyplusplus import function_transformers as FT class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'override_bug' @@ -19,6 +20,9 @@ def customize( self, mb ): mb.class_("Derived2").member_functions("eval_c").exclude() + mb.class_( 'BB' ).include() + do_smth = mb.mem_funs( 'do_smth' ) + do_smth.add_transformation( FT.output(0) ) def run_tests(self, module): class C( module.B ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-06-03 05:20:11
|
Revision: 1324 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1324&view=rev Author: roman_yakovenko Date: 2008-06-02 22:20:17 -0700 (Mon, 02 Jun 2008) Log Message: ----------- fixing small issue related to unions Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/messages/warnings_.py pyplusplus_dev/unittests/data/classes_to_be_exported.hpp pyplusplus_dev/unittests/test_all.py Added Paths: ----------- pyplusplus_dev/unittests/data/embeded_to_be_exported.hpp pyplusplus_dev/unittests/embeded_tester.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-06-02 21:19:07 UTC (rev 1323) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-06-03 05:20:17 UTC (rev 1324) @@ -337,6 +337,8 @@ if not self.name: return messages.W1018 #it is possible to do so, but not for unnamed classes defined under namespace. + if self.class_type == declarations.CLASS_TYPES.UNION: + return messages.W1054 if isinstance( self.parent, declarations.namespace_t ): return '' if not self in self.parent.public_members: Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-06-02 21:19:07 UTC (rev 1323) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-06-03 05:20:17 UTC (rev 1324) @@ -216,6 +216,8 @@ W1053 = warning( 'Py++ will not expose function "%s" - the function has variable-argument list, spicified by ellipsis (...).' ) +W1054 = compilation_error( 'Py++ can not expose unions.' ) + warnings = globals() all_warning_msgs = [] Modified: pyplusplus_dev/unittests/data/classes_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/classes_to_be_exported.hpp 2008-06-02 21:19:07 UTC (rev 1323) +++ pyplusplus_dev/unittests/data/classes_to_be_exported.hpp 2008-06-03 05:20:17 UTC (rev 1324) @@ -95,6 +95,15 @@ } +union Word +{ + short word; + struct + { + char low, high; + }; +}; + }//classes namespace pyplusplus{ namespace aliases{ Added: pyplusplus_dev/unittests/data/embeded_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/embeded_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/embeded_to_be_exported.hpp 2008-06-03 05:20:17 UTC (rev 1324) @@ -0,0 +1,13 @@ +// 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) + +#ifndef __embeded_to_be_exported_hpp__ +#define __embeded_to_be_exported_hpp__ + +struct item_t{ + int i; +}; + +#endif//__embeded_to_be_exported_hpp__ Added: pyplusplus_dev/unittests/embeded_tester.py =================================================================== --- pyplusplus_dev/unittests/embeded_tester.py (rev 0) +++ pyplusplus_dev/unittests/embeded_tester.py 2008-06-03 05:20:17 UTC (rev 1324) @@ -0,0 +1,64 @@ +# 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.call_policies import * + +clone_def_code = """ + +namespace bpl = boost::python; + +bpl::object clone_item( const item_t& item ){ + std::auto_ptr< item_t > new_item( new item_t() ); + new_item->i = item.i; + return bpl::object( new_item ); +} + +""" + +clone_reg_code = """ + +def("clone_item", &clone_item ); + + bp::register_ptr_to_python< std::auto_ptr< item_t > >(); + +""" + + +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'embeded' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def customize(self, mb ): + mb.add_declaration_code( clone_def_code ) + mb.add_registration_code( clone_reg_code, True ) + + def run_tests( self, module): + item = module.item_t() + item.i = 78 + + item2 = module.clone_item(item) + self.failUnless( item2.i == item.i ) + self.failUnless( sys.getrefcount( item2 ) == 2 ) #one for boost.python second for current scope + +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/test_all.py =================================================================== --- pyplusplus_dev/unittests/test_all.py 2008-06-02 21:19:07 UTC (rev 1323) +++ pyplusplus_dev/unittests/test_all.py 2008-06-03 05:20:17 UTC (rev 1324) @@ -104,6 +104,7 @@ import split_module_indexing_suite_bug_tester import inner_tmpl_class_tester import bug_covariant_returns_tester +import embeded_tester testers = [ algorithms_tester @@ -195,6 +196,7 @@ , split_module_indexing_suite_bug_tester , inner_tmpl_class_tester , bug_covariant_returns_tester + , embeded_tester ] class module_runner_t( object ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-06-12 07:09:58
|
Revision: 1336 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1336&view=rev Author: roman_yakovenko Date: 2008-06-12 00:10:06 -0700 (Thu, 12 Jun 2008) Log Message: ----------- improving control over order of generated code for classes Thanks to Jason Kankiewicz for the patch Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/classes_tester.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-06-12 06:24:44 UTC (rev 1335) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-06-12 07:10:06 UTC (rev 1336) @@ -178,7 +178,8 @@ self._held_type = None self._noncopyable = None self._wrapper_alias = None - self._registration_code = [] + self._registration_code_head = [] + self._registration_code_tail = [] self._declaration_code = [] self._wrapper_code = [] self._null_constructor_body = '' @@ -236,17 +237,33 @@ def declaration_code( self ): """ List of strings, that contains valid C++ code, that will be added to - the class registration section + the class declaration section """ return self._declaration_code @property + def registration_code_head( self ): + """ + List of strings, that contains valid C++ code, that will be added to + the head of the class registration section + """ + return self._registration_code_head + + @property + def registration_code_tail( self ): + """ + List of strings, that contains valid C++ code, that will be added to + the tail of the class registration section + """ + return self._registration_code_tail + + @property def registration_code( self ): """ - List of strings, that contains valid C++ code, that will be added to + List of strings, that contains all C++ code, that will be added to the class registration section """ - return self._registration_code + return self.registration_code_head + self.registration_code_tail @property def wrapper_code( self ): @@ -311,13 +328,20 @@ """adds the code to the declaration section""" self.declaration_code.append( user_text.user_text_t( code ) ) - def add_registration_code( self, code, works_on_instance=True ): + def add_registration_code( self, code, works_on_instance=True, tail=True ): """adds the code to the class registration section - works_on_instance: If true, the custom code can be applied directly to obj inst. - Example: ObjInst."CustomCode" + @param works_on_instance: If true, the custom code can be applied directly to obj inst. Example: ObjInst.code + @type works_on_instance: bool + + @param tail: if True, the custom code is appended to the end of the class registration code. + @type tail: bool """ - self.registration_code.append( user_text.class_user_text_t( code, works_on_instance ) ) + if tail: + self.registration_code_tail.append( user_text.class_user_text_t( code, works_on_instance ) ) + else: + self.registration_code_head.append( user_text.class_user_text_t( code, works_on_instance ) ) + #preserving backward computability add_code = add_registration_code Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-06-12 06:24:44 UTC (rev 1335) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-06-12 07:10:06 UTC (rev 1336) @@ -244,11 +244,15 @@ ctext_t = code_creators.custom_text_t for cls_creator in class_creators: cls_decl = cls_creator.declaration - #uc = user code - uc_creators = map( lambda uc: ctext_t( uc.text, uc.works_on_instance ) - , cls_decl.registration_code ) - cls_creator.adopt_creators( uc_creators ) + uc_creators_head = map( lambda uc: ctext_t( uc.text, uc.works_on_instance ) + , cls_decl.registration_code_head ) + cls_creator.adopt_creators( uc_creators_head, 0 ) + + uc_creators_tail = map( lambda uc: ctext_t( uc.text, uc.works_on_instance ) + , cls_decl.registration_code_tail ) + cls_creator.adopt_creators( uc_creators_tail ) + uc_creators = map( lambda uc: ctext_t( uc.text ), cls_decl.wrapper_code ) if uc_creators: cls_creator.wrapper.adopt_creators( uc_creators ) Modified: pyplusplus_dev/unittests/classes_tester.py =================================================================== --- pyplusplus_dev/unittests/classes_tester.py 2008-06-12 06:24:44 UTC (rev 1335) +++ pyplusplus_dev/unittests/classes_tester.py 2008-06-12 07:10:06 UTC (rev 1336) @@ -22,6 +22,8 @@ apple = mb.class_( 'apple' ) self.failUnless( apple.alias == 'the_tastest_fruit' ) apple.alias = 'apple' + apple.add_registration_code( "/*head*/", works_on_instance=False, tail=False ) + apple.add_registration_code( "/*tail*/", works_on_instance=False, tail=True ) protected_static_t = mb.class_( 'protected_static_t' ) self.failUnless( 'PROTECTED_STATIC' in protected_static_t.alias) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-06-24 06:52:40
|
Revision: 1348 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1348&view=rev Author: roman_yakovenko Date: 2008-06-23 23:52:49 -0700 (Mon, 23 Jun 2008) Log Message: ----------- bug fix: code generation for arrays defined in global namespace Thanks to Hans Meine Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/global_variable.py pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp Modified: pyplusplus_dev/pyplusplus/code_creators/global_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/global_variable.py 2008-06-24 05:23:42 UTC (rev 1347) +++ pyplusplus_dev/pyplusplus/code_creators/global_variable.py 2008-06-24 06:52:49 UTC (rev 1348) @@ -122,7 +122,7 @@ def _create_namespaces(self): ns_names = declarations.declaration_path( self.declaration.parent ) - if len(ns_names) > 1 and ns_names[0] == '::': + if len(ns_names) >= 1 and ns_names[0] == '::': ns_names = ns_names[1:] return ns_names Modified: pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp 2008-06-24 05:23:42 UTC (rev 1347) +++ pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp 2008-06-24 06:52:49 UTC (rev 1348) @@ -21,4 +21,7 @@ } + +extern const char someSin[256]; + #endif//__global_variables_to_be_exported_hpp__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-13 20:49:52
|
Revision: 1369 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1369&view=rev Author: roman_yakovenko Date: 2008-07-13 13:50:00 -0700 (Sun, 13 Jul 2008) Log Message: ----------- adding initial support for ctypes module Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/global_variable.py pyplusplus_dev/pyplusplus/code_creators/member_variable.py pyplusplus_dev/pyplusplus/code_repository/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/bool_by_ref_tester.py pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp pyplusplus_dev/unittests/data/global_variables_to_be_exported.cpp pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp pyplusplus_dev/unittests/global_variables_tester.py pyplusplus_dev/unittests/member_variables_tester.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -91,6 +91,7 @@ from global_variable import global_variable_t from global_variable import array_gv_t from global_variable import array_gv_wrapper_t +from global_variable import global_variable_addressof_t from member_variable import member_variable_base_t from member_variable import member_variable_t @@ -101,6 +102,7 @@ from member_variable import array_mv_wrapper_t from member_variable import mem_var_ref_t from member_variable import mem_var_ref_wrapper_t +from member_variable import member_variable_addressof_t from class_declaration import class_t from class_declaration import class_wrapper_t Modified: pyplusplus_dev/pyplusplus/code_creators/global_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/global_variable.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/code_creators/global_variable.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -56,7 +56,7 @@ else: obj_identifier = algorithm.create_identifier( self, '::boost::python::object' ) ref_identifier = algorithm.create_identifier( self, '::boost::ref' ) - result.append( ' = %s( %s( %s ) );' % ( obj_identifier, ref_identifier, self.decl_identifier ) ) + result.append( ' = %s( %s( %s ) );' % ( obj_identifier, ref_identifier, self.decl_identifier ) ) return ''.join( result ) class array_gv_t( global_variable_base_t ): @@ -74,7 +74,7 @@ def _create_impl( self ): if self.declaration.already_exposed: return '' - + answer = [] answer.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) answer.append( '().attr("%s")' % self.alias ) @@ -141,7 +141,7 @@ def _create_impl( self ): if self.declaration.already_exposed: return '' - + answer = [self._create_namespaces_name()] answer.append( self.wrapper_type.decl_string ) answer.append( ''.join([ self.wrapper_creator_name, '(){']) ) @@ -157,3 +157,28 @@ def _get_system_headers_impl( self ): return [code_repository.array_1.file_name] + +class global_variable_addressof_t( global_variable_base_t ): + """ + Creates boost.python code that exposes address of global variable. + + This functionality is pretty powerful if you use it with "ctypes" - + standard package. + """ + def __init__(self, variable ): + global_variable_base_t.__init__( self, variable=variable ) + + def _create_impl(self): + if self.declaration.already_exposed: + return '' + + assert isinstance( self.declaration, pygccxml.declarations.variable_t ) + result = [] + #TODO: porting to 64Bit is welcome + result.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) + result.append( '().attr("%s")' % self.alias ) + result.append( ' = boost::uint32_t( boost::addressof( %s ) );' % self.decl_identifier ) + return ''.join( result ) + + def _get_system_headers_impl( self ): + return [code_repository.ctypes_integration.file_name] Modified: pyplusplus_dev/pyplusplus/code_creators/member_variable.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -30,7 +30,7 @@ def _set_wrapper( self, new_wrapper ): self._wrapper = new_wrapper wrapper = property( _get_wrapper, _set_wrapper ) - + def _get_system_headers_impl( self ): files = [] if self.declaration.getter_call_policies: @@ -38,7 +38,7 @@ if self.declaration.setter_call_policies: files.append( self.declaration.setter_call_policies.header_file ) return files - + class member_variable_t( member_variable_base_t ): """ Creates boost.python code that exposes member variable. @@ -130,12 +130,12 @@ doc = self.documentation add_property = 'add_property' add_property_args = [ '"%s"' % self.alias ] - getter_code = declarations.call_invocation.join( + getter_code = declarations.call_invocation.join( make_getter , [ '&' + self.decl_identifier , self.declaration.getter_call_policies.create( self ) ] , os.linesep + self.indent( self.PARAM_SEPARATOR, 6) ) - + add_property_args.append( getter_code ) if not self.declaration.is_read_only: setter_code = '' @@ -143,14 +143,14 @@ if self.declaration.setter_call_policies \ and not self.declaration.setter_call_policies.is_default(): setter_args.append( self.declaration.setter_call_policies.create( self ) ) - setter_code = declarations.call_invocation.join( + setter_code = declarations.call_invocation.join( make_setter , setter_args , os.linesep + self.indent( self.PARAM_SEPARATOR, 6) ) add_property_args.append( setter_code) if doc: add_property_args.append( doc ) - return declarations.call_invocation.join( + return declarations.call_invocation.join( add_property , add_property_args , os.linesep + self.indent( self.PARAM_SEPARATOR, 4 ) ) @@ -391,7 +391,7 @@ answer = [] answer.append( 'typedef %s;' % self.wrapper.wrapper_creator_type.create_typedef( 'array_wrapper_creator' ) ) answer.append( os.linesep * 2 ) - + doc = '' if self.declaration.type_qualifiers.has_static: answer.append( self.parent.class_var_name + '.add_static_property' ) @@ -425,7 +425,7 @@ answer.append( os.linesep ) answer.append( '}' ) return ''.join( answer ) - + def _get_system_headers_impl( self ): return [] @@ -445,7 +445,7 @@ @property def wrapper_type( self ): tmpl = "%(namespace)s::%(constness)sarray_1_t< %(item_type)s, %(array_size)d>" - + constness = '' if declarations.is_const( self.declaration.type ): constness = 'const_' @@ -463,14 +463,14 @@ if declarations.is_const( self.declaration.type ): wrapped_cls_type = declarations.const_t( wrapped_cls_type ) return declarations.reference_t( wrapped_cls_type ) - + @property def wrapper_creator_type(self): return declarations.free_function_type_t( return_type=self.wrapper_type , arguments_types=[self.wrapped_class_type] ) - - @property + + @property def wrapper_creator_name(self): return '_'.join( ['pyplusplus', self.declaration.name, 'wrapper'] ) @@ -494,8 +494,8 @@ def _get_system_headers_impl( self ): return [code_repository.array_1.file_name] - + class mem_var_ref_t( member_variable_base_t ): """ Creates C++ code that creates accessor for class member variable, that has type reference. @@ -644,3 +644,39 @@ def _get_system_headers_impl( self ): return [] + +class member_variable_addressof_t( member_variable_base_t ): + """ + Creates boost.python code that exposes address of member variable. + + This functionality is pretty powerful if you use it with "ctypes" - + standard package. + + """ + def __init__(self, variable, wrapper=None ): + member_variable_base_t.__init__( self, variable=variable, wrapper=wrapper ) + + def _create_impl( self ): + doc = '' #static property does not support documentation + if self.declaration.type_qualifiers.has_static: + add_property = 'add_static_property' + else: + if self.documentation: + doc = self.documentation + add_property = 'add_property' + answer = [ add_property ] + answer.append( '( ' ) + answer.append('"%s"' % self.alias) + answer.append( self.PARAM_SEPARATOR ) + + answer.append( 'pyplus_conv::make_addressof_getter(&%s)' + % self.decl_identifier ) + if doc: + answer.append( self.PARAM_SEPARATOR ) + answer.append( doc ) + answer.append( ' ) ' ) + + return ''.join( answer ) + + def _get_system_headers_impl( self ): + return [code_repository.ctypes_integration.file_name] Modified: pyplusplus_dev/pyplusplus/code_repository/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/__init__.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/code_repository/__init__.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -19,8 +19,15 @@ import convenience import return_range import call_policies +import ctypes_integration -all = [ array_1, gil_guard, convenience, call_policies, named_tuple, return_range ] +all = [ array_1 + , gil_guard + , convenience + , call_policies + , named_tuple + , return_range + , ctypes_integration ] headers = map( lambda f: f.file_name, all ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -21,6 +21,7 @@ self._apply_smart_ptr_wa = False self._is_read_only = None self._use_make_functions = None + self._expose_address = None __call_policies_doc__ = \ """There are usecase, when exporting member variable forces Py++ to @@ -89,7 +90,27 @@ self._use_make_functions = value use_make_functions = property( get_use_make_functions, set_use_make_functions , doc=__use_make_functions_doc__) + + __expose_address_doc__ = \ + """There are some cases when Boost.Python doesn't provide a convenient way + to expose the variable to Python. For example: + double* x[10]; + //or + char* buffer; //in case you want to modify the buffer in place + + In this cases Py++ doesn't help too. In these cases it is possible to expose + the actual address of the variable. After that, you can use built-in "ctypes" + package to edit the content of the variable. + """ + def get_expose_address( self ): + return self._expose_address + def set_expose_address( self, value ): + self._expose_address = value + expose_address = property( get_expose_address, set_expose_address + , doc= __expose_address_doc__ ) + + def __find_out_is_read_only(self): type_ = declarations.remove_alias( self.type ) @@ -127,14 +148,15 @@ return messages.W1033 if self.bits == 0 and self.name == "": return messages.W1034 - if declarations.is_array( self.type ) and declarations.array_size( self.type ) < 1: - return messages.W1045 + if not self.expose_address: + if declarations.is_array( self.type ) and declarations.array_size( self.type ) < 1: + return messages.W1045 type_ = declarations.remove_alias( self.type ) type_ = declarations.remove_const( type_ ) if declarations.is_pointer( type_ ): - if self.type_qualifiers.has_static: + if not self.expose_address and self.type_qualifiers.has_static: return messages.W1035 - if python_traits.is_immutable( type_.base ): + if not self.expose_address and python_traits.is_immutable( type_.base ): return messages.W1036 units = declarations.decompose_type( type_ ) Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -309,7 +309,7 @@ if not ( None is element_type ) and class_traits.is_my_case( element_type ): value_cls = class_traits.get_declaration( element_type ) has_prerequisits = value_cls.less_than_comparable \ - and value_cls.equality_comparable + and value_cls.equality_comparable if ( not has_prerequisits ) and ( value_cls not in created_value_traits ): created_value_traits.add( value_cls ) element_type_cc = code_creators.value_traits_t( value_cls ) @@ -576,19 +576,19 @@ self.__extmodule.adopt_declaration_creator( wrapper ) #next constructors are not present in code, but compiler generated - #Boost.Python requiers them to be declared in the wrapper class + #Boost.Python requiers them to be declared in the wrapper class noncopyable_vars = self.curr_decl.find_noncopyable_vars() - + copy_constr = self.curr_decl.find_copy_constructor() if not self.curr_decl.noncopyable and copy_constr and copy_constr.is_artificial: cccc = code_creators.copy_constructor_wrapper_t( class_=self.curr_decl) wrapper.adopt_creator( cccc ) - trivial_constr = self.curr_decl.find_trivial_constructor() + trivial_constr = self.curr_decl.find_trivial_constructor() if trivial_constr and trivial_constr.is_artificial and not noncopyable_vars: tcons = code_creators.null_constructor_wrapper_t( class_=self.curr_decl ) wrapper.adopt_creator( tcons ) - + exposed = self.expose_overloaded_mem_fun_using_macro( cls_decl, cls_cc ) cls_parent_cc.adopt_creator( cls_cc ) @@ -655,6 +655,15 @@ self.__types_db.update( self.curr_decl ) self.__dependencies_manager.add_exported( self.curr_decl ) + if self.curr_decl.expose_address: + creator_type = None + if isinstance( self.curr_decl.parent, declarations.namespace_t ): + creator_type = code_creators.global_variable_addressof_t + else: + creator_type = code_creators.member_variable_addressof_t + self.curr_code_creator.adopt_creator( creator_type(self.curr_decl) ) + return + if declarations.is_array( self.curr_decl.type ): if self._register_array_1( self.curr_decl.type ): array_1_registrator = code_creators.array_1_registrator_t( array_type=self.curr_decl.type ) Modified: pyplusplus_dev/unittests/bool_by_ref_tester.py =================================================================== --- pyplusplus_dev/unittests/bool_by_ref_tester.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/bool_by_ref_tester.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -33,7 +33,7 @@ module.listener.__init__(self) def listen( self, id, name, skip): print "Python: listen called with", id, name, skip - return True ## Test always returns True... + return 11## Test always returns True... c = list1() ret = module.callListener( c ) Modified: pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/data/bool_by_ref_to_be_exported.hpp 2008-07-13 20:50:00 UTC (rev 1369) @@ -5,13 +5,13 @@ class listener { public: - virtual void listen(int id, const std::string& name, bool& skip) { + virtual void listen(int id, const std::string& name, int& skip) { throw std::runtime_error ( std::string ("Virtual function listener::listen called!") ); } }; bool callListener ( listener* myListener) { - bool skip = false; + int skip = 10; std::cout << "C++: Calling myListener->listen\n"; myListener->listen(100, "test", skip); std::cout << "C++: Called OK " << skip <<"\n"; Modified: pyplusplus_dev/unittests/data/global_variables_to_be_exported.cpp =================================================================== --- pyplusplus_dev/unittests/data/global_variables_to_be_exported.cpp 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/data/global_variables_to_be_exported.cpp 2008-07-13 20:50:00 UTC (rev 1369) @@ -5,20 +5,25 @@ #include "global_variables_to_be_exported.hpp" -namespace global_variables{ +namespace global_variables{ const color const_var = red; color non_const_var = blue; data garray[10]; double arr_of_doubles[100]; - + void init_garray(){ for( int i =0; i < 10; ++i ){ garray[i].value = -i; } } +int some_value = -7; +int get_some_value(){ return some_value; } +unsigned int get_some_value_address(){ return (unsigned int)( &some_value ); } + } -const char someSin[3] = "AB"; \ No newline at end of file + +const char someSin[3] = "AB"; Modified: pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/data/global_variables_to_be_exported.hpp 2008-07-13 20:50:00 UTC (rev 1369) @@ -6,7 +6,7 @@ #ifndef __global_variables_to_be_exported_hpp__ #define __global_variables_to_be_exported_hpp__ -namespace global_variables{ +namespace global_variables{ enum color{ red, green, blue }; @@ -19,6 +19,12 @@ extern double arr_of_doubles[100]; void init_garray(); +extern int some_value; + +int get_some_value(); + +unsigned int get_some_value_address(); + } Modified: pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/data/member_variables_to_be_exported.hpp 2008-07-13 20:50:00 UTC (rev 1369) @@ -9,12 +9,12 @@ #include <string> #include <iostream> -namespace member_variables{ +namespace member_variables{ struct point{ enum color{ red, green, blue }; - - point() + + point() : prefered_color( blue ) , x( -1 ) , y( 2 ) @@ -42,7 +42,7 @@ unsigned int a : 1; unsigned int : 0; const unsigned int b : 11; -}; +}; unsigned int get_a(const bit_fields_t& inst); void set_a( bit_fields_t& inst, unsigned int new_value ); @@ -55,17 +55,17 @@ } } - struct variable_t{ + struct variable_t{ variable_t() : value(-9){} - int value; + int value; }; int get_ivars_item( int index ){ return ivars[index]; } - + const variable_t vars[3]; - int ivars[10]; + int ivars[10]; int ivars2[10]; }; @@ -78,10 +78,10 @@ }; struct tree_node_t{ - + data_t *data; tree_node_t *left; - tree_node_t *right; + tree_node_t *right; const tree_node_t *parent; tree_node_t(const tree_node_t* parent=0) @@ -90,7 +90,7 @@ , right( 0 ) , parent( parent ) {} - + ~tree_node_t(){ std::cout << "\n~tree_node_t"; } @@ -108,7 +108,7 @@ fundamental_t( EFruit& fruit, const int& i ) : m_fruit( fruit ), m_i( i ) {} - + EFruit& m_fruit; const int& m_i; }; @@ -151,5 +151,17 @@ } +namespace ctypes{ + struct image_t{ + image_t(){ + data = new int[5]; + for(int i=0; i<5; i++){ + data[i] = i; + } + } + int* data; + }; } + +} #endif//__member_variables_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/global_variables_tester.py =================================================================== --- pyplusplus_dev/unittests/global_variables_tester.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/global_variables_tester.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -5,22 +5,24 @@ import os import sys +import ctypes import unittest import fundamental_tester_base class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'global_variables' - + def __init__( self, *args ): - fundamental_tester_base.fundamental_tester_base_t.__init__( + fundamental_tester_base.fundamental_tester_base_t.__init__( self , tester_t.EXTENSION_NAME , *args ) - - def customize(self, mb ): + + def customize(self, mb ): mb.variable('non_const_var').alias = 'NonConstVar' + mb.variable( 'some_value' ).expose_address = True - def run_tests(self, module): + def run_tests(self, module): self.failUnless( module.NonConstVar == module.color.blue ) self.failUnless( module.const_var == module.color.red ) module.init_garray() @@ -28,11 +30,19 @@ for index in range( 10 ): self.failUnless( -index == module.garray[index].value ) self.failUnless( 3 == len( module.someSin ) - and module.someSin[0] == 'A' + and module.someSin[0] == 'A' and module.someSin[1] == 'B' and module.someSin[2] == '\0' ) + + self.failUnless( module.some_value == module.get_some_value_address() ) + self.failUnless( -7 == module.get_some_value() ) + x = ctypes.c_int.from_address( module.some_value ) + self.failUnless( x.value == module.get_some_value() ) + x.value = 9 + self.failUnless( x.value == module.get_some_value() == 9) + def create_suite(): - suite = unittest.TestSuite() + suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) return suite Modified: pyplusplus_dev/unittests/member_variables_tester.py =================================================================== --- pyplusplus_dev/unittests/member_variables_tester.py 2008-07-13 20:48:20 UTC (rev 1368) +++ pyplusplus_dev/unittests/member_variables_tester.py 2008-07-13 20:50:00 UTC (rev 1369) @@ -5,35 +5,39 @@ import os import sys +import ctypes import unittest import fundamental_tester_base +import pdb class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'member_variables' - + def __init__( self, *args ): - fundamental_tester_base.fundamental_tester_base_t.__init__( + fundamental_tester_base.fundamental_tester_base_t.__init__( self , tester_t.EXTENSION_NAME , *args ) - - def customize(self, mb ): + + def customize(self, mb ): mb.variable( 'prefered_color' ).alias = 'PreferedColor' mb.classes().always_expose_using_scope = True + image = mb.class_( 'image_t' ) + image.var( 'data' ).expose_address = True def change_default_color( self, module ): module.point.default_color = module.point.color.blue - + def change_prefered_color( self, module ): - xypoint = module.point() + xypoint = module.point() xypoint.PreferedColor = module.point.color.blue - + def set_b( self, bf, value ): bf.b = value - - def run_tests(self, module): + + def run_tests(self, module): self.failIfRaisesAny( module.point ) - xypoint = module.point() + xypoint = module.point() self.failUnless( module.point.instance_count == 1) self.failUnless( xypoint.instance_count == 1) self.failUnless( module.point.default_color == module.point.color.red) @@ -49,43 +53,52 @@ self.failUnless( 1 == bf.a ) self.failUnless( bf.b == module.get_b( bf ) ) self.failIfNotRaisesAny( lambda: self.set_b( bf, 23 ) ) - + array = module.array_t() self.failUnless( len( array.vars ) == 3 ) for i in range( len( array.vars ) ): self.failUnless( array.vars[i].value == -9 ) self.failUnless( len( array.ivars ) == 10 ) - + ivars = array.ivars del array #testing call policies for i in range(20): for index in range(10): self.failUnless( ivars[index] == -index ) - + array = module.array_t() for index in range( len(array.ivars) ): array.ivars[index] = index * index self.failUnless( array.get_ivars_item( index ) == index * index ) - + tree = module.create_tree() self.failUnless( tree.parent is None ) self.failUnless( tree.data.value == 0 ) self.failUnless( tree.right is None ) self.failUnless( tree.left ) self.failUnless( tree.left.data.value == 1 ) - + tree.right = module.create_tree() self.failUnless( tree.right.parent is None ) self.failUnless( tree.right.data.value == 0 ) self.failUnless( tree.right.right is None ) self.failUnless( tree.right.left ) self.failUnless( tree.right.left.data.value == 1 ) - + mem_var_str = module.mem_var_str_t() mem_var_str.identity( module.mem_var_str_t.class_name ) - + + image = module.image_t() + + #pdb.set_trace() + data_type = ctypes.POINTER( ctypes.c_int ) + data = data_type.from_address( image.data ) + for j in range(5): + print '%d : %d' % ( j, data[j] ) + + def create_suite(): - suite = unittest.TestSuite() + suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) return suite @@ -93,4 +106,4 @@ unittest.TextTestRunner(verbosity=2).run( create_suite() ) if __name__ == "__main__": - run_suite() \ No newline at end of file + run_suite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-07-14 18:58:35
|
Revision: 1372 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1372&view=rev Author: roman_yakovenko Date: 2008-07-14 11:58:40 -0700 (Mon, 14 Jul 2008) Log Message: ----------- adding ablity to generate class wrapper destructor Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/calldef.py pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/messages/warnings_.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/transfer_ownership_tester.py Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -68,6 +68,7 @@ from calldef import casting_operator_t from calldef import mem_fun_overloads_t from calldef import free_fun_overloads_t +from calldef import destructor_wrapper_t from calldef import casting_constructor_t from calldef import constructor_wrapper_t from calldef import mem_fun_overloads_class_t Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -1157,7 +1157,25 @@ def _get_system_headers_impl( self ): return [] +class destructor_wrapper_t( code_creator.code_creator_t + , declaration_based.declaration_based_t ): + """ + Creates class wrapper destructor from the code provided by the user + """ + def __init__( self, class_ ): + code_creator.code_creator_t.__init__( self ) + declaration_based.declaration_based_t.__init__( self, declaration=class_ ) + def _create_impl(self): + answer = [ 'virtual ~%s(){' % self.declaration.wrapper_alias ] + answer.append( self.indent( os.linesep.join( self.declaration.destructor_code ) ) ) + answer.append( '}' ) + return os.linesep.join( answer ) + + def _get_system_headers_impl( self ): + return [] + + class calldef_overloads_class_t( code_creator.code_creator_t ): def __init__( self, functions ): #precondition: all member functions belong to same class and Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -76,8 +76,8 @@ @property def indexing_suite( self ): - """reference to indexing suite configuration class. - + """reference to indexing suite configuration class. + If the class is not STD container, this property will contain None" """ if self._indexing_suite is None: @@ -105,7 +105,7 @@ else: self._always_expose_using_scope = False return self._always_expose_using_scope - + def _set_always_expose_using_scope( self, value ): self._always_expose_using_scope = value always_expose_using_scope = property( _get_always_expose_using_scope, _set_always_expose_using_scope @@ -134,12 +134,12 @@ less_than_comparable = property( _get_less_than_comparable, _set_less_than_comparable , doc="indicates existence of public operator<. " \ +"Default value is calculated, based on information presented in the declarations tree" ) - + def _get_opaque( self ): return self._opaque def _set_opaque( self, value ): - self._opaque = value + self._opaque = value self.ignore = value #don't expose opaque type opaque = property( _get_opaque, _set_opaque @@ -163,12 +163,12 @@ class class_t( class_common_details_t , scopedef_wrapper.scopedef_t , declarations.class_t): - + class EXPOSED_CLASS_TYPE: DECLARED = 'declared' WRAPPER = 'wrapper' ALL = ( DECLARED, WRAPPER ) - + def __init__(self, *arguments, **keywords): class_common_details_t.__init__( self ) declarations.class_t.__init__(self, *arguments, **keywords ) @@ -177,19 +177,20 @@ self._redefine_operators = False self._held_type = None self._noncopyable = None - self._wrapper_alias = None + self._wrapper_alias = None self._registration_code_head = [] self._registration_code_tail = [] self._declaration_code = [] self._wrapper_code = [] self._null_constructor_body = '' self._copy_constructor_body = '' + self._destructor_code = [] self._exception_translation_code = None self._properties = [] self._redefined_funcs = None self._require_self_reference = False self._exposed_class_type = self.EXPOSED_CLASS_TYPE.DECLARED - + def _get_redefine_operators( self ): return self._redefine_operators def _set_redefine_operators( self, new_value ): @@ -288,6 +289,15 @@ , doc="copy constructor code, that will be added as is to the copy constructor of class-wrapper") @property + def destructor_code(self): + """list of code to be added to wrapper destructor""" + return self._destructor_code + + def add_destructor_code(self, code): + """adds code to the class-wrapper destructor""" + self._destructor_code.append( code ) + + @property def exception_argument_name( self ): """exception argument name for translate exception function @@ -341,7 +351,7 @@ self.registration_code_tail.append( user_text.class_user_text_t( code, works_on_instance ) ) else: self.registration_code_head.append( user_text.class_user_text_t( code, works_on_instance ) ) - + #preserving backward computability add_code = add_registration_code @@ -385,7 +395,7 @@ vfunction_selector = lambda member: isinstance( member, declarations.member_function_t ) \ and member.virtuality == declarations.VIRTUALITY_TYPES.PURE_VIRTUAL members.extend( filter( vfunction_selector, self.private_members ) ) - + def is_exportable( decl ): #filter out non-public member operators - Py++ does not support them right now if isinstance( decl, declarations.member_operator_t ) \ @@ -396,7 +406,7 @@ return False if decl.ignore == True or decl.exportable == False: return False - return True + return True #-#if declarations.has_destructor( self ) \ #-# and not declarations.has_public_destructor( self ): members = filter( is_exportable, members ) @@ -425,7 +435,7 @@ def add_properties( self, recognizer=None, exclude_accessors=False ): props = properties.find_properties( self, recognizer, exclude_accessors ) self.properties.extend( props ) - + def add_static_property( self, name, fget, fset=None, doc='' ): """adds new static property to the class""" self._properties.append( properties.property_t( name, fget, fset, doc, True ) ) @@ -456,14 +466,14 @@ all_included = declarations.custom_matcher_t( lambda decl: decl.ignore == False and decl.exportable ) all_protected = declarations.access_type_matcher_t( 'protected' ) & all_included - all_pure_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.PURE_VIRTUAL ) + all_pure_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.PURE_VIRTUAL ) all_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.VIRTUAL ) \ & ( declarations.access_type_matcher_t( 'public' ) \ - | declarations.access_type_matcher_t( 'protected' )) + | declarations.access_type_matcher_t( 'protected' )) all_not_pure_virtual = ~all_pure_virtual - query = all_protected | all_pure_virtual - mf_query = query | all_virtual + query = all_protected | all_pure_virtual + mf_query = query | all_virtual relevant_opers = declarations.custom_matcher_t( lambda decl: decl.symbol in ('()', '[]') ) funcs = [] defined_funcs = [] @@ -493,7 +503,7 @@ if declarations.is_base_and_derived( f_impl.parent, f.parent ): #add function from the most derived class not_reimplemented_funcs.remove( f_impl ) - not_reimplemented_funcs.add( f ) + not_reimplemented_funcs.add( f ) break else: #should test whether this function is implemented in base class @@ -504,18 +514,18 @@ if is_same_function( f, f_defined ): break else: - not_reimplemented_funcs.add( f ) + not_reimplemented_funcs.add( f ) functions = filter( lambda f: ( False == f.ignore and True == f.exportable ) or all_pure_virtual( f ) , list( not_reimplemented_funcs ) ) - + #Boost.Python is not able to call for non-virtual function, from the base #class if there is a virtual function with the same within base class #See override_bug tester for more information def buggy_bpl_filter( f ): - if f.parent is self: + if f.parent is self: return False if f.access_type != ACCESS_TYPES.PUBLIC: return False @@ -564,6 +574,9 @@ if self.copy_constructor_body: explanation.append( messages.W1022 ) + if self.destructor_code: + explanation.append( messages.W1055 ) + redefined_funcs = self.redefined_funcs() if redefined_funcs: funcs = map( lambda f: f.name, redefined_funcs ) @@ -607,7 +620,7 @@ #MSVC 7.1 has problem with taking reference to operator= if self.member_operators( is_assign, allow_empty=True, recursive=False ): return impl_details.GUESS_VALUES.ALWAYS_TRUE - return super(class_t, self).guess_always_expose_using_scope_value() + return super(class_t, self).guess_always_expose_using_scope_value() def _get_require_self_reference(self): return self._require_self_reference Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -3,7 +3,7 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -"""This package defines all user messages (warnings + errors), which will be +"""This package defines all user messages (warnings + errors), which will be reported to user. """ @@ -11,13 +11,13 @@ """implementation details""" def __new__(self, value, identifier=None): return str.__new__(self, value ) - + def __init__(self, value, identifier=None): - self.__identifier = identifier - + self.__identifier = identifier + @property def identifier( self ): - return self.__identifier + return self.__identifier def __mod__( self, values ): str_value = super( message_type, self ).__str__() @@ -34,55 +34,55 @@ W0000 = warning( '%s' ) #general message, usefull in few cases -W1000 = compilation_error( +W1000 = compilation_error( 'Py++, by default, does not expose internal compilers declarations. ' 'Names of those declarations usually start with "__".' ) -W1001 = compilation_error( +W1001 = compilation_error( 'Py++, by default, does not expose internal declarations. ' 'GCC-XML reports that these declaration belong to "<internal>" header.' ) -W1002 = compilation_error( +W1002 = compilation_error( 'Py++, by default, does not expose compiler generated declarations.' ) -W1003 = warning( - 'Virtual functions that returns const reference cannot be overridden from Python. ' - 'Reason: boost::python::override::operator()(...) saves the result of the marshaling ' - '(from Python to C++) on the stack. Thus operator() returns reference ' - 'to a temporary variable. Consider to use "Function Transformation" functionality ' +W1003 = warning( + 'Virtual functions that returns const reference cannot be overridden from Python. ' + 'Reason: boost::python::override::operator()(...) saves the result of the marshaling ' + '(from Python to C++) on the stack. Thus operator() returns reference ' + 'to a temporary variable. Consider to use "Function Transformation" functionality ' 'to solve the problem.' ) -W1004 = compilation_error( - 'Boost.Python library can not expose function, which takes as argument/returns ' - 'pointer to function. ' +W1004 = compilation_error( + 'Boost.Python library can not expose function, which takes as argument/returns ' + 'pointer to function. ' ' See http://www.boost.org/libs/python/doc/v2/faq.html#funcptr for more information.' ) -W1005 = compilation_error( - 'Py++ cannot expose function that takes as argument/returns instance of non-public class. ' +W1005 = compilation_error( + 'Py++ cannot expose function that takes as argument/returns instance of non-public class. ' 'Generated code will not compile.' ) -W1006 = compilation_error( +W1006 = compilation_error( 'Py++ need your help to expose function that takes as argument/returns C++ arrays. ' 'Take a look on "Function Transformation" functionality and define the transformation.' ) -W1007 = warning( - 'The function has more than %d arguments ( %d ). ' - 'You should adjust BOOST_PYTHON_MAX_ARITY macro. ' +W1007 = warning( + 'The function has more than %d arguments ( %d ). ' + 'You should adjust BOOST_PYTHON_MAX_ARITY macro. ' 'For more information see: http://www.boost.org/libs/python/doc/v2/configuration.html' ) -W1008 = warning( - 'The function returns non-const reference to "Python immutable" type. ' +W1008 = warning( + 'The function returns non-const reference to "Python immutable" type. ' 'The value cannot be modified from Python. ' ) -W1009 = execution_error( - 'The function takes as argument (name=%s, pos=%d) non-const reference ' - 'to Python immutable type - function could not be called from Python. ' +W1009 = execution_error( + 'The function takes as argument (name=%s, pos=%d) non-const reference ' + 'to Python immutable type - function could not be called from Python. ' 'Take a look on "Function Transformation" functionality and define the transformation.' ) W1010 = execution_error( - 'The function introduces registration order problem. ' - 'For more information about the problem read next document: ' - 'http://language-binding.net/pyplusplus/documentation/functions/registration_order.html ' + 'The function introduces registration order problem. ' + 'For more information about the problem read next document: ' + 'http://language-binding.net/pyplusplus/documentation/functions/registration_order.html ' 'Problematic functions list: %s' ) W1011 = warning( "Py++ doesn't export private not virtual functions." ) @@ -91,14 +91,14 @@ W1013 = compilation_error( "Py++ doesn't export private constructor." ) -W1014 = compilation_error( +W1014 = compilation_error( '"%s" is not supported. ' 'See Boost.Python documentation: http://www.boost.org/libs/python/doc/v2/operators.html#introduction.' ) W1015 = compilation_error( "Py++ doesn't export private operators." ) -W1016 = warning( - 'Py++ does not exports non-const casting operators with user defined type as return value. ' +W1016 = warning( + 'Py++ does not exports non-const casting operators with user defined type as return value. ' 'This could be change in future.' ) W1017 = compilation_error( "Py++ doesn't export non-public casting operators." ) @@ -113,7 +113,7 @@ W1022 = warning( "Py++ will generate class wrapper - hand written code should be added to the wrapper class copy constructor body" ) -W1023 = warning( +W1023 = warning( "Py++ will generate class wrapper - there are few functions that should be redefined in class wrapper. " "The functions are: %s." ) @@ -133,10 +133,10 @@ W1031 = warning( 'Py++ will generate class wrapper - user asked to expose non - public member function "%s"' ) -W1032 = execution_error( - "Boost.Python library does not support enums with duplicate values. " - "You can read more about this here: " - "http://boost.org/libs/python/todo.html#support-for-enums-with-duplicate-values . " +W1032 = execution_error( + "Boost.Python library does not support enums with duplicate values. " + "You can read more about this here: " + "http://boost.org/libs/python/todo.html#support-for-enums-with-duplicate-values . " "The quick work around is to add new class variable to the exported enum, from Python. " ) W1033 = compilation_error( "Py++ can not expose unnamed variables" ) @@ -147,21 +147,21 @@ W1036 = compilation_error( "Py++ can not expose pointer to Python immutable member variables. This could be changed in future." ) -W1037 = compilation_error( - "Boost.Python library can not expose variables, which are pointer to function." +W1037 = compilation_error( + "Boost.Python library can not expose variables, which are pointer to function." " See http://www.boost.org/libs/python/doc/v2/faq.html#funcptr for more information." ) W1038 = compilation_error( "Py++ can not expose variables of with unnamed type." ) W1039 = compilation_error( "Py++ doesn't expose private or protected member variables." ) -W1040 = execution_error( +W1040 = execution_error( 'The declaration is unexposed, but there are other declarations, which refer to it. ' - 'This could cause "no to_python converter found" run time error. ' + 'This could cause "no to_python converter found" run time error. ' 'Declarations: %s' ) -W1041 = warning( - 'Property "%s" could not be created. There is another exposed declaration with the same name( alias )." ' +W1041 = warning( + 'Property "%s" could not be created. There is another exposed declaration with the same name( alias )." ' 'The property will make it inaccessible.' ) W1042 = warning( @@ -175,15 +175,15 @@ W1044 = warning( 'Py++ created an ugly alias ("%s") for function wrapper.' ) -W1045 = compilation_error( +W1045 = compilation_error( 'Py++ does not expose static arrays with unknown size. ' 'You can fix this by setting array size to the actual one.' 'For more information see "array_t" class documentation.' ) -W1046 = warning( - 'The virtual function was declared with empty throw. ' - 'Adding the ability to override the function from Python breaks the exception specification. ' - 'The function wrapper can throw any exception. ' +W1046 = warning( + 'The virtual function was declared with empty throw. ' + 'Adding the ability to override the function from Python breaks the exception specification. ' + 'The function wrapper can throw any exception. ' 'In case of exception in run-time, the behaviour of the program is undefined! ' ) W1047 = warning( @@ -192,32 +192,34 @@ 'of the classes will not be exposed to Python.' 'Other classes : %s' ) -W1048 = warning( +W1048 = warning( 'There are two or more aliases within "pyplusplus::aliases" namespace for ' 'the class. Py++ selected "%s" as class alias. Other aliases: %s' ) -W1049 = warning( - 'This method could not be overriden in Python - method returns reference ' +W1049 = warning( + 'This method could not be overriden in Python - method returns reference ' 'to local variable!' ) W1050 = compilation_error( - 'The function returns "%s" type. You have to specify a call policies.' - 'Be sure to take a look on Py++ defined call policies: ' + 'The function returns "%s" type. You have to specify a call policies.' + 'Be sure to take a look on Py++ defined call policies: ' 'http://language-binding.net/pyplusplus/documentation/functions/call_policies.html#py-defined-call-policies' ) -W1051 = warning( +W1051 = warning( 'The function takes as argument (name=%s, pos=%d) "%s" type. ' 'You have to specify a call policies or to use "Function Transformation" ' 'functionality.' ) -W1052 = warning( +W1052 = warning( 'Py++ will not expose free operator "%s" - all classes, this operator works on, are excluded.' ) -W1053 = warning( +W1053 = warning( 'Py++ will not expose function "%s" - the function has variable-argument list, spicified by ellipsis (...).' ) W1054 = compilation_error( 'Py++ can not expose unions.' ) +W1055 = warning( "Py++ will generate class wrapper - hand written code should be added to the wrapper class destructor body" ) + warnings = globals() all_warning_msgs = [] @@ -230,13 +232,13 @@ try: int( identifier[1:] ) except: - continue - msg = '%s %s: %s' % ( explanation.__class__.prefix, identifier, str(explanation) ) + continue + msg = '%s %s: %s' % ( explanation.__class__.prefix, identifier, str(explanation) ) msg_inst = explanation.__class__( msg, identifier ) globals()[ identifier ] = msg_inst all_warning_msgs.append( msg_inst ) - + del warnings del identifier del explanation Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -624,6 +624,10 @@ for property_def in cls_decl.properties: cls_cc.adopt_creator( code_creators.property_t(property_def) ) + if wrapper and cls_decl.destructor_code: + destructor = code_creators.destructor_wrapper_t( class_=cls_decl ) + wrapper.adopt_creator( destructor ) + self.curr_decl = cls_decl self.curr_code_creator = cls_parent_cc Modified: pyplusplus_dev/unittests/transfer_ownership_tester.py =================================================================== --- pyplusplus_dev/unittests/transfer_ownership_tester.py 2008-07-14 18:14:53 UTC (rev 1371) +++ pyplusplus_dev/unittests/transfer_ownership_tester.py 2008-07-14 18:58:40 UTC (rev 1372) @@ -12,14 +12,10 @@ from pyplusplus.module_builder import call_policies decref_code = \ -""" - virtual ~%(cls)s(){ - if (this->m_pyobj) { - //Py_DECREF(this->m_pyobj); - this->m_pyobj = 0; - } - } -""" +"""if (this->m_pyobj) { + //Py_DECREF(this->m_pyobj); + this->m_pyobj = 0; +}""" incref_code = \ """ @@ -36,9 +32,9 @@ class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'transfer_ownership' - + def __init__( self, *args ): - fundamental_tester_base.fundamental_tester_base_t.__init__( + fundamental_tester_base.fundamental_tester_base_t.__init__( self , tester_t.EXTENSION_NAME , *args ) @@ -46,12 +42,12 @@ def customize( self, mb ): event_clss = mb.classes( lambda cls: cls.name in ( 'event_t', 'do_nothing_t' ) ) for cls in event_clss: - cls.add_wrapper_code( decref_code % { 'cls' : cls.wrapper_alias } ) + cls.add_destructor_code( decref_code ) 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( impl_conv_code % { 'from' : cls.wrapper_alias , 'to' : cls.decl_string } @@ -62,7 +58,7 @@ 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 } @@ -73,16 +69,16 @@ simulator = mb.class_( 'simulator_t' ) simulator.mem_fun( 'get_event' ).call_policies \ = call_policies.return_internal_reference() - + 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 ): self.container.append( 1 ) - + print '1' notify_data = [] simulator = module.simulator_t() @@ -97,9 +93,9 @@ simulator.run() print '6' self.failUnless( notify_data[0] == 1 ) - + def create_suite(): - suite = unittest.TestSuite() + suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) return suite This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |