pygccxml-commit Mailing List for C++ Python language bindings (Page 19)
Brought to you by:
mbaas,
roman_yakovenko
You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
(190) |
Apr
(166) |
May
(170) |
Jun
(75) |
Jul
(105) |
Aug
(131) |
Sep
(99) |
Oct
(84) |
Nov
(67) |
Dec
(54) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(66) |
Feb
(49) |
Mar
(25) |
Apr
(62) |
May
(21) |
Jun
(34) |
Jul
(9) |
Aug
(21) |
Sep
(5) |
Oct
|
Nov
(63) |
Dec
(34) |
2008 |
Jan
(10) |
Feb
(42) |
Mar
(26) |
Apr
(25) |
May
(6) |
Jun
(40) |
Jul
(18) |
Aug
(29) |
Sep
(6) |
Oct
(32) |
Nov
(14) |
Dec
(56) |
2009 |
Jan
(127) |
Feb
(52) |
Mar
(2) |
Apr
(10) |
May
(29) |
Jun
(3) |
Jul
|
Aug
(16) |
Sep
(4) |
Oct
(11) |
Nov
(8) |
Dec
(14) |
2010 |
Jan
(31) |
Feb
(1) |
Mar
(7) |
Apr
(9) |
May
(1) |
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
(8) |
Mar
(4) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <rom...@us...> - 2008-08-26 08:55:48
|
Revision: 1407 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1407&view=rev Author: roman_yakovenko Date: 2008-08-26 08:55:58 +0000 (Tue, 26 Aug 2008) Log Message: ----------- simplify container_traits functionality Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/container_traits.py pygccxml_dev/unittests/find_container_traits_tester.py Modified: pygccxml_dev/pygccxml/declarations/container_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/container_traits.py 2008-08-26 05:14:49 UTC (rev 1406) +++ pygccxml_dev/pygccxml/declarations/container_traits.py 2008-08-26 08:55:58 UTC (rev 1407) @@ -254,17 +254,31 @@ declaration( and not definition ) it parsers the class name in order to extract all the information. """ - def __init__( self, container_name, element_type_index, element_type_typedef ): + def __init__( self + , container_name + , element_type_index + , element_type_typedef + , defaults_remover + , key_type_index=None + , key_type_typedef=None ): """ container_name - std container name element_type_index - position of value\\mapped type within template arguments list element_type_typedef - class typedef to the value\\mapped type + key_type_index - position of key type within template arguments list + key_type_typedef - class typedef to the key type """ - self.name = container_name + self._name = container_name + self.remove_defaults_impl = defaults_remover self.element_type_index = element_type_index self.element_type_typedef = element_type_typedef + self.key_type_index = key_type_index + self.key_type_typedef = key_type_typedef + def name(self): + return self._name + def get_container_or_none( self, type ): """returns reference to the class declaration or None""" type = type_traits.remove_alias( type ) @@ -280,7 +294,7 @@ else: return - if not cls.name.startswith( self.name + '<' ): + if not cls.name.startswith( self.name() + '<' ): return for ns in std_namespaces: @@ -295,7 +309,7 @@ """returns reference to the class declaration""" cls = self.get_container_or_none( type ) if not cls: - raise TypeError( 'Type "%s" is not instantiation of std::%s' % ( type.decl_string, self.name ) ) + raise TypeError( 'Type "%s" is not instantiation of std::%s' % ( type.decl_string, self.name() ) ) return cls def element_type( self, type ): @@ -309,86 +323,45 @@ ref = type_traits.impl_details.find_value_type( cls.top_parent, value_type_str ) if None is ref: raise RuntimeError( "Unable to find out %s '%s' value type." - % ( self.name, cls.decl_string ) ) + % ( self.name(), cls.decl_string ) ) return ref + def remove_defaults( self, type_or_string ): + name = type_or_string + if not isinstance( type_or_string, types.StringTypes ): + name = self.class_declaration( type_or_string ).name + if not self.remove_defaults_impl: + return name + no_defaults = self.remove_defaults_impl( name ) + if not no_defaults: + return name + else: + return no_defaults +list_traits = container_traits_impl_t( 'list', 0, 'value_type', defaults_eraser.erase_allocator ) -def create_traits_class( container_name - , element_type_index - , element_type_typedef - , remove_defaults_=None ): - """ creates concrete container traits class """ +deque_traits = container_traits_impl_t( 'deque', 0, 'value_type', defaults_eraser.erase_allocator ) - impl_tmp = container_traits_impl_t( container_name, element_type_index, element_type_typedef ) +queue_traits = container_traits_impl_t( 'queue', 0, 'value_type', defaults_eraser.erase_container ) - class xxx_traits: - """extract information from the container""" +priority_queue_traits = container_traits_impl_t( 'priority_queue', 0, 'value_type', defaults_eraser.erase_container_compare ) - impl = None +vector_traits = container_traits_impl_t( 'vector', 0, 'value_type', defaults_eraser.erase_allocator ) - @staticmethod - def name(): - return xxx_traits.impl.name +stack_traits = container_traits_impl_t( 'stack', 0, 'value_type', defaults_eraser.erase_container ) - @staticmethod - def is_my_case( type ): - """returns True if type is the container class, otherwise False""" - return xxx_traits.impl.is_my_case( type ) +map_traits = container_traits_impl_t( 'map', 1, 'mapped_type', defaults_eraser.erase_map_compare_allocator ) +multimap_traits = container_traits_impl_t( 'multimap', 1, 'mapped_type', defaults_eraser.erase_map_compare_allocator ) - @staticmethod - def class_declaration( type ): - """returns reference to the container class""" - return xxx_traits.impl.class_declaration( type ) +hash_map_traits = container_traits_impl_t( 'hash_map', 1, 'mapped_type', defaults_eraser.erase_hashmap_compare_allocator ) +hash_multimap_traits = container_traits_impl_t( 'hash_multimap', 1, 'mapped_type', defaults_eraser.erase_hashmap_compare_allocator ) - @staticmethod - def element_type( type ): - """returns reference to container name value\\mapped type class""" - return xxx_traits.impl.element_type( type ) +set_traits = container_traits_impl_t( 'set', 0, 'value_type', defaults_eraser.erase_compare_allocator) +multiset_traits = container_traits_impl_t( 'multiset', 0, 'value_type', defaults_eraser.erase_compare_allocator ) - @staticmethod - def remove_defaults( type_or_string ): - name = None - if not isinstance( type_or_string, types.StringTypes ): - name = xxx_traits.class_declaration( type_or_string ).name - else: - name = type_or_string - if not remove_defaults_: - return name - no_defaults = remove_defaults_( name ) - if not no_defaults: - return name - else: - return no_defaults - - xxx_traits.impl = impl_tmp - - return xxx_traits +hash_set_traits = container_traits_impl_t( 'hash_set', 0, 'value_type', defaults_eraser.erase_hash_allocator ) +hash_multiset_traits = container_traits_impl_t( 'hash_multiset', 0, 'value_type', defaults_eraser.erase_hash_allocator ) -list_traits = create_traits_class( 'list', 0, 'value_type', defaults_eraser.erase_allocator ) - -deque_traits = create_traits_class( 'deque', 0, 'value_type', defaults_eraser.erase_allocator ) - -queue_traits = create_traits_class( 'queue', 0, 'value_type', defaults_eraser.erase_container ) - -priority_queue_traits = create_traits_class( 'priority_queue', 0, 'value_type', defaults_eraser.erase_container_compare ) - -vector_traits = create_traits_class( 'vector', 0, 'value_type', defaults_eraser.erase_allocator ) - -stack_traits = create_traits_class( 'stack', 0, 'value_type', defaults_eraser.erase_container ) - -map_traits = create_traits_class( 'map', 1, 'mapped_type', defaults_eraser.erase_map_compare_allocator ) -multimap_traits = create_traits_class( 'multimap', 1, 'mapped_type', defaults_eraser.erase_map_compare_allocator ) - -hash_map_traits = create_traits_class( 'hash_map', 1, 'mapped_type', defaults_eraser.erase_hashmap_compare_allocator ) -hash_multimap_traits = create_traits_class( 'hash_multimap', 1, 'mapped_type', defaults_eraser.erase_hashmap_compare_allocator ) - -set_traits = create_traits_class( 'set', 0, 'value_type', defaults_eraser.erase_compare_allocator) -multiset_traits = create_traits_class( 'multiset', 0, 'value_type', defaults_eraser.erase_compare_allocator ) - -hash_set_traits = create_traits_class( 'hash_set', 0, 'value_type', defaults_eraser.erase_hash_allocator ) -hash_multiset_traits = create_traits_class( 'hash_multiset', 0, 'value_type', defaults_eraser.erase_hash_allocator ) - container_traits = ( list_traits , deque_traits Modified: pygccxml_dev/unittests/find_container_traits_tester.py =================================================================== --- pygccxml_dev/unittests/find_container_traits_tester.py 2008-08-26 05:14:49 UTC (rev 1406) +++ pygccxml_dev/unittests/find_container_traits_tester.py 2008-08-26 08:55:58 UTC (rev 1407) @@ -23,14 +23,14 @@ tester_t.global_ns = declarations.get_global_namespace( decls ) tester_t.global_ns.init_optimizer() - def __cmp_traits( self, typedef, expected, partial_name ): + def __cmp_traits( self, typedef, expected, partial_name): if isinstance( typedef, str ): typedef = self.global_ns.typedef( typedef ) traits = declarations.find_container_traits( typedef ) self.failUnless( traits, 'container traits for "%s" not found' % str( typedef ) ) self.failUnless( traits is expected - , 'container "%s", expected %s, got %s' - % ( str(typedef), expected.__name__, traits.__name__ ) ) + , 'container "%s", expected %s_traits, got %s_traits' + % ( str(typedef), expected.name(), traits.name() ) ) cls = declarations.remove_declarated( typedef ) self.failUnless( cls.container_traits is expected ) self.failUnless( cls.partial_name == partial_name ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-26 05:14:40
|
Revision: 1406 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1406&view=rev Author: roman_yakovenko Date: 2008-08-26 05:14:49 +0000 (Tue, 26 Aug 2008) Log Message: ----------- construct gccxml configuration even if gccxml was not found Modified Paths: -------------- pygccxml_dev/unittests/autoconfig.py Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2008-08-25 18:12:09 UTC (rev 1405) +++ pygccxml_dev/unittests/autoconfig.py 2008-08-26 05:14:49 UTC (rev 1406) @@ -41,13 +41,16 @@ pygccxml.declarations.class_t.USE_DEMANGLED_AS_NAME = True class cxx_parsers_cfg: - gccxml = None + + keywd = { 'working_directory' : data_directory + , 'define_symbols' : [ gccxml_version ] + , 'compiler' : compiler } + if os.path.exists( os.path.join( gccxml_path, 'gccxml' ) ) \ or os.path.exists( os.path.join( gccxml_path, 'gccxml.exe' ) ): - gccxml = pygccxml.parser.gccxml_configuration_t( gccxml_path=gccxml_path - , working_directory=data_directory - , define_symbols=[ gccxml_version ] - , compiler=compiler ) + keywd[ 'gccxml_path'] = gccxml_path + gccxml = pygccxml.parser.gccxml_configuration_t( **keywd ) + pdb_loader = None if sys.platform == 'win32': from pygccxml.msvc import pdb This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-25 18:12:06
|
Revision: 1405 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1405&view=rev Author: roman_yakovenko Date: 2008-08-25 18:12:09 +0000 (Mon, 25 Aug 2008) Log Message: ----------- add new tester to check infinite loop Modified Paths: -------------- pygccxml_dev/unittests/data/indexing_suites2.hpp pygccxml_dev/unittests/find_container_traits_tester.py Modified: pygccxml_dev/unittests/data/indexing_suites2.hpp =================================================================== --- pygccxml_dev/unittests/data/indexing_suites2.hpp 2008-08-21 18:02:50 UTC (rev 1404) +++ pygccxml_dev/unittests/data/indexing_suites2.hpp 2008-08-25 18:12:09 UTC (rev 1405) @@ -85,4 +85,8 @@ typedef std::vector<indexing_suites2::item_t*> items_ptr_t; }} +namespace infinite_loop{ + std::map< std::string, int > test_infinite_loop(); +} + #endif//__indexing_suites2_to_be_exported_hpp__ Modified: pygccxml_dev/unittests/find_container_traits_tester.py =================================================================== --- pygccxml_dev/unittests/find_container_traits_tester.py 2008-08-21 18:02:50 UTC (rev 1404) +++ pygccxml_dev/unittests/find_container_traits_tester.py 2008-08-25 18:12:09 UTC (rev 1405) @@ -65,7 +65,14 @@ x = 'map<std::string, bool (*)(std::string&, Ogre::MaterialScriptContext&), std::less<std::string>, std::allocator<std::pair<std::string const, bool (*)(std::string&, Ogre::MaterialScriptContext&)> > >' ct = declarations.find_container_traits( x ) y = ct.remove_defaults( x ) - + + def test_infinite_loop(self): + rt = self.global_ns.free_fun( 'test_infinite_loop' ).return_type + map_traits = declarations.find_container_traits( rt ) + self.failUnless( map_traits is declarations.map_traits ) + elem = map_traits.element_type( rt ) + self.failUnless( elem.decl_string == 'int' ) + def create_suite(): suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-21 18:02:40
|
Revision: 1404 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1404&view=rev Author: roman_yakovenko Date: 2008-08-21 18:02:50 +0000 (Thu, 21 Aug 2008) Log Message: ----------- add new test cases Modified Paths: -------------- pygccxml_dev/unittests/data/vector_traits.hpp pygccxml_dev/unittests/vector_traits_tester.py Modified: pygccxml_dev/unittests/data/vector_traits.hpp =================================================================== --- pygccxml_dev/unittests/data/vector_traits.hpp 2008-08-21 12:38:47 UTC (rev 1403) +++ pygccxml_dev/unittests/data/vector_traits.hpp 2008-08-21 18:02:50 UTC (rev 1404) @@ -1,9 +1,9 @@ -// 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) +// 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) -#include <string> +#include <string> #include <vector> @@ -65,4 +65,6 @@ }; } -} \ No newline at end of file +} + +void do_nothing( std::vector< std::wstring >& ); Modified: pygccxml_dev/unittests/vector_traits_tester.py =================================================================== --- pygccxml_dev/unittests/vector_traits_tester.py 2008-08-21 12:38:47 UTC (rev 1403) +++ pygccxml_dev/unittests/vector_traits_tester.py 2008-08-21 18:02:50 UTC (rev 1404) @@ -59,6 +59,11 @@ cnt = 'std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >@::std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >' traits = declarations.find_container_traits( cnt ) self.failUnless( declarations.vector_traits is traits) + + def test_element_type( self ): + do_nothing = self.global_ns.free_fun( 'do_nothing' ) + v = declarations.remove_reference( declarations.remove_declarated( do_nothing.arguments[0].type )) + declarations.vector_traits.element_type( v ) def create_suite(): suite = unittest.TestSuite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-21 12:38:38
|
Revision: 1403 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1403&view=rev Author: roman_yakovenko Date: 2008-08-21 12:38:47 +0000 (Thu, 21 Aug 2008) Log Message: ----------- improve "already_exposed" functionality Modified Paths: -------------- pyplusplus_dev/pyplusplus/utils/__init__.py Modified: pyplusplus_dev/pyplusplus/utils/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/utils/__init__.py 2008-08-21 09:19:58 UTC (rev 1402) +++ pyplusplus_dev/pyplusplus/utils/__init__.py 2008-08-21 12:38:47 UTC (rev 1403) @@ -73,7 +73,7 @@ def find_out_normalized_name( self, decl ): if decl.name: - return decl.name + return decl.partial_name elif decl.location:#unnamed enums, classes, unions return str( decl.location.as_tuple() ) elif isinstance( decl, declarations.namespace_t ): @@ -93,11 +93,13 @@ self.exposed_sign = self.UNEXPOSED_DECL_SIGN else: self.exposed_sign = self.EXPOSED_DECL_SIGN + self.update_key( decl.__class__ ) self.signature = decl.create_decl_string( with_defaults=False ) if isinstance( decl, declarations.calldef_t ): self.signature = self.signature + decl.function_type().decl_string + self.normalized_name = self.find_out_normalized_name( decl ) def __str__( self ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-21 09:19:50
|
Revision: 1402 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1402&view=rev Author: roman_yakovenko Date: 2008-08-21 09:19:58 +0000 (Thu, 21 Aug 2008) Log Message: ----------- improve "already_exposed" functionality Modified Paths: -------------- pygccxml_dev/unittests/vector_traits_tester.py pyplusplus_dev/pyplusplus/code_creators/declaration_based.py pyplusplus_dev/pyplusplus/code_creators/module.py pyplusplus_dev/pyplusplus/file_writers/single_file.py pyplusplus_dev/pyplusplus/file_writers/writer.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/pyplusplus/utils/__init__.py pyplusplus_dev/unittests/already_exposed_tester.py pyplusplus_dev/unittests/balanced_files_tester.py pyplusplus_dev/unittests/data/already_exposed_to_be_exported.hpp pyplusplus_dev/unittests/exposed_decls_db_tester.py pyplusplus_dev/unittests/fundamental_tester_base.py pyplusplus_dev/unittests/split_module_tester.py pyplusplus_dev/unittests/unions_tester.py Added Paths: ----------- pyplusplus_dev/unittests/data/already_exposed_2to_be_exported.hpp Modified: pygccxml_dev/unittests/vector_traits_tester.py =================================================================== --- pygccxml_dev/unittests/vector_traits_tester.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pygccxml_dev/unittests/vector_traits_tester.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -55,6 +55,11 @@ continue self.failUnless( not traits.is_my_case( struct.typedef( 'container' ) ) ) + def test_declaration( self ): + cnt = 'std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >@::std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >' + traits = declarations.find_container_traits( cnt ) + self.failUnless( declarations.vector_traits is traits) + def create_suite(): suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) @@ -64,4 +69,4 @@ unittest.TextTestRunner(verbosity=2).run( create_suite() ) if __name__ == "__main__": - run_suite() \ No newline at end of file + run_suite() Modified: pyplusplus_dev/pyplusplus/code_creators/declaration_based.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/declaration_based.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/pyplusplus/code_creators/declaration_based.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -23,20 +23,19 @@ if name == None: name = self.declaration.name return algorithm.create_valid_name( name ) - - def _get_declaration(self): + + @property + def declaration(self): + """The declaration this code creator is based on. + @type: L{decl_wrapper_t<decl_wrappers.decl_wrapper_t>} + """ return self._decl - declaration = property( _get_declaration, - doc="""The declaration this code creator is based on. - @type: L{decl_wrapper_t<decl_wrappers.decl_wrapper_t>} - """) def _get_alias_impl( self ): return self.declaration.alias - def _get_alias(self): - return self._get_alias_impl() - + def _get_alias(self): + return self._get_alias_impl() def _set_alias(self, alias): self.declaration.alias = alias alias = property( _get_alias, _set_alias ) Modified: pyplusplus_dev/pyplusplus/code_creators/module.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/module.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/pyplusplus/code_creators/module.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -11,7 +11,9 @@ import compound import algorithm import module_body +import declaration_based import include_directories +from pygccxml import utils class module_t(compound.compound_t): """This class represents the source code for the entire extension module. @@ -179,3 +181,19 @@ def add_declaration_code( self, code, position ): self.adopt_declaration_creator( custom.custom_text_t( code ) ) + + @utils.cached + def specially_exposed_decls(self): + """list of exposed declarations, which were not ``included``, but still + were exposed. For example, std containers. + """ + decls = set() + #select all declaration based code creators + ccs = filter( lambda cc: isinstance( cc, declaration_based.declaration_based_t ) + , algorithm.make_flatten_list( self ) ) + #leave only "ignored" + ccs = filter( lambda cc: cc.declaration.ignore == True, ccs ) + + decls = map( lambda cc: cc.declaration, ccs ) + + return set( decls ) Modified: pyplusplus_dev/pyplusplus/file_writers/single_file.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/single_file.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/pyplusplus/file_writers/single_file.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -23,9 +23,11 @@ target_dir = os.path.dirname( self.file_name ) if not target_dir: target_dir = os.getcwd() + if not os.path.exists( target_dir ): + os.makedirs( target_dir ) headers = self.get_user_headers( [self.extmodule] ) map( lambda header: self.extmodule.add_include( header ) , headers ) self.write_code_repository( target_dir ) self.write_file( self.file_name, self.extmodule.create(), encoding=self.encoding ) - self.save_exposed_decls_db( target_dir ) \ No newline at end of file + self.save_exposed_decls_db( target_dir ) Modified: pyplusplus_dev/pyplusplus/file_writers/writer.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/writer.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/pyplusplus/file_writers/writer.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -32,7 +32,8 @@ if None is files_sum_repository: self.__files_sum_repository = md5sum_repository.dummy_repository_t() self.__exposed_decls_db = utils.exposed_decls_db_t() - self.__exposed_decls_db.register_decls( extmodule.global_ns ) + self.__exposed_decls_db.register_decls( extmodule.global_ns + , extmodule.specially_exposed_decls ) @property def encoding( self ): Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -253,6 +253,21 @@ self.__extmodule.adopt_creators( uc_creators, insert_pos ) cls_creator.associated_decl_creators.extend( uc_creators ) + def __get_exposed_containers(self): + """list of exposed declarations, which were not ``included``, but still + were exposed. For example, std containers + + std containers exposed by Py++, even if the user didn't ``include`` them. + """ + cmp_by_name = lambda cls1, cls2: cmp( cls1.decl_string, cls2.decl_string ) + used_containers = list( self.__types_db.used_containers ) + used_containers = filter( lambda cls: cls.indexing_suite.include_files + , used_containers ) + used_containers.sort( cmp_by_name ) + used_containers = filter( lambda cnt: cnt.already_exposed == False + , used_containers ) + return used_containers + def _treat_indexing_suite( self ): def create_explanation(cls): msg = '//WARNING: the next line of code will not compile, because "%s" does not have operator== !' @@ -271,17 +286,9 @@ creators = [] created_value_traits = set() - cmp_by_name = lambda cls1, cls2: cmp( cls1.decl_string, cls2.decl_string ) - used_containers = list( self.__types_db.used_containers ) - used_containers = filter( lambda cls: cls.indexing_suite.include_files - , used_containers ) - used_containers.sort( cmp_by_name ) - for cls in used_containers: + for cls in self.__get_exposed_containers(): self.__print_readme( cls ) - if cls.already_exposed: - continue - cls_creator = create_cls_cc( cls ) self.__dependencies_manager.add_exported( cls ) creators.append( cls_creator ) Modified: pyplusplus_dev/pyplusplus/utils/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/utils/__init__.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/pyplusplus/utils/__init__.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -85,13 +85,17 @@ self.exposed_sign, self.key, self.normalized_name, self.signature \ = row.split( self.FIELD_DELIMITER ) + def update_key( self, cls ): + self.key = cls.__name__ + def __init_from_decl( self, decl ): if decl.ignore: self.exposed_sign = self.UNEXPOSED_DECL_SIGN else: self.exposed_sign = self.EXPOSED_DECL_SIGN - self.key = decl.__class__.__name__ - self.signature = decl.decl_string + self.update_key( decl.__class__ ) + + self.signature = decl.create_decl_string( with_defaults=False ) if isinstance( decl, declarations.calldef_t ): self.signature = self.signature + decl.function_type().decl_string self.normalized_name = self.find_out_normalized_name( decl ) @@ -137,9 +141,8 @@ self.__registry[ row.key ][row.normalized_name] = [row] else: self.__registry[ row.key ][row.normalized_name].append(row) - - def __find_in_registry( self, decl ): - row = self.row_t( decl ) + + def __find_row_in_registry( self, row ): try: decls = filter( lambda rrow: rrow.does_refer_same_decl( row ) , self.__registry[ row.key ][ row.normalized_name ] ) @@ -149,7 +152,24 @@ return None except KeyError: return None - + + def __find_in_registry( self, decl ): + row = self.row_t( decl ) + found = self.__find_row_in_registry( row ) + if found: + return found + if isinstance( decl, declarations.class_t ): + row.update_key( declarations.class_declaration_t ) + found = self.__find_row_in_registry( row ) + if found: + return found + if isinstance( decl, declarations.class_declaration_t ): + row.update_key( declarations.class_t ) + found = self.__find_row_in_registry( row ) + if found: + return found + return None + def is_exposed( self, decl ): row = self.__find_in_registry( decl) return row and self.row_t.EXPOSED_DECL_SIGN == row.exposed_sign @@ -166,6 +186,15 @@ decl.ignore = True decl.already_exposed = False - def register_decls( self, global_ns ): + def register_decls( self, global_ns, special_decls ): + """register decls in the database + + global_ns - reference to the global namespace object + special_decls - set of declarations, which were exposed, even so they + were not ``included``. For example std containers. + """ for decl in global_ns.decls(): - self.__update_registry( self.row_t( decl ) ) + row = self.row_t( decl ) + if decl in special_decls: + row.exposed_sign = row.EXPOSED_DECL_SIGN + self.__update_registry( row ) Modified: pyplusplus_dev/unittests/already_exposed_tester.py =================================================================== --- pyplusplus_dev/unittests/already_exposed_tester.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/unittests/already_exposed_tester.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -12,24 +12,36 @@ import fundamental_tester_base class tester_t( unittest.TestCase ): - def test(self): - exposed_db = utils.exposed_decls_db_t() - + def test(self): fpath = os.path.join( autoconfig.data_directory, 'already_exposed_to_be_exported.hpp' ) mb = module_builder.module_builder_t( [module_builder.create_source_fc( fpath )] , gccxml_path=autoconfig.gccxml.executable ) mb.global_ns.exclude() mb.namespace( 'already_exposed' ).include() - exposed_db.register_decls( mb.global_ns ) - exposed_db.save( autoconfig.build_dir ) - mb.register_module_dependency( autoconfig.build_dir ) - mb.class_( 'ae_derived' ).include() + mb.build_code_creator( 'already_exposed' ) + + already_exposed_dir = os.path.join( autoconfig.build_directory, 'already_exposed' ) + mb.write_module( os.path.join( already_exposed_dir, 'already_exposed.cpp' ) ) + + #----------------------------------------------------------------------- + + fpath = os.path.join( autoconfig.data_directory, 'already_exposed_2to_be_exported.hpp' ) + mb = module_builder.module_builder_t( [module_builder.create_source_fc( fpath )] + , gccxml_path=autoconfig.gccxml.executable ) + + mb.global_ns.exclude() + mb.namespace( 'to_be_exposed' ).include() + mb.build_code_creator( 'to_be_exposed' ) + + mb.register_module_dependency( already_exposed_dir ) - mb.build_code_creator( 'xxx' ) + mb.build_code_creator( 'to_be_exposed' ) + to_be_exposed_dir = os.path.join( autoconfig.build_directory, 'to_be_exposed' ) + mb.write_module( os.path.join( to_be_exposed_dir, 'to_be_exposed.cpp' ) ) body = mb.code_creator.body - self.failUnless( 1 == len( body.creators ) ) + self.failUnless( 2 == len( body.creators ) ) ae_derived_code = body.creators[0].create() self.failUnless( mb.class_( 'ae_base' ).decl_string in ae_derived_code ) Modified: pyplusplus_dev/unittests/balanced_files_tester.py =================================================================== --- pyplusplus_dev/unittests/balanced_files_tester.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/unittests/balanced_files_tester.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -32,7 +32,7 @@ exposed_db = utils.exposed_decls_db_t() - exposed_db.register_decls( mb.global_ns ) + exposed_db.register_decls( mb.global_ns, [] ) exposed_db.save( autoconfig.build_dir ) mb.register_module_dependency( autoconfig.build_dir ) Added: pyplusplus_dev/unittests/data/already_exposed_2to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/already_exposed_2to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/already_exposed_2to_be_exported.hpp 2008-08-21 09:19:58 UTC (rev 1402) @@ -0,0 +1,24 @@ +// 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 __already_exposed_2to_be_exported_hpp__ +#define __already_exposed_2to_be_exported_hpp__ + +#include "already_exposed_to_be_exported.hpp" +#include <vector> +#include <string> + +namespace to_be_exposed{ + +struct ae_derived : public already_exposed::ae_base +{}; + +inline std::vector< std::string > do_nothing(){ + return std::vector< std::string >(); +} + +} + +#endif//__already_exposed_2to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/data/already_exposed_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/already_exposed_to_be_exported.hpp 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/unittests/data/already_exposed_to_be_exported.hpp 2008-08-21 09:19:58 UTC (rev 1402) @@ -6,6 +6,9 @@ #ifndef __already_exposed_to_be_exported_hpp__ #define __already_exposed_to_be_exported_hpp__ +#include <vector> +#include <string> + namespace already_exposed{ struct ae_t{}; @@ -14,9 +17,8 @@ struct ae_base{}; +void do_smth( const std::vector< std::string >& ); + } - -struct ae_derived : public already_exposed::ae_base -{}; - + #endif//__already_exposed_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/exposed_decls_db_tester.py =================================================================== --- pyplusplus_dev/unittests/exposed_decls_db_tester.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/unittests/exposed_decls_db_tester.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -69,7 +69,7 @@ global_ns.exclude() ns.include() - db.register_decls( global_ns ) + db.register_decls( global_ns, [] ) for x in ns.decls(recursive=True): self.failUnless( db.is_exposed( x ) == True ) Modified: pyplusplus_dev/unittests/fundamental_tester_base.py =================================================================== --- pyplusplus_dev/unittests/fundamental_tester_base.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/unittests/fundamental_tester_base.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -54,14 +54,17 @@ irrelevant_decl_types = ( declarations.typedef_t , declarations.namespace_t , declarations.free_operator_t ) + specially_exposed_decls = mb.code_creator.specially_exposed_decls for d in mb.decls(): if not d.exportable: continue elif isinstance( d, declarations.free_operator_t ): continue elif d.ignore: + if d in specially_exposed_decls: + continue if exposed_db.is_exposed( d ): - i = 0 + i = 0 self.failUnless( not exposed_db.is_exposed( d ) , '''Declaration "%s" is NOT exposed, but for some reason it is marked as such.''' % str( d ) ) Modified: pyplusplus_dev/unittests/split_module_tester.py =================================================================== --- pyplusplus_dev/unittests/split_module_tester.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/unittests/split_module_tester.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -32,7 +32,7 @@ exposed_db = utils.exposed_decls_db_t() - exposed_db.register_decls( mb.global_ns ) + exposed_db.register_decls( mb.global_ns, [] ) exposed_db.save( autoconfig.build_dir ) mb.register_module_dependency( autoconfig.build_dir ) Modified: pyplusplus_dev/unittests/unions_tester.py =================================================================== --- pyplusplus_dev/unittests/unions_tester.py 2008-08-20 20:07:03 UTC (rev 1401) +++ pyplusplus_dev/unittests/unions_tester.py 2008-08-21 09:19:58 UTC (rev 1402) @@ -44,8 +44,9 @@ obj2.set_i( 1977 ) self.failUnless( obj2.i == 1977 ) - mdll = ctypes.cdll.LoadLibrary( module.__file__ ) - self.failUnless( 4 == mdll.mmm( 1, 3 ) ) + if 'win' not in sys.platform: + mdll = ctypes.cdll.LoadLibrary( module.__file__ ) + self.failUnless( 4 == mdll.mmm( 1, 3 ) ) def create_suite(): suite = unittest.TestSuite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-20 20:06:53
|
Revision: 1401 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1401&view=rev Author: roman_yakovenko Date: 2008-08-20 20:07:03 +0000 (Wed, 20 Aug 2008) Log Message: ----------- fix code generation for pure virtual function, which returns auto_ptr<...> and invoked from C++ Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_creators/calldef.py pyplusplus_dev/unittests/return_auto_ptr_tester.py Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-08-20 20:02:25 UTC (rev 1400) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-08-20 20:07:03 UTC (rev 1401) @@ -274,11 +274,11 @@ if keywd_args: result.append( self.indent( self.param_sep(), 3 ) ) result.append( keywd_args ) - + result.append( ' )' ) #make_constructor - + doc = self.create_doc() - if doc: + if doc: result.append( self.param_sep() ) result.append( doc ) @@ -341,6 +341,7 @@ } def create_body( self ): + auto_ptr_traits = declarations.auto_ptr_traits if not self.declaration.overridable: return self.unoverriden_function_body() template = [] @@ -348,18 +349,28 @@ if precall_code: template.append( os.linesep.join( precall_code ) ) template.append( '%(override)s func_%(alias)s = this->get_override( "%(alias)s" );' ) - template.append( '%(return_)sfunc_%(alias)s( %(args)s );') + if self.declaration.return_type \ + and auto_ptr_traits.is_smart_pointer( self.declaration.return_type ): + template.append( 'boost::python::object %(alias)s_result = func_%(alias)s( %(args)s );' ) + template.append( 'return boost::python::extract< %(return_type)s >( %(alias)s_result );' ) + else: + template.append( '%(return_)sfunc_%(alias)s( %(args)s );') template = os.linesep.join( template ) return_ = '' if not declarations.is_void( self.declaration.return_type ): return_ = 'return ' + return_type = '' + if self.declaration.return_type: + return_type = self.declaration.return_type.decl_string + return template % { 'override' : self.override_identifier() , 'alias' : self.declaration.alias , 'return_' : return_ , 'args' : self.function_call_args() + , 'return_type' : return_type } def _create_impl(self): Modified: pyplusplus_dev/unittests/return_auto_ptr_tester.py =================================================================== --- pyplusplus_dev/unittests/return_auto_ptr_tester.py 2008-08-20 20:02:25 UTC (rev 1400) +++ pyplusplus_dev/unittests/return_auto_ptr_tester.py 2008-08-20 20:07:03 UTC (rev 1401) @@ -20,9 +20,8 @@ , *args ) def customize( self, mb ): - pass - #~ r_input = mb.class_( 'r_input_t' ) - #~ r_input.held_type = 'std::auto_ptr< %s >' % r_input.decl_string + r_input = mb.class_( 'r_input_t' ) + r_input.held_type = 'std::auto_ptr< %s >' % r_input.decl_string def create_py_input( self, module, rows, cols ): class py_input_t( module.generic_input_t ): @@ -43,12 +42,8 @@ a = self.create_py_input( module, 3, 7 ) c = a.create_r_input() self.failUnless( c.rows() == 3 and c.cols() == 7 ) - try: - b = module.process_input(a) - self.failUnless( b.rows() == 3 and b.cols() == 7 ) - except TypeError, err: - print err - + b = module.process_input(a) + self.failUnless( b.rows() == 3 and b.cols() == 7 ) c = a.create_r_input_shared() self.failUnless( c.rows() == 3 and c.cols() == 7 ) b = module.process_input_shared(a) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-20 20:02:16
|
Revision: 1400 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1400&view=rev Author: roman_yakovenko Date: 2008-08-20 20:02:25 +0000 (Wed, 20 Aug 2008) Log Message: ----------- add auto_ptr_traits Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/__init__.py pygccxml_dev/pygccxml/declarations/type_traits.py Modified: pygccxml_dev/pygccxml/declarations/__init__.py =================================================================== --- pygccxml_dev/pygccxml/declarations/__init__.py 2008-08-20 11:32:49 UTC (rev 1399) +++ pygccxml_dev/pygccxml/declarations/__init__.py 2008-08-20 20:02:25 UTC (rev 1400) @@ -172,6 +172,7 @@ from type_traits import has_public_binary_operator from type_traits import has_any_non_copyconstructor +from type_traits import auto_ptr_traits from type_traits import smart_pointer_traits from container_traits import list_traits Modified: pygccxml_dev/pygccxml/declarations/type_traits.py =================================================================== --- pygccxml_dev/pygccxml/declarations/type_traits.py 2008-08-20 11:32:49 UTC (rev 1399) +++ pygccxml_dev/pygccxml/declarations/type_traits.py 2008-08-20 20:02:25 UTC (rev 1400) @@ -1008,6 +1008,41 @@ raise RuntimeError( "Unable to find out shared_ptr value type. shared_ptr class is: %s" % cls.decl_string ) return ref +class auto_ptr_traits: + """implements functionality, needed for convinient work with std::auto_ptr pointers""" + + @staticmethod + def is_smart_pointer( type ): + """returns True, if type represents instantiation of C{boost::shared_ptr}, False otherwise""" + type = remove_alias( type ) + type = remove_cv( type ) + type = remove_declarated( type ) + if not isinstance( type, ( class_declaration.class_declaration_t, class_declaration.class_t ) ): + return False + if not impl_details.is_defined_in_xxx( 'std', type ): + return False + return type.decl_string.startswith( '::std::auto_ptr<' ) + + @staticmethod + def value_type( type ): + """returns reference to boost::shared_ptr value type""" + if not auto_ptr_traits.is_smart_pointer( type ): + raise TypeError( 'Type "%s" is not instantiation of std::auto_ptr' % type.decl_string ) + type = remove_alias( type ) + cls = remove_cv( type ) + cls = remove_declarated( type ) + if isinstance( cls, class_declaration.class_t ): + return remove_declarated( cls.typedef( "element_type", recursive=False ).type ) + elif not isinstance( cls, ( class_declaration.class_declaration_t, class_declaration.class_t ) ): + raise RuntimeError( "Unable to find out auto_ptr value type. auto_ptr class is: %s" % cls.decl_string ) + else: + value_type_str = templates.args( cls.name )[0] + ref = impl_details.find_value_type( cls.top_parent, value_type_str ) + if None is ref: + raise RuntimeError( "Unable to find out auto_ptr value type. shared_ptr class is: %s" % cls.decl_string ) + return ref + + def is_std_string( type ): """returns True, if type represents C++ std::string, False otherwise""" decl_strings = [ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-20 11:32:40
|
Revision: 1399 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1399&view=rev Author: roman_yakovenko Date: 2008-08-20 11:32:49 +0000 (Wed, 20 Aug 2008) Log Message: ----------- improve dependencies_manager.py class algorithm Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/calldef.py pygccxml_dev/pygccxml/declarations/class_declaration.py pygccxml_dev/pygccxml/declarations/dependencies.py pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py pyplusplus_dev/unittests/data/mem_fun_with_exception_to_be_exported.hpp Modified: pygccxml_dev/pygccxml/declarations/calldef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/calldef.py 2008-08-20 06:20:45 UTC (rev 1398) +++ pygccxml_dev/pygccxml/declarations/calldef.py 2008-08-20 11:32:49 UTC (rev 1399) @@ -310,13 +310,13 @@ , doc="returns function demangled name. It can help you to deal with function template instantiations") def i_depend_on_them( self, recursive=True ): - report_dependency = lambda x: dependencies.dependency_info_t( self, x ) + report_dependency = lambda *args, **keywd: dependencies.dependency_info_t( self, *args, **keywd ) answer = [] + if self.return_type: + answer.append( report_dependency( self.return_type, hint="return type" ) ) map( lambda arg: answer.append( report_dependency( arg.type ) ) , self.arguments ) - if self.return_type: - answer.append( report_dependency( self.return_type ) ) - map( lambda exception: answer.append( report_dependency( exception ) ) + map( lambda exception: answer.append( report_dependency( exception, hint="exception" ) ) , self.exceptions ) return answer Modified: pygccxml_dev/pygccxml/declarations/class_declaration.py =================================================================== --- pygccxml_dev/pygccxml/declarations/class_declaration.py 2008-08-20 06:20:45 UTC (rev 1398) +++ pygccxml_dev/pygccxml/declarations/class_declaration.py 2008-08-20 11:32:49 UTC (rev 1399) @@ -457,9 +457,10 @@ def i_depend_on_them( self, recursive=True ): report_dependency = lambda *args: dependencies.dependency_info_t( self, *args ) + answer = [] - map( lambda base: answer.append( report_dependency( base.related_class, base.access_type ) ) + map( lambda base: answer.append( report_dependency( base.related_class, base.access_type, "base class" ) ) , self.bases ) if recursive: Modified: pygccxml_dev/pygccxml/declarations/dependencies.py =================================================================== --- pygccxml_dev/pygccxml/declarations/dependencies.py 2008-08-20 06:20:45 UTC (rev 1398) +++ pygccxml_dev/pygccxml/declarations/dependencies.py 2008-08-20 11:32:49 UTC (rev 1399) @@ -10,7 +10,7 @@ import cpptypes class dependency_info_t( object ): - def __init__( self, declaration, depend_on_it, access_type=None ): + def __init__( self, declaration, depend_on_it, access_type=None, hint=None ): object.__init__( self ) #prevent recursive import import class_declaration @@ -18,6 +18,7 @@ self._declaration = declaration self._depend_on_it = depend_on_it self._access_type = access_type + self._hint = hint @property def declaration( self ): @@ -39,6 +40,12 @@ return 'declaration "%s" depends( %s ) on "%s" ' \ % ( self.declaration, self.access_type, self.depend_on_it ) + @property + def hint(self): + """the declaration, that report dependency can put some additional inforamtion + about dependency. It can be used later""" + return self._hint + def find_out_depend_on_declaration( self ): """if declaration depends on other declaration and not on some type this function will return reference to it. Otherwise None will be returned Modified: pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2008-08-20 06:20:45 UTC (rev 1398) +++ pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2008-08-20 11:32:49 UTC (rev 1399) @@ -76,12 +76,14 @@ if decl.already_exposed: return [] dependencies = decl.i_depend_on_them(recursive=False) + if isinstance( decl, declarations.class_t ): dependencies = filter( lambda d: d.access_type != declarations.ACCESS_TYPES.PRIVATE - , dependencies ) + , dependencies ) + return dependencies - def __has_unexposed_dependency( self, exported_ids, depend_on_decl ): + def __has_unexposed_dependency( self, exported_ids, depend_on_decl, dependency ): sptr_traits = declarations.smart_pointer_traits if None is depend_on_decl: @@ -93,7 +95,7 @@ if sptr_traits.is_smart_pointer( depend_on_decl ): try: value_type = sptr_traits.value_type( depend_on_decl ) - return self.__has_unexposed_dependency( exported_ids, value_type ) + return self.__has_unexposed_dependency( exported_ids, value_type, dependency ) except RuntimeError: pass @@ -103,9 +105,23 @@ if isinstance( depend_on_decl, declarations.class_types ): if depend_on_decl.opaque: return + if dependency.hint == "base class": + return #base class for some class don't have to be exported if isinstance( depend_on_decl, declarations.variable_t ): if not decl.expose_value: return + + if isinstance( dependency.decl, declarations.variable_t ): + #the only dependency of the variable is its type + if not dependency.decl.expose_value: + return + + if dependency.hint == "return type": + #in this case we don't check, the return type but the function + if isinstance( dependency.decl, declarations.calldef_t ): + if dependency.decl.return_type and dependency.decl.call_policies \ + and decl_wrappers.is_return_opaque_pointer_policy( dependency.decl.call_policies ): + return return id( depend_on_decl ) not in exported_ids @@ -115,7 +131,7 @@ for decl in self.__exported_decls: for dependency in self.__build_dependencies( decl ): depend_on_decl = dependency.find_out_depend_on_declaration() - if self.__has_unexposed_dependency( exported_ids, depend_on_decl ): + if self.__has_unexposed_dependency( exported_ids, depend_on_decl, dependency ): if messages.filter_disabled_msgs([messages.W1040], depend_on_decl.disabled_messages ): #need to report dependency errors used_not_exported.append(dependency) Modified: pyplusplus_dev/unittests/data/mem_fun_with_exception_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/mem_fun_with_exception_to_be_exported.hpp 2008-08-20 06:20:45 UTC (rev 1398) +++ pyplusplus_dev/unittests/data/mem_fun_with_exception_to_be_exported.hpp 2008-08-20 11:32:49 UTC (rev 1399) @@ -1,23 +1,23 @@ -// 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 __mem_fun_with_exception_to_be_exported_hpp__ -#define __mem_fun_with_exception_to_be_exported_hpp__ - -#include <exception> - -namespace mem_fun_with_exception{ +// 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 __mem_fun_with_exception_to_be_exported_hpp__ +#define __mem_fun_with_exception_to_be_exported_hpp__ + +#include <stdexcept> + +namespace mem_fun_with_exception{ + struct data_t{ public: - virtual void do_nothing() throw( std::exception ) + virtual void do_nothing() throw( std::exception ) {} }; - -} - + +} + #endif//__mem_fun_with_exception_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-08-20 06:20:38
|
Revision: 1398 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1398&view=rev Author: roman_yakovenko Date: 2008-08-20 06:20:45 +0000 (Wed, 20 Aug 2008) Log Message: ----------- improve dependencies_manager.py class algorithm add new test Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/properties.py pyplusplus_dev/pyplusplus/file_writers/multiple_files.py pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py pyplusplus_dev/pyplusplus/module_creator/types_database.py pyplusplus_dev/unittests/test_all.py Added Paths: ----------- pyplusplus_dev/unittests/data/return_auto_ptr_to_be_exported.hpp pyplusplus_dev/unittests/return_auto_ptr_tester.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2008-08-18 18:58:51 UTC (rev 1397) +++ pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper.py 2008-08-20 06:20:45 UTC (rev 1398) @@ -185,10 +185,11 @@ return messages.filter_disabled_msgs( msgs, self.__msgs_to_ignore ) @property - def disabled_messaged( self ): + def disabled_messages( self ): """list of messages to ignore""" return self.__msgs_to_ignore - + disabled_messaged = disabled_messages + def disable_messages( self, *args ): """set messages, which should not be reported to you Modified: pyplusplus_dev/pyplusplus/decl_wrappers/properties.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/properties.py 2008-08-18 18:58:51 UTC (rev 1397) +++ pyplusplus_dev/pyplusplus/decl_wrappers/properties.py 2008-08-20 06:20:45 UTC (rev 1398) @@ -262,7 +262,7 @@ def __report_illegal_property( self, property_ ): logger = _logging_.loggers.declarations - if not messages.filter_disabled_msgs([messages.W1041], property_.fget.parent.disabled_messaged ): + if not messages.filter_disabled_msgs([messages.W1041], property_.fget.parent.disabled_messages ): return #user disabled property warning logger.warn( "%s;%s" % ( property_.fget.parent, messages.W1041 % property_ ) ) Modified: pyplusplus_dev/pyplusplus/file_writers/multiple_files.py =================================================================== --- pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2008-08-18 18:58:51 UTC (rev 1397) +++ pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2008-08-20 06:20:45 UTC (rev 1398) @@ -155,7 +155,7 @@ return self.create_value_traits_header_name( value_class ) except RuntimeError, error: decls_logger = _logging_.loggers.declarations - if not messages.filter_disabled_msgs([messages.W1042], code_creator.declaration.disabled_messaged ): + if not messages.filter_disabled_msgs([messages.W1042], code_creator.declaration.disabled_messages ): return #user disabled property warning decls_logger.warn( "%s;%s" % ( code_creator.declaration, messages.W1042 ) ) Modified: pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2008-08-18 18:58:51 UTC (rev 1397) +++ pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2008-08-20 06:20:45 UTC (rev 1398) @@ -81,29 +81,44 @@ , dependencies ) return dependencies + def __has_unexposed_dependency( self, exported_ids, depend_on_decl ): + sptr_traits = declarations.smart_pointer_traits + + if None is depend_on_decl: + return + + if self.__is_std_decl( depend_on_decl ): + return + + if sptr_traits.is_smart_pointer( depend_on_decl ): + try: + value_type = sptr_traits.value_type( depend_on_decl ) + return self.__has_unexposed_dependency( exported_ids, value_type ) + except RuntimeError: + pass + + if isinstance( depend_on_decl, decl_wrappers.decl_wrapper_t ): + if depend_on_decl.already_exposed: + return + if isinstance( depend_on_decl, declarations.class_types ): + if depend_on_decl.opaque: + return + if isinstance( depend_on_decl, declarations.variable_t ): + if not decl.expose_value: + return + + return id( depend_on_decl ) not in exported_ids + def __find_out_used_but_not_exported( self ): used_not_exported = [] exported_ids = set( map( lambda d: id( d ), self.__exported_decls ) ) for decl in self.__exported_decls: - for dependency in self.__build_dependencies( decl ): - depend_on_decl = dependency.find_out_depend_on_declaration() - if None is depend_on_decl: - continue - if self.__is_std_decl( depend_on_decl ): - continue - if isinstance( depend_on_decl, decl_wrappers.decl_wrapper_t ): - if depend_on_decl.already_exposed: - continue - if isinstance( depend_on_decl, declarations.class_types ): - if depend_on_decl.opaque: - continue - if isinstance( decl, declarations.variable_t ): - if not decl.expose_value: - continue - if id( depend_on_decl ) not in exported_ids: - report = messages.filter_disabled_msgs([messages.W1040], depend_on_decl.disabled_messaged ) - if report: - used_not_exported.append( dependency ) + for dependency in self.__build_dependencies( decl ): + depend_on_decl = dependency.find_out_depend_on_declaration() + if self.__has_unexposed_dependency( exported_ids, depend_on_decl ): + if messages.filter_disabled_msgs([messages.W1040], depend_on_decl.disabled_messages ): + #need to report dependency errors + used_not_exported.append(dependency) return used_not_exported def __group_by_unexposed( self, dependencies ): Modified: pyplusplus_dev/pyplusplus/module_creator/types_database.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/types_database.py 2008-08-18 18:58:51 UTC (rev 1397) +++ pyplusplus_dev/pyplusplus/module_creator/types_database.py 2008-08-20 06:20:45 UTC (rev 1398) @@ -75,7 +75,7 @@ container_cls.indexing_suite.element_type except RuntimeError: decls_logger = _logging_.loggers.declarations - if not messages.filter_disabled_msgs([messages.W1042], container_cls.disabled_messaged ): + if not messages.filter_disabled_msgs([messages.W1042], container_cls.disabled_messages ): return #user disabled property warning decls_logger.warn( "%s;%s" % ( container_cls, messages.W1042 ) ) self.__containers.add( container_cls ) Added: pyplusplus_dev/unittests/data/return_auto_ptr_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/return_auto_ptr_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/return_auto_ptr_to_be_exported.hpp 2008-08-20 06:20:45 UTC (rev 1398) @@ -0,0 +1,52 @@ +// 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 __return_auto_ptr_to_be_exported_hpp__ +#define __return_auto_ptr_to_be_exported_hpp__ +#include "boost/shared_ptr.hpp" +#include <memory> + + +namespace smart_pointers{ + +struct r_input_t{ + r_input_t(unsigned int rows, unsigned int cols) + : m_rows(rows) + , m_cols(cols) + {} + + unsigned int rows() const {return m_rows;} + unsigned int cols() const {return m_cols;} + +private: + unsigned int m_rows; + unsigned int m_cols; +}; + + +class generic_input_t +{ +public: + // Pure virtual function to convert to the required type + virtual std::auto_ptr<r_input_t> create_r_input() = 0; + + virtual boost::shared_ptr<r_input_t> create_r_input_shared() = 0; +}; + + +// Function which converts generic_input_t to r_input_t +std::auto_ptr<r_input_t> process_input(generic_input_t& input) +{ + return input.create_r_input(); +} + +boost::shared_ptr<r_input_t> process_input_shared(generic_input_t& input) +{ + return input.create_r_input_shared(); +} + +} + +#endif//__return_auto_ptr_to_be_exported_hpp__ Added: pyplusplus_dev/unittests/return_auto_ptr_tester.py =================================================================== --- pyplusplus_dev/unittests/return_auto_ptr_tester.py (rev 0) +++ pyplusplus_dev/unittests/return_auto_ptr_tester.py 2008-08-20 06:20:45 UTC (rev 1398) @@ -0,0 +1,66 @@ +# 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 import messages + +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'return_auto_ptr' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def customize( self, mb ): + pass + #~ r_input = mb.class_( 'r_input_t' ) + #~ r_input.held_type = 'std::auto_ptr< %s >' % r_input.decl_string + + def create_py_input( self, module, rows, cols ): + class py_input_t( module.generic_input_t ): + def __init__( self, rows, cols ): + module.generic_input_t.__init__( self ) + self.rows = rows + self.cols = cols + + def create_r_input( self ): + return module.r_input_t( self.rows, self.cols ) + + def create_r_input_shared( self ): + return module.r_input_t( self.rows, self.cols ) + + return py_input_t(rows, cols) + + def run_tests( self, module): + a = self.create_py_input( module, 3, 7 ) + c = a.create_r_input() + self.failUnless( c.rows() == 3 and c.cols() == 7 ) + try: + b = module.process_input(a) + self.failUnless( b.rows() == 3 and b.cols() == 7 ) + except TypeError, err: + print err + + c = a.create_r_input_shared() + self.failUnless( c.rows() == 3 and c.cols() == 7 ) + b = module.process_input_shared(a) + self.failUnless( b.rows() == 3 and b.cols() == 7 ) + +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-08-18 18:58:51 UTC (rev 1397) +++ pyplusplus_dev/unittests/test_all.py 2008-08-20 06:20:45 UTC (rev 1398) @@ -108,6 +108,7 @@ import unions_tester import cp_return_addressof_tester import make_constructor_tester +import return_auto_ptr_tester #import ogre_generate_tester testers = [ @@ -204,6 +205,7 @@ , unions_tester , cp_return_addressof_tester , make_constructor_tester + , return_auto_ptr_tester # , ogre_generate_tester too much time ] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-18 18:58:54
|
Revision: 1397 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1397&view=rev Author: roman_yakovenko Date: 2008-08-18 18:58:51 +0000 (Mon, 18 Aug 2008) Log Message: ----------- improving "make_constructor" functionality Modified Paths: -------------- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/messages/warnings_.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/data/free_functions_to_be_exported.hpp pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp pyplusplus_dev/unittests/make_constructor_tester.py Added Paths: ----------- pyplusplus_dev/pyplusplus/module_creator/fake_constructors_manager.py Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-08-14 18:49:06 UTC (rev 1396) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-08-18 18:58:51 UTC (rev 1397) @@ -169,6 +169,9 @@ WRAPPER = 'wrapper' ALL = ( DECLARED, WRAPPER ) + FAKE_CONSTRUCTOR_TYPES = ( declarations.member_function_t, declarations.free_function_t ) + FAKE_CONSTRUCTOR_TYPE_NAMES = 'member and free functions' + def __init__(self, *arguments, **keywords): class_common_details_t.__init__( self ) declarations.class_t.__init__(self, *arguments, **keywords ) @@ -193,17 +196,17 @@ self._expose_this = None self._expose_sizeof = None self._fake_constructors = [] - + @property def fake_constructors(self): """list of fake constructors""" return self._fake_constructors - + def add_fake_constructors( self, f ): """f - reference to a calldef_t object or list of them - + boost::python::make_constructor allows to register a C++ function, as a - class constructor. + class constructor. """ if isinstance( f, declarations.calldef_t ): self._fake_constructors.add( f ) @@ -624,7 +627,16 @@ return explanation def _readme_impl( self ): - return self.is_wrapper_needed() + explanation = self.is_wrapper_needed() + for fc in self.fake_constructors: + if fc.ignore: + explanation.append( messages.W1062 % ( str( self ), str( fc ) ) ) + if not fc.exportable: + explanation.append( messages.W1063 % ( str( self ), str( fc ) ) ) + if not isinstance( fc, self.FAKE_CONSTRUCTOR_TYPES ): + explanation.append( messages.W1064 + % ( str( fc ), str( self ), self.FAKE_CONSTRUCTOR_TYPE_NAMES ) ) + return explanation def guess_always_expose_using_scope_value( self ): def is_assign( oper ): Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-08-14 18:49:06 UTC (rev 1396) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-08-18 18:58:51 UTC (rev 1397) @@ -237,6 +237,15 @@ W1061 = compilation_error( 'Py++ can not expose "%s" - its type is "%s".' ' This could be changed in future.') +W1062 = compilation_error( '"%s" contains "fake constructor" "%s", that was excluded.' + ' Py++ will not generate "__init__" method, based on that function.') + +W1063 = compilation_error( '"%s" contains "fake constructor" "%s", that is exportable.' + ' Py++ will not generate "__init__" method, based on that function.') + +W1064 = compilation_error( 'Py++ can not expose "%s" as "fake constructor" of "%s".' + ' Only the following function types supported: %s' ) + warnings = globals() all_warning_msgs = [] Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-14 18:49:06 UTC (rev 1396) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-18 18:58:51 UTC (rev 1397) @@ -9,6 +9,7 @@ import dependencies_manager import opaque_types_manager import call_policies_resolver +import fake_constructors_manager from pygccxml import declarations from pyplusplus import decl_wrappers @@ -78,7 +79,7 @@ self.__types_db = types_db if not self.__types_db: self.__types_db = types_database.types_database_t() - + global_ns = declarations.get_global_namespace(decls) self.__extmodule = code_creators.module_t( global_ns ) if boost_python_ns_name: @@ -101,9 +102,7 @@ self.__array_1_registered = set() #(type.decl_string,size) self.__free_operators = [] self.__exposed_free_fun_overloads = set() - self.__fake_constructors = set() - for cls in global_ns.classes(recursive=True, allow_empty=True): - self.__fake_constructors.update( cls.fake_constructors ) + self.__fc_manager = fake_constructors_manager.manager_t( global_ns ) def __print_readme( self, decl ): readme = decl.readme() @@ -353,9 +352,9 @@ self.__types_db.update( self.curr_decl ) self.__dependencies_manager.add_exported( self.curr_decl ) - if self.curr_decl in self.__fake_constructors: + if self.__fc_manager.is_fake_constructor( self.curr_decl ): return - + fwrapper = None if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) @@ -460,12 +459,12 @@ def visit_free_function( self ): if self.curr_decl in self.__exposed_free_fun_overloads: return - - if self.curr_decl in self.__fake_constructors: + + if self.__fc_manager.is_fake_constructor( self.curr_decl ): self.__types_db.update( self.curr_decl ) self.__dependencies_manager.add_exported( self.curr_decl ) return - + elif self.curr_decl.use_overload_macro: parent_decl = self.curr_decl.parent names = set( map( lambda decl: decl.name @@ -608,9 +607,6 @@ if cls_decl.expose_sizeof: cls_cc.adopt_creator( code_creators.expose_sizeof_t( cls_decl ) ) - for fc in cls_decl.fake_constructors: - cls_cc.adopt_creator( code_creators.make_constructor_t( fc ) ) - for decl in exportable_members: if decl in exposed: continue @@ -646,6 +642,10 @@ destructor = code_creators.destructor_wrapper_t( class_=cls_decl ) wrapper.adopt_creator( destructor ) + for fc in cls_decl.fake_constructors: + if self.__fc_manager.should_generate_code( fc ): + cls_cc.adopt_creator( code_creators.make_constructor_t( fc ) ) + self.curr_decl = cls_decl self.curr_code_creator = cls_parent_cc Added: pyplusplus_dev/pyplusplus/module_creator/fake_constructors_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/fake_constructors_manager.py (rev 0) +++ pyplusplus_dev/pyplusplus/module_creator/fake_constructors_manager.py 2008-08-18 18:58:51 UTC (rev 1397) @@ -0,0 +1,29 @@ +# 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) + +"""defines class, which manages "fake constructors" """ + +class manager_t( object ): + def __init__( self, global_ns ): + self.__global_ns = global_ns + self.__fc_all = set() + self.__fc_exposed = set() + + for cls in global_ns.classes(recursive=True, allow_empty=True): + for fc in cls.fake_constructors: + self.__fc_all.add( fc ) + if fc.ignore: + continue + if not fc.exportable: + continue + if not isinstance( fc, cls.FAKE_CONSTRUCTOR_TYPES ): + continue + self.__fc_exposed.add( fc ) + + def is_fake_constructor( self, fc ): + return fc in self.__fc_all + + def should_generate_code( self, fc ): + return fc in self.__fc_exposed Modified: pyplusplus_dev/unittests/data/free_functions_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/free_functions_to_be_exported.hpp 2008-08-14 18:49:06 UTC (rev 1396) +++ pyplusplus_dev/unittests/data/free_functions_to_be_exported.hpp 2008-08-18 18:58:51 UTC (rev 1397) @@ -6,6 +6,8 @@ #ifndef __free_functions_to_be_exported_hpp__ #define __free_functions_to_be_exported_hpp__ +#include <stddef.h> + namespace free_functions{ inline int one(){ @@ -16,7 +18,10 @@ return a+b; } +inline void do_smth( size_t , int ){ } +} + #endif//__free_functions_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp 2008-08-14 18:49:06 UTC (rev 1396) +++ pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp 2008-08-18 18:58:51 UTC (rev 1397) @@ -9,21 +9,21 @@ #include <memory> namespace mc{ - + struct numbers_t{ numbers_t() : x( 0 ) , y( 0 ) {} ~numbers_t(){} - + static std::auto_ptr<numbers_t> create( int i, int j, int k, int m ){ std::auto_ptr<numbers_t> n( new numbers_t() ); n->x = i + j; n->y = k + m; return n; } - + int x; int y; }; @@ -35,6 +35,11 @@ return n; } +inline std::auto_ptr<numbers_t> create( double, double, double, double, double){ + return std::auto_ptr<numbers_t>(); } + +} + #endif//__make_constructor_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/make_constructor_tester.py =================================================================== --- pyplusplus_dev/unittests/make_constructor_tester.py 2008-08-14 18:49:06 UTC (rev 1396) +++ pyplusplus_dev/unittests/make_constructor_tester.py 2008-08-18 18:58:51 UTC (rev 1397) @@ -10,27 +10,28 @@ class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'make_constructor' - + 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 ): mc = mb.namespace( 'mc' ) numbers = mc.class_( 'numbers_t' ) numbers.add_fake_constructors( mc.calldefs( 'create' ) ) - - - def run_tests(self, module): + numbers.add_fake_constructors( mc.calldefs(lambda d: d.name.startswith('~') ) ) + mc.calldef( 'create', arg_types=[None]*5 ).exclude() + + def run_tests(self, module): n = module.numbers_t( 1,2,3,4) self.failUnless( n.x == 1+2 and n.y == 3+4) n = module.numbers_t( 10, 18) self.failUnless( n.x == 10 and n.y == 18) - + 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. |
From: <rom...@us...> - 2008-08-14 18:48:56
|
Revision: 1396 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1396&view=rev Author: roman_yakovenko Date: 2008-08-14 18:49:06 +0000 (Thu, 14 Aug 2008) Log Message: ----------- update documentation Modified Paths: -------------- pyplusplus_dev/docs/history/history.rest Added Paths: ----------- pyplusplus_dev/docs/documentation/functions/make_constructor.rest Added: pyplusplus_dev/docs/documentation/functions/make_constructor.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/make_constructor.rest (rev 0) +++ pyplusplus_dev/docs/documentation/functions/make_constructor.rest 2008-08-14 18:49:06 UTC (rev 1396) @@ -0,0 +1,78 @@ +================ +make_constructor +================ + +.. contents:: Table of contents + +------------ +Introduction +------------ + +`Boost.Python`_ allows us to register some function as `Python`_ class ``__init__`` +method. This could be done using `make_constructor`_ functionality. + +Not every function could be registered as ``__init__`` method. The function return +type should be a pointer or a smart pointer to the new class instance. + +------------- +Usage example +------------- +I am going to use the following code to demonstrate the functionality: + +.. code-block:: C++ + + #include <memory> + + namespace mc{ + + struct number_t{ + + static std::auto_ptr<number_t> create( int i, int j); + + int x; + }; + + std::auto_ptr<number_t> create(int i); + + }//namespace mc + +The code is pretty simple - it defines two ``create`` functions, which construct +new class ``number_t`` instances. + +`Py++`_ configuration is pretty simple: + +.. code-block:: Python + + from pyplusplus import module_builder + + mb = module_builder.module_builder_t( ... ) + mc = mb.namespace( 'mc ') + number = mc.class_( 'number_t' ) + number.add_fake_constructors( mc.calldefs( 'create' ) ) + #------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Basically you associate with the class the functions, you want to register as +the class ``__init__`` method. + +The method ``add_fake_constructors`` takes as argument a reference to "create" +function or a list of such. + +The generated code is pretty boring and the only thing I would like to mention +is that the function will **not** be exposed as a standalone function. + +The usage code is even more boring: + +.. code-block:: Python + + from your_module import number_t + + number = number_t( 1 ) + print number.x + number = number_t( 1, 2 ) + print number.x + +.. _`make_constructor`: http://www.boost.org/doc/libs/1_35_0/libs/python/doc/v2/make_function.html#make_constructor-spec +.. _`Py++` : ./../../pyplusplus.html +.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org Modified: pyplusplus_dev/docs/history/history.rest =================================================================== --- pyplusplus_dev/docs/history/history.rest 2008-08-14 07:45:25 UTC (rev 1395) +++ pyplusplus_dev/docs/history/history.rest 2008-08-14 18:49:06 UTC (rev 1396) @@ -115,6 +115,7 @@ which will not break the existing code. I see few solutions to the problem: * change the alias of the functions + .. code-block:: Python from pyplusplus import module_builder @@ -140,10 +141,13 @@ 3. New and highly experimental feature was introduced - `Boost.Python and ctypes integration`_. - ../documentation/ctypes_integration.html .. _`Boost.Python and ctypes integration` : ../documentation/ctypes_integration.html +4. Support for `boost::python::make_constructor`_ functionality was added. + +.. _`boost::python::make_constructor` : ../documentation/functions/make_constructor.html + ------------- Version 0.9.5 ------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-14 07:45:15
|
Revision: 1395 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1395&view=rev Author: roman_yakovenko Date: 2008-08-14 07:45:25 +0000 (Thu, 14 Aug 2008) Log Message: ----------- small correction in documentation Modified Paths: -------------- pyplusplus_dev/docs/documentation/ctypes/this_and_sizeof.rest Modified: pyplusplus_dev/docs/documentation/ctypes/this_and_sizeof.rest =================================================================== --- pyplusplus_dev/docs/documentation/ctypes/this_and_sizeof.rest 2008-08-14 07:43:48 UTC (rev 1394) +++ pyplusplus_dev/docs/documentation/ctypes/this_and_sizeof.rest 2008-08-14 07:45:25 UTC (rev 1395) @@ -28,7 +28,7 @@ .. code-block:: Python import ctypes - import <your module> import <your class> as data_t + from <your module> import <your class> as data_t d = data_t() print d.this This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-14 07:43:38
|
Revision: 1394 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1394&view=rev Author: roman_yakovenko Date: 2008-08-14 07:43:48 +0000 (Thu, 14 Aug 2008) Log Message: ----------- small correction in documentation Modified Paths: -------------- pyplusplus_dev/docs/documentation/ctypes/unions.rest Modified: pyplusplus_dev/docs/documentation/ctypes/unions.rest =================================================================== --- pyplusplus_dev/docs/documentation/ctypes/unions.rest 2008-08-14 07:31:30 UTC (rev 1393) +++ pyplusplus_dev/docs/documentation/ctypes/unions.rest 2008-08-14 07:43:48 UTC (rev 1394) @@ -47,7 +47,7 @@ .. code-block:: Python import ctypes - import <your module> import data_t + from <your module> import data_t #lets define our union class actual_data_t( ctypes.Union ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-14 07:31:27
|
Revision: 1393 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1393&view=rev Author: roman_yakovenko Date: 2008-08-14 07:31:30 +0000 (Thu, 14 Aug 2008) Log Message: ----------- documentation changes: replace "next" with "the following" Modified Paths: -------------- index.rest pygccxml_dev/docs/design.rest pygccxml_dev/docs/download.rest pygccxml_dev/docs/pygccxml.rest pygccxml_dev/docs/query_interface.rest pygccxml_dev/docs/upgrade_issues.rest pyplusplus_dev/docs/comparisons/pyste.rest pyplusplus_dev/docs/documentation/architecture.rest pyplusplus_dev/docs/documentation/containers.rest pyplusplus_dev/docs/documentation/ctypes/ctypes_integration.rest pyplusplus_dev/docs/documentation/ctypes/unions.rest pyplusplus_dev/docs/documentation/functions/call_policies.rest pyplusplus_dev/docs/documentation/functions/default_args.rest pyplusplus_dev/docs/documentation/functions/overloading.rest pyplusplus_dev/docs/documentation/functions/registration_order.rest pyplusplus_dev/docs/documentation/functions/transformation/inout.rest pyplusplus_dev/docs/documentation/functions/transformation/input.rest pyplusplus_dev/docs/documentation/functions/transformation/input_c_buffer.rest pyplusplus_dev/docs/documentation/functions/transformation/input_static_array.rest pyplusplus_dev/docs/documentation/functions/transformation/modify_type.rest pyplusplus_dev/docs/documentation/functions/transformation/name_mangling.rest pyplusplus_dev/docs/documentation/functions/transformation/output.rest pyplusplus_dev/docs/documentation/functions/transformation/output_static_array.rest pyplusplus_dev/docs/documentation/functions/transformation/transfer_ownership.rest pyplusplus_dev/docs/documentation/functions/transformation/transformation.rest pyplusplus_dev/docs/documentation/how_to/absolute_relative_paths.rest pyplusplus_dev/docs/documentation/how_to/best_practices.rest pyplusplus_dev/docs/documentation/how_to/file_name_too_long.rest pyplusplus_dev/docs/documentation/how_to/templates.rest pyplusplus_dev/docs/documentation/inserting_code.rest pyplusplus_dev/docs/documentation/multi_module_development.rest pyplusplus_dev/docs/documentation/properties.rest pyplusplus_dev/docs/documentation/split_module.rest pyplusplus_dev/docs/documentation/warnings.rest pyplusplus_dev/docs/download.rest pyplusplus_dev/docs/examples/boost/boost.rest pyplusplus_dev/docs/history/history.rest pyplusplus_dev/docs/peps/dsl_challenge.rest pyplusplus_dev/docs/pyplusplus.rest pyplusplus_dev/docs/quotes.rest pyplusplus_dev/docs/troubleshooting_guide/easy_extending_guide/easy_extending_guide.rest pyplusplus_dev/docs/troubleshooting_guide/exceptions/exceptions.rest Modified: index.rest =================================================================== --- index.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ index.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -38,7 +38,7 @@ --------------- `Boost`_ provides free peer-reviewed portable C++ source libraries. `pyboost`_ -package export next libraries to Python: +package export the following libraries to Python: * `Boost.Date_Time`_ - date time library designed to provide a basis for performing efficient time calculations Modified: pygccxml_dev/docs/design.rest =================================================================== --- pygccxml_dev/docs/design.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pygccxml_dev/docs/design.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -184,7 +184,7 @@ ``file_configuration_t`` - a class, that contains some data and description how -to treat the data. ``file_configuration_t`` can contain reference to the next types +to treat the data. ``file_configuration_t`` can contain reference to the the following types of data: (1) path to C++ source file Modified: pygccxml_dev/docs/download.rest =================================================================== --- pygccxml_dev/docs/download.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pygccxml_dev/docs/download.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -58,7 +58,7 @@ pygccxml -------- In command prompt or shell change current directory to be "pygccxml-X.Y.Z". -"X.Y.Z" is version of `pygccxml`_. Type next command: +"X.Y.Z" is version of `pygccxml`_. Type the following command: | ``python setup.py install`` Modified: pygccxml_dev/docs/pygccxml.rest =================================================================== --- pygccxml_dev/docs/pygccxml.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pygccxml_dev/docs/pygccxml.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -39,7 +39,7 @@ Query interface --------------- `pygccxml`_ provides simple and powerful API to query declarations tree. How many -lines is needed to write next query? +lines is needed to write the following query? :: select all free functions from the project Modified: pygccxml_dev/docs/query_interface.rest =================================================================== --- pygccxml_dev/docs/query_interface.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pygccxml_dev/docs/query_interface.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -38,7 +38,7 @@ User interface -------------- -As you already know, ``pygccxml.declarations`` package defines next classes: +As you already know, ``pygccxml.declarations`` package defines the following classes: * ``scopedef_t`` - base class for all classes, that can contain other declarations @@ -205,7 +205,7 @@ }; ``clone`` member function `call policies`_ is ``return_value_policy<manage_new_object>()``. -Next code applies the `call policies`_ on all ``clone`` member functions within the +The following code applies the `call policies`_ on all ``clone`` member functions within the project: .. code-block:: Python @@ -216,7 +216,7 @@ Another example, from `Py++`_ project. Sometimes it is desirable to -exclude declaration, from being exported to Python. Next code will exclude +exclude declaration, from being exported to Python. The following code will exclude ``clone`` member function from being exported: .. code-block:: Python @@ -226,7 +226,7 @@ As you can see this class allows you to write less code. Basically using this class you don't have to write loops. If will do it for you. Also if you insist to write loops, ``mdecl_wrapper_t`` class implements ``__len__``, ``__getitem__`` -and ``__iter__`` methods. So you can write next code: +and ``__iter__`` methods. So you can write the following code: .. code-block:: Python Modified: pygccxml_dev/docs/upgrade_issues.rest =================================================================== --- pygccxml_dev/docs/upgrade_issues.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pygccxml_dev/docs/upgrade_issues.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -99,7 +99,7 @@ ------------------------------------------ Both versions of GCC-XML have a few issues, related to default arguments. GCC-XML 0.9 -fixes some issues, but introduces another ones. Take a look on next examples: +fixes some issues, but introduces another ones. Take a look on the following examples: * .. code-block:: C++ @@ -209,7 +209,7 @@ GCC-XML 0.9 mangles names different than the previous one. This change is the most dramatic one, because it may require from you to change the code. -Consider next C++ code: +Consider the following C++ code: .. code-block:: C++ Modified: pyplusplus_dev/docs/comparisons/pyste.rest =================================================================== --- pyplusplus_dev/docs/comparisons/pyste.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/comparisons/pyste.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -198,9 +198,9 @@ void do_smth(expensive_to_copy* x, const expensive_to_copy& y){ - //Pyste generates next code + //Pyste generates the following code //call_method< void >(self, "do_smth", x, y); - //Py++ generates next code + //Py++ generates the following code *this->get_override("do_smth")( boost::python::ptr(x), boost::ref(y) ); //------------------------------^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^ } @@ -290,7 +290,7 @@ Features list ------------- `Py++`_ supports almost all features `Pyste`_ implements. `Py++`_, -version 0.8.0, does not implements next functionality, implemented by `Pyste`_: +version 0.8.0, does not implements the following functionality, implemented by `Pyste`_: * *pow* operator @@ -324,7 +324,7 @@ ------------------ Both `Pyste`_ and `Py++`_ generate working code. As we already saw in some -cases `Py++`_ do better job. `Py++`_ allows next customization on +cases `Py++`_ do better job. `Py++`_ allows the following customization on generated code: * To define std and user directories. *include_t* code creator will take @@ -409,7 +409,7 @@ This comparison was a little unfair. First of all `Pyste`_ is no more under active development\\support. Second, `Pyste`_ has been written 2 years ago and -had different goal. Next definitions will help you to understand the main +had different goal. The following definitions will help you to understand the main difference between `Pyste`_ and `Py++`_. `Pyste`_ Modified: pyplusplus_dev/docs/documentation/architecture.rest =================================================================== --- pyplusplus_dev/docs/documentation/architecture.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/architecture.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -26,7 +26,7 @@ On the earlier stage of the development, I realized, that all this functionality does not belong to code generator and should be implemented out side of it. `pygccxml`_ project was born. `pygccxml`_ made the code generator to be smaller -and C++ parser independent. It provides next services: +and C++ parser independent. It provides the following services: * definition of classes, that describe C++ declaration and types, and their analyzers ( type traits ) @@ -82,7 +82,7 @@ wrapping or hiding the API will not provide an additional value. The interface of all those services is pretty simple and well polished. -Before I explain how these services are integrated, take a look on next source +Before I explain how these services are integrated, take a look on the following source code: .. code-block:: Python @@ -111,7 +111,7 @@ good, it makes a lot of sense to configure the code generation engine, using the declarations tree. How does `Py++`_ add missing functionality to ``pygccxml.declarations`` classes? There were few possible solutions to the -problem. The next one was implemented: +problem. The following one was implemented: 1. ``pygccxml.parser`` package interface was extended. Instead of creating a concrete instance of declaration classes, ``pygccxml.parser`` package uses @@ -129,7 +129,7 @@ * the functionality provided by ``pygccxml.declarations`` and ``pygccxml.parser`` packages is available for ``pyplusplus.decl_wrappers`` classes -* classes defined in ``pyplusplus.decl_wrappers`` package implement next +* classes defined in ``pyplusplus.decl_wrappers`` package implement the following functionality: * setting reasonable defaults for the code generation engine( call policies, @@ -161,7 +161,7 @@ ----------------- Do you know how many ways exist to export member function? If you will try to -answer the question, consider next function characteristics and their mix: +answer the question, consider the following function characteristics and their mix: * virtuality( non virtual, virtual or pure virtual ) @@ -243,7 +243,7 @@ ~~~~~~~~~~~~~~~~~~~~~~ ``code_creators.module_t`` class is a top level ``code creator``. Take a look on -next possible "snapshot" of the ``code creators tree``: +the following possible "snapshot" of the ``code creators tree``: :: @@ -296,7 +296,7 @@ ---------------- ``File writers`` classes are responsible for writing ``code creators tree`` into -the files. `Py++`_ implements next strategies of writing ``code creators tree`` +the files. `Py++`_ implements the following strategies of writing ``code creators tree`` into files: * single file Modified: pyplusplus_dev/docs/documentation/containers.rest =================================================================== --- pyplusplus_dev/docs/documentation/containers.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/containers.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -40,7 +40,7 @@ `Boost.Python`_ mailing list or `documentation`_ for the new indexing suite. -Now, I am sure you have next question: if this suite is so good, why it is not +Now, I am sure you have the following question: if this suite is so good, why it is not in the main branch? The short answer is that this suite has some problems on MSVC 6.0 compiler and there are few users, that still use that compiler. The long answer is here: @@ -77,7 +77,7 @@ ------------------- By default, `Py++`_ works with built-in indexing suite. If you want to use -next version of indexing suite, you should tell this to the ``module_builder_t.__init__`` +indexing suite version 2, you should tell this to the ``module_builder_t.__init__`` method: .. code-block:: Python @@ -102,7 +102,7 @@ `Py++`_ defines ``indexing_suite1_t`` class. This class allows configure any detail of generated code: -* ``no_proxy`` - a boolean, if ``value_type`` is one of the next types +* ``no_proxy`` - a boolean, if ``value_type`` is one of the the following types * fundamental type @@ -119,11 +119,11 @@ * ``element_type`` - is a reference to container ``value_type`` or ``mapped_type``. -Next version of indexing suite API +Indexing suite version 2 API ---------------------------------- In this case there is no single place, where you can configure exported container -functionality. Please take a look on next C++ code: +functionality. Please take a look on the following C++ code: .. code-block:: C++ Modified: pyplusplus_dev/docs/documentation/ctypes/ctypes_integration.rest =================================================================== --- pyplusplus_dev/docs/documentation/ctypes/ctypes_integration.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/ctypes/ctypes_integration.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -77,7 +77,7 @@ ----------------- The functionality is going to be developed father and I intend to add -next features: +the following features: * to port this functionality to 64bit systems Modified: pyplusplus_dev/docs/documentation/ctypes/unions.rest =================================================================== --- pyplusplus_dev/docs/documentation/ctypes/unions.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/ctypes/unions.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -20,7 +20,7 @@ Example -------- -For this example I am going to use next code: +For this example I am going to use the following code: .. code-block:: C++ Modified: pyplusplus_dev/docs/documentation/functions/call_policies.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/call_policies.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/call_policies.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -432,7 +432,7 @@ `Boost.Python`_ call policies are stateless classes, which do not care any information about the invoked function or object. In out case we have to pass -next information: +dependency_libraries information: * the size of array @@ -451,7 +451,7 @@ * default constructor -* call operator with next signature: +* call operator with the following signature: .. code-block:: C++ @@ -462,7 +462,7 @@ Pay attention: this operator will be invoked **after** the function. This call policy is **not thread-safe**! -For our case, next class could be defined: +For our case, the following class could be defined: .. code-block:: C++ @@ -490,7 +490,7 @@ ... }; -Next "get size" class treats this situation: +The following "get size" class treats this situation: .. code-block:: C++ Modified: pyplusplus_dev/docs/documentation/functions/default_args.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/default_args.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/default_args.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -9,7 +9,7 @@ ------------ There is more than one way to export function with default arguments. Before we -proceed, please take a look on next class: +proceed, please take a look on the following class: .. code-block:: C++ Modified: pyplusplus_dev/docs/documentation/functions/overloading.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/overloading.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/overloading.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -11,7 +11,7 @@ Things get a little bit complex, when you have to export overloaded functions. In general the solution is to explicitly say to compiler what function you want to export, by specifying its type. Before we proceed, please take a look -on next class: +on the following class: .. code-block:: C++ @@ -76,11 +76,11 @@ Overloaded template function ---------------------------- -I am sure you already know next fact, but still I want to remind it: +I am sure you already know the following fact, but still I want to remind it: * `GCC-XML`_ doesn't report about un-instantiated templates -It is very important to understand it. Lets take a look on next source code: +It is very important to understand it. Lets take a look on the following source code: .. code-block:: C++ Modified: pyplusplus_dev/docs/documentation/functions/registration_order.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/registration_order.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/registration_order.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -64,7 +64,7 @@ Registration order pitfalls --------------------------- -Do you want to guess what is the output of the next program: +Do you want to guess what is the output of the following program: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/functions/transformation/inout.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/inout.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/transformation/inout.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -34,7 +34,7 @@ Lets say that you need to expose ``hello_world`` function. As you know ``std::string`` is mapped to `Python`_ string, which is immutable type, so you -have to create small wrapper for the function. Next `Py++`_ code does it for you: +have to create small wrapper for the function. The following `Py++`_ code does it for you: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/functions/transformation/input.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/input.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/transformation/input.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -28,7 +28,7 @@ Lets say that you need to expose ``hello_world`` function. As you know ``std::string`` is mapped to `Python`_ string, which is immutable type, so you -have to create small wrapper for the function. Next `Py++`_ code does it for you: +have to create small wrapper for the function. The following `Py++`_ code does it for you: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/functions/transformation/input_c_buffer.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/input_c_buffer.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/transformation/input_c_buffer.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -26,8 +26,8 @@ void write( char* buffer, int size ) const; }; -In order to expose ``write`` member function we need to create small wrapper: -Next `Py++`_ code does it for you: +In order to expose ``write`` member function we need to create small wrapper. +The following `Py++`_ code does it for you: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/functions/transformation/input_static_array.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/input_static_array.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/transformation/input_static_array.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -34,7 +34,7 @@ }; In order to expose ``init`` member function we need to create small wrapper: -Next `Py++`_ code does it for you: +The following `Py++`_ code does it for you: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/functions/transformation/modify_type.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/modify_type.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/transformation/modify_type.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -38,7 +38,7 @@ Lets say that you need to expose ``hello_world`` function. As you know ``std::string`` is mapped to `Python`_ string, which is immutable type, so you -have to create small wrapper for the function. Next `Py++`_ code does it for you: +have to create small wrapper for the function. The following `Py++`_ code does it for you: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/functions/transformation/name_mangling.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/name_mangling.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/transformation/name_mangling.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -18,7 +18,7 @@ I am sure you want to ask why and where `Py++`_ uses name mangling? `Py++`_ uses name mangling to create function-wrappers for overloaded and\\or free functions. -Consider next use case: +Consider the following use case: .. code-block:: C++ Modified: pyplusplus_dev/docs/documentation/functions/transformation/output.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/output.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/transformation/output.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -30,7 +30,7 @@ Lets say that you need to expose ``hello_world`` function. As you know ``std::string`` is mapped to `Python`_ string, which is immutable type, so you -have to create small wrapper for the function. Next `Py++`_ code does it for you: +have to create small wrapper for the function. The following `Py++`_ code does it for you: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/functions/transformation/output_static_array.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/output_static_array.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/transformation/output_static_array.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -32,8 +32,8 @@ int x,y,z; }; -In order to expose ``get_values`` member function we need to create small wrapper: -Next `Py++`_ code does it for you: +In order to expose ``get_values`` member function we need to create small wrapper. +The following `Py++`_ code does it for you: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/functions/transformation/transfer_ownership.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/transfer_ownership.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/transformation/transfer_ownership.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -34,7 +34,7 @@ Lets say that you need to expose "do_smth" function. According to the FAQ, you have to create small wrapper, which will take ``std::auto_ptr`` as an argument. -Next `Py++`_ code does it for you: +The following `Py++`_ code does it for you: .. code-block:: Python Modified: pyplusplus_dev/docs/documentation/functions/transformation/transformation.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/transformation/transformation.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/functions/transformation/transformation.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -65,7 +65,7 @@ mb = module_builder.module_builder_t( ... ) get_size = mb.mem_fun( 'image_t::get_size' ) get_size.add_transformation( FT.output(0), FT.output(1) ) - #Next line has same effect + #the following line has same effect get_size.add_transformation( FT.output('width'), FT.output('height') ) `Py++`_ will generate a code, very similar to one found in Modified: pyplusplus_dev/docs/documentation/how_to/absolute_relative_paths.rest =================================================================== --- pyplusplus_dev/docs/documentation/how_to/absolute_relative_paths.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/how_to/absolute_relative_paths.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -4,8 +4,7 @@ **Absolute\\relative paths** -Consider next fileers, the average number of characters per line is -less than 2. Please cs layout: +Consider the following layout: :: boost/ Modified: pyplusplus_dev/docs/documentation/how_to/best_practices.rest =================================================================== --- pyplusplus_dev/docs/documentation/how_to/best_practices.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/how_to/best_practices.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -58,7 +58,7 @@ come to conclusion, that in order to improve compilation speed, user should be able to control( to be able to generate ) precompiled header file. He implemented an initial version of the functionality. After small discussion, - we agreed on next interface: + we agreed on the following interface: .. code-block:: Python @@ -86,7 +86,7 @@ * **Caveats** - Consider next file layout: + Consider the following file layout: :: boost/ @@ -101,7 +101,7 @@ .. code-block:: Python - #Next code will expose nothing + #the following code will expose nothing mb = module_builder( [ 'date_time/date_time.hpp' ], ... ) #while this one will work as expected Modified: pyplusplus_dev/docs/documentation/how_to/file_name_too_long.rest =================================================================== --- pyplusplus_dev/docs/documentation/how_to/file_name_too_long.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/how_to/file_name_too_long.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -34,7 +34,7 @@ mb = module_builder_t( ... ) holder = mb.class_( 'holder< int >' ) holder.alias = 'IntHolder' - #next line has same effect as the previous one: + #the following line has same effect as the previous one: holder.rename( 'IntHolder' ) Another solution to the problem, is to use different strategy to split the generated Modified: pyplusplus_dev/docs/documentation/how_to/templates.rest =================================================================== --- pyplusplus_dev/docs/documentation/how_to/templates.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/how_to/templates.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -8,7 +8,7 @@ Introduction ------------ -I would like to introduce next piece of code I will use for most exlanations. +I would like to introduce the following piece of code. I am going to use it for most exlanations. .. code-block:: C++ Modified: pyplusplus_dev/docs/documentation/inserting_code.rest =================================================================== --- pyplusplus_dev/docs/documentation/inserting_code.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/inserting_code.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -16,7 +16,7 @@ Insert code to module --------------------- -Almost every ``Boost.Python`` module has next structure: +Almost every ``Boost.Python`` module has the following structure: .. code-block:: C++ @@ -58,7 +58,7 @@ -------------------- ``class_t`` declaration defines few methods, which add user code to the generated one. -Lets take a look on next use case: +Lets take a look on the following use case: .. code-block:: C++ @@ -119,7 +119,7 @@ win = window_t( ) height, width = win.get_size() - If you will pass ``works_on_instance=False`` next code will be generated: + If you will pass ``works_on_instance=False`` the following code will be generated: .. code-block:: C++ @@ -153,13 +153,13 @@ ---------------------------- There are use cases, when you have to add code to `class wrapper`_. Please take a -look on next thread: http://mail.python.org/pipermail/c++-sig/2006-June/010791.html . +look on the following thread: http://mail.python.org/pipermail/c++-sig/2006-June/010791.html . .. _`class wrapper` : http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions -The short description is next: there are classes with parent/child relationship. +The short description is the following: there are classes with parent/child relationship. Parent keeps child class instances using raw pointer. When parent die, it also destroys children classes. It is not an option to switch to ``boost::shared_ptr``. Modified: pyplusplus_dev/docs/documentation/multi_module_development.rest =================================================================== --- pyplusplus_dev/docs/documentation/multi_module_development.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/multi_module_development.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -70,7 +70,7 @@ mb_core.build_code_creator( 'png' ) mb.write_module( 'png.cpp' ) -`Py++`_ will generate code very similar to the next one: +`Py++`_ will generate code very similar to the the following one: .. code-block:: C++ Modified: pyplusplus_dev/docs/documentation/properties.rest =================================================================== --- pyplusplus_dev/docs/documentation/properties.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/properties.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -61,7 +61,7 @@ Call policies ------------- -Consider next use case: +Consider the following use case: .. code-block:: C++ @@ -144,7 +144,7 @@ accessors, which constructs the property. `Py++`_ does it by analyzing name and type of the accessors. -`Py++`_ understands next coding conventions: +`Py++`_ understands the following coding conventions: * lowercase_with_underscores * UpperCamel Modified: pyplusplus_dev/docs/documentation/split_module.rest =================================================================== --- pyplusplus_dev/docs/documentation/split_module.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/split_module.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -50,7 +50,7 @@ as follows: * every class has it's own source & header file -* next declarations are split to separate source files: +* the following declarations are split to separate source files: * named & unnamed enumerations @@ -102,10 +102,10 @@ This mode solves the problem, I mentioned earlier - you have to expose huge class and you have problems to compile generated code. -`Py++`_ will split huge class to files using next strategy: +`Py++`_ will split huge class to files using the following strategy: * every generated source file can contain maximum 20 exposed declarations -* next declarations are split to separate source files: +* the following declarations are split to separate source files: * enumerations Modified: pyplusplus_dev/docs/documentation/warnings.rest =================================================================== --- pyplusplus_dev/docs/documentation/warnings.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/documentation/warnings.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -159,7 +159,7 @@ The `Py++`_ package defines all loggers in the ``pyplusplus._logging_`` package. Both packages define a ``loggers`` class. Those classes keep references to - different loggers. The ``loggers`` classes look very similar to the next class: + different loggers. The ``loggers`` classes look very similar to the following class: .. code-block:: Python Modified: pyplusplus_dev/docs/download.rest =================================================================== --- pyplusplus_dev/docs/download.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/download.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -32,7 +32,7 @@ ------------ In command prompt or shell change current directory to be "pyplusplus-X.Y.Z". -"X.Y.Z" is version of `Py++`_. Type next command: +"X.Y.Z" is version of `Py++`_. Type the following command: | ``python setup.py install`` Modified: pyplusplus_dev/docs/examples/boost/boost.rest =================================================================== --- pyplusplus_dev/docs/examples/boost/boost.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/examples/boost/boost.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -37,7 +37,7 @@ I believe that `Py++`_ is ready for hard work. It is quick, stable and flexible. `Py++`_ is a new tool and in my opinion I should prove its -usefulness. Using `Py++`_, I exposed next libraries to Python: +usefulness. Using `Py++`_, I exposed the following libraries to Python: * `Boost.Date_Time`_ * `Boost.CRC`_ Modified: pyplusplus_dev/docs/history/history.rest =================================================================== --- pyplusplus_dev/docs/history/history.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/history/history.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -61,7 +61,7 @@ **Keep reading.** If you use "function transformation" functionality, than it is possible the - generated code will **NOT** work. Consider next example: + generated code will **NOT** work. Consider the following example: .. code-block:: C++ @@ -466,7 +466,7 @@ Sorry for the inconvenience :-(. -3. Better split of extension module to files. From now next declarations will +3. Better split of extension module to files. From now the following declarations will have dedicated file: * named enumerations, defined within namespace Modified: pyplusplus_dev/docs/peps/dsl_challenge.rest =================================================================== --- pyplusplus_dev/docs/peps/dsl_challenge.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/peps/dsl_challenge.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -14,7 +14,7 @@ Py++ user interface ------------------- -I will use next C++ code as an example: +I will use the following C++ code as an example: .. code-block:: C++ @@ -39,7 +39,7 @@ 3. to rename ``x`` and ``y`` to ``X`` and ``Y`` -Today, in order to configure this class, the user has to write next code: +Today, in order to configure this class, the user has to write the following code: .. code-block:: Python @@ -117,7 +117,7 @@ PointTmpl = mb.module.template('Point') Point = PointTmpl( 'int' ) - This is a trivial example, which is why it looks grate. Consider next class: + This is a trivial example, which is why it looks grate. Consider the following class: .. code-block:: C++ @@ -163,7 +163,7 @@ --------- Using B-API the user is forced to write full declaration name, otherwise he faces -next problem: +the following problem: .. code-block:: Python Modified: pyplusplus_dev/docs/pyplusplus.rest =================================================================== --- pyplusplus_dev/docs/pyplusplus.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/pyplusplus.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -23,7 +23,7 @@ `Boost.Python`_ library allows you to expose C++ code to `Python`_ in quick and elegant way. Code generation process, using Py++ consists from few steps. -Next paragraphs will tell you more about every step. +The following paragraphs will tell you more about every step. *"read declarations"* Modified: pyplusplus_dev/docs/quotes.rest =================================================================== --- pyplusplus_dev/docs/quotes.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/quotes.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -134,7 +134,7 @@ .. _`pythonOCC` : http://www.minerva-plm.org/pythonOCC/ .. _`OpenCascade` : http://www.opencascade.org/ -* I am :-). I created Python bindings for next libraries: +* I am :-). I created Python bindings for the following libraries: * `Boost.Date_Time`_ * `Boost.CRC`_ Modified: pyplusplus_dev/docs/troubleshooting_guide/easy_extending_guide/easy_extending_guide.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/easy_extending_guide/easy_extending_guide.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/troubleshooting_guide/easy_extending_guide/easy_extending_guide.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -36,7 +36,7 @@ Boost.Python doesn't handle ``C arrays``, the only exception are ``char*`` and ``wchar_t*``. -Consider next function: +Consider the following function: .. code-block:: C++ Modified: pyplusplus_dev/docs/troubleshooting_guide/exceptions/exceptions.rest =================================================================== --- pyplusplus_dev/docs/troubleshooting_guide/exceptions/exceptions.rest 2008-08-13 19:45:24 UTC (rev 1392) +++ pyplusplus_dev/docs/troubleshooting_guide/exceptions/exceptions.rest 2008-08-14 07:31:30 UTC (rev 1393) @@ -32,7 +32,7 @@ add a missing functionality to Boost.Python library. Well, I quickly found out that the task is not a trivial one. -The next solution, I thought about, was to expose the exception class as-is and +The following solution, I thought about, was to expose the exception class as-is and to define new class in Python, which derives from it and the built-in ``Exception``. I implemented it and when I run the code I've got ``TypeError``: "Error when calling the metaclass bases multiple bases have instance lay-out conflict". This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-13 19:45:24
|
Revision: 1392 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1392&view=rev Author: roman_yakovenko Date: 2008-08-13 19:45:24 +0000 (Wed, 13 Aug 2008) Log Message: ----------- adding make_constructor functionality 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/module_creator/creator.py pyplusplus_dev/unittests/test_all.py Added Paths: ----------- pyplusplus_dev/unittests/cp_return_addressof_tester.py pyplusplus_dev/unittests/data/cp_return_addressof_to_be_exported.hpp pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp pyplusplus_dev/unittests/make_constructor_tester.py Property Changed: ---------------- pyplusplus_dev/unittests/data/ Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-08-12 04:30:53 UTC (rev 1391) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -44,6 +44,7 @@ from calldef import free_function_t from calldef import mem_fun_t +from calldef import make_constructor_t from calldef import mem_fun_pv_t from calldef import mem_fun_pv_wrapper_t Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-08-12 04:30:53 UTC (rev 1391) +++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -51,10 +51,12 @@ arg_utils = calldef_utils.argument_utils_t( self.declaration, algorithm.make_id_creator( self ) ) return arg_utils.keywords_args() - def create_call_policies( self ): - if self.declaration.call_policies.is_default(): + def create_call_policies( self, default_generates_code_too=False ): + if False == default_generates_code_too \ + and self.declaration.call_policies.is_default(): return '' - return self.declaration.call_policies.create( self ) + else: + return self.declaration.call_policies.create( self ) def create_def_code( self ): if not self.works_on_instance: @@ -221,6 +223,81 @@ else: return '&%s' % fname +class make_constructor_t( calldef_t ): + def __init__( self, function ): + calldef_t.__init__( self, function=function ) + + def make_cnstr_identifier( self ): + return algorithm.create_identifier( self, '::boost::python::make_constructor' ) + + def create_function_type_alias_code( self, exported_class_alias=None ): + ftype = self.declaration.function_type() + return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias, with_defaults=False ) + + def create_function_ref_code(self, use_function_alias=False): + fname = declarations.full_name( self.declaration, with_defaults=False ) + if use_function_alias: + return '%s( &%s )' % ( self.function_type_alias, fname ) + elif self.declaration.create_with_signature: + return '(%s)( &%s )' % ( self.declaration.function_type().partial_decl_string, fname ) + else: + return '&%s' % fname + + def _create_impl( self ): + if self.declaration.already_exposed: + return '' + + result = [] + + if not self.works_on_instance: + result.append( self.create_function_type_alias_code() ) + result.append( os.linesep * 2 ) + + result.append( self.create_def_code() + '( ' ) + result.append( os.linesep + self.indent( '"__init__"' ) ) + + result.append( self.param_sep() ) + result.append( self.make_cnstr_identifier() + '( ') + result.append( self.create_function_ref_code( not self.works_on_instance ) ) + + keywd_args = None + if self.declaration.use_keywords: + keywd_args = self.create_keywords_args() + + if self.declaration.call_policies: + default_generates_code_too = bool( keywd_args ) + c_p_code = self.create_call_policies( default_generates_code_too ) + if c_p_code: + result.append( self.indent( self.param_sep(), 3 ) ) + result.append( c_p_code ) + + if keywd_args: + result.append( self.indent( self.param_sep(), 3 ) ) + result.append( keywd_args ) + + result.append( ' )' ) #make_constructor + + doc = self.create_doc() + if doc: + result.append( self.param_sep() ) + result.append( doc ) + + result.append( ' )' ) + if not self.works_on_instance: + result.append( ';' ) + + if not self.works_on_instance: + #indenting and adding scope + code = ''.join( result ) + result = [ '{ //%s' % declarations.full_name( self.declaration, with_defaults=False ) ] + result.append( os.linesep * 2 ) + result.append( self.indent( code ) ) + result.append( os.linesep * 2 ) + result.append( '}' ) + + return ''.join( result ) + + class mem_fun_pv_t( calldef_t ): def __init__( self, function, wrapper ): calldef_t.__init__( self, function=function, wrapper=wrapper ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-08-12 04:30:53 UTC (rev 1391) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -192,6 +192,23 @@ self._exposed_class_type = self.EXPOSED_CLASS_TYPE.DECLARED self._expose_this = None self._expose_sizeof = None + self._fake_constructors = [] + + @property + def fake_constructors(self): + """list of fake constructors""" + return self._fake_constructors + + def add_fake_constructors( self, f ): + """f - reference to a calldef_t object or list of them + + boost::python::make_constructor allows to register a C++ function, as a + class constructor. + """ + if isinstance( f, declarations.calldef_t ): + self._fake_constructors.add( f ) + else: + self._fake_constructors.extend( f ) def _get_redefine_operators( self ): return self._redefine_operators Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-12 04:30:53 UTC (rev 1391) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -78,8 +78,9 @@ self.__types_db = types_db if not self.__types_db: self.__types_db = types_database.types_database_t() - - self.__extmodule = code_creators.module_t( declarations.get_global_namespace(decls) ) + + global_ns = declarations.get_global_namespace(decls) + self.__extmodule = code_creators.module_t( global_ns ) if boost_python_ns_name: bp_ns_alias = code_creators.namespace_alias_t( alias=boost_python_ns_name , full_namespace_name='::boost::python' ) @@ -100,8 +101,10 @@ self.__array_1_registered = set() #(type.decl_string,size) self.__free_operators = [] self.__exposed_free_fun_overloads = set() + self.__fake_constructors = set() + for cls in global_ns.classes(recursive=True, allow_empty=True): + self.__fake_constructors.update( cls.fake_constructors ) - def __print_readme( self, decl ): readme = decl.readme() if not readme: @@ -347,9 +350,13 @@ return self.__extmodule def visit_member_function( self ): - fwrapper = None self.__types_db.update( self.curr_decl ) self.__dependencies_manager.add_exported( self.curr_decl ) + + if self.curr_decl in self.__fake_constructors: + return + + fwrapper = None if None is self.curr_decl.call_policies: self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl ) @@ -453,6 +460,12 @@ def visit_free_function( self ): if self.curr_decl in self.__exposed_free_fun_overloads: return + + if self.curr_decl in self.__fake_constructors: + self.__types_db.update( self.curr_decl ) + self.__dependencies_manager.add_exported( self.curr_decl ) + return + elif self.curr_decl.use_overload_macro: parent_decl = self.curr_decl.parent names = set( map( lambda decl: decl.name @@ -595,6 +608,9 @@ if cls_decl.expose_sizeof: cls_cc.adopt_creator( code_creators.expose_sizeof_t( cls_decl ) ) + for fc in cls_decl.fake_constructors: + cls_cc.adopt_creator( code_creators.make_constructor_t( fc ) ) + for decl in exportable_members: if decl in exposed: continue Added: pyplusplus_dev/unittests/cp_return_addressof_tester.py =================================================================== --- pyplusplus_dev/unittests/cp_return_addressof_tester.py (rev 0) +++ pyplusplus_dev/unittests/cp_return_addressof_tester.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -0,0 +1,42 @@ +# 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 ctypes +import unittest +import fundamental_tester_base +from pyplusplus.module_builder import call_policies + +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'cp_return_addressof' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def customize(self, mb ): + mb.classes().always_expose_using_scope = True + mb.calldef( 'get_buffer' ).call_policies \ + = call_policies.return_value_policy( call_policies.return_addressof ) + + def run_tests(self, module): + image = module.image_t() + buffer_type = ctypes.c_int * 5 + buffer = buffer_type.from_address( image.get_buffer() ) + self.failUnless( [0,1,2,3,4] == list( buffer ) ) + +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() Property changes on: pyplusplus_dev/unittests/data ___________________________________________________________________ Modified: svn:ignore - *.obj call_policies_to_be_exported.os global_variables_to_be_exported.os member_functions_to_be_exported.os + *.obj call_policies_to_be_exported.os global_variables_to_be_exported.os member_functions_to_be_exported.os cache duplicate_aliases_to_be_exported.os factory_to_be_exported.os member_variables_to_be_exported.os non_overridable_to_be_exported.os particleuniverse.xml smart_pointers_to_be_exported.os split_module_bug_to_be_exported.os statics_to_be_exported.os throw_to_be_exported.os vector3_to_be_exported.os vector_with_shared_data_to_be_exported.os Added: pyplusplus_dev/unittests/data/cp_return_addressof_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/cp_return_addressof_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/cp_return_addressof_to_be_exported.hpp 2008-08-13 19:45:24 UTC (rev 1392) @@ -0,0 +1,28 @@ +// 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 __cp_return_addressof_to_be_exported_hpp__ +#define __cp_return_addressof_to_be_exported_hpp__ + +#include <string> + +struct image_t{ + image_t() + : buffer( new int[5] ) + { + for( int i = 0; i < 5; ++i ){ + buffer[i] = i; + } + } + + ~image_t(){ delete[] buffer; } + + int* get_buffer() const { return buffer; } + +private: + int* buffer; +}; + +#endif//__cp_return_addressof_to_be_exported_hpp__ Added: pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/make_constructor_to_be_exported.hpp 2008-08-13 19:45:24 UTC (rev 1392) @@ -0,0 +1,40 @@ +// 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 __make_constructor_to_be_exported_hpp__ +#define __make_constructor_to_be_exported_hpp__ + +#include <memory> + +namespace mc{ + +struct numbers_t{ + numbers_t() + : x( 0 ) + , y( 0 ) + {} + ~numbers_t(){} + + static std::auto_ptr<numbers_t> create( int i, int j, int k, int m ){ + std::auto_ptr<numbers_t> n( new numbers_t() ); + n->x = i + j; + n->y = k + m; + return n; + } + + int x; + int y; +}; + +inline std::auto_ptr<numbers_t> create( int i, int j){ + std::auto_ptr<numbers_t> n( new numbers_t() ); + n->x = i; + n->y = j; + return n; +} + +} + +#endif//__make_constructor_to_be_exported_hpp__ Added: pyplusplus_dev/unittests/make_constructor_tester.py =================================================================== --- pyplusplus_dev/unittests/make_constructor_tester.py (rev 0) +++ pyplusplus_dev/unittests/make_constructor_tester.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -0,0 +1,41 @@ +# 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 + +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'make_constructor' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def customize(self, mb ): + mc = mb.namespace( 'mc' ) + numbers = mc.class_( 'numbers_t' ) + numbers.add_fake_constructors( mc.calldefs( 'create' ) ) + + + def run_tests(self, module): + n = module.numbers_t( 1,2,3,4) + self.failUnless( n.x == 1+2 and n.y == 3+4) + n = module.numbers_t( 10, 18) + self.failUnless( n.x == 10 and n.y == 18) + +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-08-12 04:30:53 UTC (rev 1391) +++ pyplusplus_dev/unittests/test_all.py 2008-08-13 19:45:24 UTC (rev 1392) @@ -107,6 +107,7 @@ import embeded_tester import unions_tester import cp_return_addressof_tester +import make_constructor_tester #import ogre_generate_tester testers = [ @@ -202,6 +203,7 @@ , embeded_tester , unions_tester , cp_return_addressof_tester + , make_constructor_tester # , ogre_generate_tester too much time ] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-12 04:30:43
|
Revision: 1391 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1391&view=rev Author: roman_yakovenko Date: 2008-08-12 04:30:53 +0000 (Tue, 12 Aug 2008) Log Message: ----------- adding new use-case Modified Paths: -------------- pyplusplus_dev/unittests/data/indexing_suites_to_be_exported.hpp Modified: pyplusplus_dev/unittests/data/indexing_suites_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/indexing_suites_to_be_exported.hpp 2008-08-09 11:25:14 UTC (rev 1390) +++ pyplusplus_dev/unittests/data/indexing_suites_to_be_exported.hpp 2008-08-12 04:30:53 UTC (rev 1391) @@ -1,20 +1,20 @@ -// 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 __indexing_suites_to_be_exported_hpp__ -#define __indexing_suites_to_be_exported_hpp__ +// 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 __indexing_suites_to_be_exported_hpp__ +#define __indexing_suites_to_be_exported_hpp__ + #include <vector> -#include <string> - -namespace indexing_suites { - -typedef std::vector< std::string > strings_t; - -inline void do_nothing( const strings_t& ){} +#include <string> +namespace indexing_suites { + +typedef std::vector< std::string > strings_t; + +inline void do_nothing( const strings_t& ){} + struct item_t{ item_t() : value( -1 ){} @@ -27,23 +27,29 @@ } int value; -}; +}; - -typedef std::vector<item_t> items_t; +typedef std::vector<item_t> items_t; + +typedef std::vector<item_t*> items_ptr_t; + inline item_t get_value( const std::vector<item_t>& vec, unsigned int index ){ return vec.at(index); } +inline item_t get_ptr_value( const std::vector<item_t*>& vec, unsigned int index ){ + return *vec.at(index); +} + inline void set_value( std::vector<item_t>& vec, unsigned int index, item_t value ){ vec.at(index); vec[index] = value; } - -typedef std::vector<int> ivector; -ivector empty_ivector(){ return ivector(); } - -} - -#endif//__indexing_suites_to_be_exported_hpp__ + +typedef std::vector<int> ivector; +ivector empty_ivector(){ return ivector(); } + +} + +#endif//__indexing_suites_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-08-09 11:25:05
|
Revision: 1390 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1390&view=rev Author: roman_yakovenko Date: 2008-08-09 11:25:14 +0000 (Sat, 09 Aug 2008) Log Message: ----------- adding get_named_parent algorithm Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/__init__.py pygccxml_dev/pygccxml/declarations/algorithm.py Modified: pygccxml_dev/pygccxml/declarations/__init__.py =================================================================== --- pygccxml_dev/pygccxml/declarations/__init__.py 2008-08-09 08:44:35 UTC (rev 1389) +++ pygccxml_dev/pygccxml/declarations/__init__.py 2008-08-09 11:25:14 UTC (rev 1390) @@ -81,6 +81,7 @@ from algorithm import make_flatten from algorithm import apply_visitor from algorithm import declaration_path +from algorithm import get_named_parent from algorithm import find_declaration from algorithm import match_declaration_t from algorithm import find_all_declarations Modified: pygccxml_dev/pygccxml/declarations/algorithm.py =================================================================== --- pygccxml_dev/pygccxml/declarations/algorithm.py 2008-08-09 08:44:35 UTC (rev 1389) +++ pygccxml_dev/pygccxml/declarations/algorithm.py 2008-08-09 11:25:14 UTC (rev 1390) @@ -70,9 +70,27 @@ else: return decl.cache.partial_declaration_path +def get_named_parent( decl ): + """ + returns a reference to a named parent declaration + + @param decl: the child declaration + @type decl: L{declaration_t} + + @return: reference to L{declaration_t} or None if not found + """ + if not decl: + return None + + parent = decl.parent + while parent and ( not parent.name or parent.name == '::' ): + parent = parent.parent + return parent + + def full_name_from_declaration_path( dpath ): ##Here I have lack of knowledge: - ##TODO: "What is the full name of declaration declared in unnamed namespace?" + ##TODO: "What is the full name of declaration declared in unnamed namespace?" result = filter( None, dpath ) result = result[0] + '::'.join( result[1:] ) return result @@ -98,7 +116,7 @@ decl.cache.full_partial_name \ = full_name_from_declaration_path( partial_declaration_path( decl ) ) return decl.cache.full_partial_name - + def make_flatten( decl_or_decls ): """ converts tree representation of declarations to flatten one. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-09 08:44:25
|
Revision: 1389 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1389&view=rev Author: roman_yakovenko Date: 2008-08-09 08:44:35 +0000 (Sat, 09 Aug 2008) Log Message: ----------- testing cool feature Modified Paths: -------------- pyplusplus_dev/unittests/unions_tester.py Modified: pyplusplus_dev/unittests/unions_tester.py =================================================================== --- pyplusplus_dev/unittests/unions_tester.py 2008-08-08 17:44:27 UTC (rev 1388) +++ pyplusplus_dev/unittests/unions_tester.py 2008-08-09 08:44:35 UTC (rev 1389) @@ -5,6 +5,7 @@ import os import sys +import pdb import ctypes import unittest import fundamental_tester_base @@ -22,6 +23,9 @@ , tester_t.EXTENSION_NAME , *args ) + def customize(self, mb): + mb.add_declaration_code('extern "C"{ int mmm( int i, int j ){ return i + j; } }' ) + def run_tests(self, module): obj = module.data_t() actual_data = actual_data_t.from_address( obj.data ) @@ -40,6 +44,8 @@ obj2.set_i( 1977 ) self.failUnless( obj2.i == 1977 ) + mdll = ctypes.cdll.LoadLibrary( module.__file__ ) + self.failUnless( 4 == mdll.mmm( 1, 3 ) ) def create_suite(): suite = unittest.TestSuite() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-08 17:44:24
|
Revision: 1388 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1388&view=rev Author: roman_yakovenko Date: 2008-08-08 17:44:27 +0000 (Fri, 08 Aug 2008) Log Message: ----------- adding sizeof and some documentation Modified Paths: -------------- pyplusplus_dev/docs/documentation/functions/call_policies.rest pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/ctypes_integration_creators.py pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/classes_tester.py pyplusplus_dev/unittests/data/classes_to_be_exported.hpp Added Paths: ----------- pyplusplus_dev/docs/documentation/ctypes/ctypes_integration.rest pyplusplus_dev/docs/documentation/ctypes/this_and_sizeof.rest pyplusplus_dev/docs/documentation/ctypes/unions.rest pyplusplus_dev/docs/documentation/ctypes/variables.rest pyplusplus_dev/docs/documentation/ctypes/www_configuration.py Added: pyplusplus_dev/docs/documentation/ctypes/ctypes_integration.rest =================================================================== --- pyplusplus_dev/docs/documentation/ctypes/ctypes_integration.rest (rev 0) +++ pyplusplus_dev/docs/documentation/ctypes/ctypes_integration.rest 2008-08-08 17:44:27 UTC (rev 1388) @@ -0,0 +1,94 @@ +================== +ctypes integration +================== + +.. contents:: Table of contents + +------------ +Introduction +------------ + +`Boost.Python`_ is really a very powerful library, but if you are working +with code written in plain "C" - you've got a problem. You have to create +wrappers for almost every function or variable. + +In general, if you want to work with plain "C" code from `Python`_ +you don't have to create any wrapper - you can use `ctypes`_ package. + +About ctypes +------------ +`ctypes`_ is a foreign function library for Python. It provides C +compatible data types, and allows to call functions in dlls/shared +libraries. It can be used to wrap these libraries in pure Python. + + +-------- +The idea +-------- + +The idea behind "ctypes integration" functionality is really simple: you +configure `Py++`_ to expose address of the variable\\return value, and than you +you use `ctypes`_ `from_address`_ functionality to access and modify the data. + +Obviously, this approach has pros and cons: + +* cons - it could be very dangerous - you can corrupt your application memory + +* cons - managing memory is not something a typical `Python`_ user get used to. + It is too "low level". + +* pros - you don't need to create wrapper in C++ + +* pros - a Python user has access to the data + +* pros - compilation time is smaller + +* pros - you still can create wrapper, but using `Python`_ + + +In my opinion, the better way to go is to "mix": + +1. expose your native code using `Boost.Python`_ and "ctypes integration" + functionality - it is easy and cheap + +2. use `ctypes`_ module to access your data + +3. create high level API in Python: the wrappers, which will ensure the + constraints and will provide more "natural" interface + +------------------------- +Implemented functionality +------------------------- + +`Py++`_ is able to + +* expose global and member variable address + +* expose "this" pointer value + +* expose a class "sizeof" + +* expose variable, which has a union type + +* return address of return value as integer - `new call policy was created`_ + +----------------- +Future directions +----------------- + +The functionality is going to be developed father and I intend to add +next features: + +* to port this functionality to 64bit systems + +* to add ability to expose "C" functions without using `Boost.Python`_. + +.. _`new call policy was created` : ./../../documentation/functions/call_policies.html#return-addressof +.. _`ctypes` : http://docs.python.org/lib/module-ctypes.html +.. _`from_address` : http://docs.python.org/lib/ctypes-data-types.html +.. _`Py++` : ./../../pyplusplus.html +.. _`pygccxml` : ./../../../pygccxml/pygccxml.html +.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + Added: pyplusplus_dev/docs/documentation/ctypes/this_and_sizeof.rest =================================================================== --- pyplusplus_dev/docs/documentation/ctypes/this_and_sizeof.rest (rev 0) +++ pyplusplus_dev/docs/documentation/ctypes/this_and_sizeof.rest 2008-08-08 17:44:27 UTC (rev 1388) @@ -0,0 +1,47 @@ +============= +this & sizeof +============= + +.. contents:: Table of contents + +----------- +The purpose +----------- + +`Py++`_ can expose a class ``sizeof`` and ``this`` pointer value to `Python`_. +I created this functionality without special purpose in mind. + +------- +Example +------- + + .. code-block:: Python + + mb = module_builder_t( ... ) + cls = mb.class_( <your class> ) + cls.expose_this = True + cls.expose_sizeof = True + +The `Python`_ class will contain two properties ``this`` and ``sizeof``. The usage +is pretty simple: + + .. code-block:: Python + + import ctypes + import <your module> import <your class> as data_t + + d = data_t() + print d.this + print d.sizeof + + +Warning: I hope you know what you are doing, otherwise don't blame me :-) + +.. _`ctypes` : http://docs.python.org/lib/module-ctypes.html +.. _`from_address` : http://docs.python.org/lib/ctypes-data-types.html +.. _`Py++` : ./../../pyplusplus.html +.. _`pygccxml` : ./../../../pygccxml/pygccxml.html +.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + Added: pyplusplus_dev/docs/documentation/ctypes/unions.rest =================================================================== --- pyplusplus_dev/docs/documentation/ctypes/unions.rest (rev 0) +++ pyplusplus_dev/docs/documentation/ctypes/unions.rest 2008-08-08 17:44:27 UTC (rev 1388) @@ -0,0 +1,75 @@ +========= +C++ union +========= + +.. contents:: Table of contents + +------------ +Introduction +------------ + +`Boost.Python`_ does not help you to expose a variable, which has a union type. +In this document, I am going to show you a complete example how to get access +to the data, stored in the variable. + +`Py++`_ will not expose a union - it is impossible using `Boost.Python`_, +instead it will expose the address of the variable and the rest is done from the +`Python`_ using `ctypes`_ package. + +-------- +Example +-------- + +For this example I am going to use next code: + + .. code-block:: C++ + + struct data_t{ + union actual_data_t{ + int i; + double d; + }; + actual_data_t data; + }; + +As in many other cases, `Py++`_ does the job automatically: + + .. code-block:: Python + + mb = module_builder_t( ... ) + mb.class_( 'data_t' ).include() + +no special code, to achieve the desired result, was written. + +The generated code is boring, so I will skip it and will continue to the usage +example: + + .. code-block:: Python + + import ctypes + import <your module> import data_t + + #lets define our union + class actual_data_t( ctypes.Union ): + _fields_ = [( "i", ctypes.c_int ), ( 'd', ctypes.c_double )] + + obj = data_t() + actual_data = actual_data_t.from_address( obj.data ) + #you can set\get data + actual_data.i = 18 + prit actual_data.i + actual_data.d = 12.12 + print actual_data.d + +That's all. Everything should work fine. You can add few getters and setters to +class ``data_t``, so you could verify the results. I did this for a tester, that +checks this functionality. + +.. _`ctypes` : http://docs.python.org/lib/module-ctypes.html +.. _`from_address` : http://docs.python.org/lib/ctypes-data-types.html +.. _`Py++` : ./../../pyplusplus.html +.. _`pygccxml` : ./../../../pygccxml/pygccxml.html +.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + Added: pyplusplus_dev/docs/documentation/ctypes/variables.rest =================================================================== --- pyplusplus_dev/docs/documentation/ctypes/variables.rest (rev 0) +++ pyplusplus_dev/docs/documentation/ctypes/variables.rest 2008-08-08 17:44:27 UTC (rev 1388) @@ -0,0 +1,78 @@ +========= +Variables +========= + +.. contents:: Table of contents + +-------------- +expose_address +-------------- + +``variable_t`` declarations have got new property ``expose_address``. If you set +it value to ``True``, `Py++`_ will register new property with the same name, but +the type of it will be ``unsigned int`` and the value is address of the variable. + +`Py++`_ will take care and generate the right code for global, static and member +variables. + +---------------- +Show me the code +---------------- + +Lets say you have the following C++ code: + + .. code-block:: C++ + + struct bytes_t{ + bytes_t(){ + data = new int[5]; + for(int i=0; i<5; i++){ + data[i] = i; + } + } + ... + int* data; + static int* x; + }; + + //somewhere in a cpp file + int* bytes_t::x = new int( 1997 ); + +In order to get access to the ``bytes_t::data`` and ``bytes_t::x`` you +have to turn on ``expose_address`` property to ``True``: + + .. code-block:: Python + + mb = module_builder_t( ... ) + bytes = mb.class_( 'bytes_t' ) + bytes.vars().expose_address = True + +`Py++`_ will generate code, which will expose the address of the variables. + +and now it is a time to show some `ctypes`_ magic: + + .. code-block:: Python + + import ctypes + import your_module as m + + bytes = m.bytes_t() + + data_type = ctypes.POINTER( ctypes.c_int ) + data = data_type.from_address( bytes.data ) + for j in range(5): + print '%d : %d' % ( j, data[j] ) + + data_type = ctypes.POINTER( ctypes.c_int ) + data = data_type.from_address( m.bytes_t.x ) + print x.contents.value + + +.. _`ctypes` : http://docs.python.org/lib/module-ctypes.html +.. _`from_address` : http://docs.python.org/lib/ctypes-data-types.html +.. _`Py++` : ./../../pyplusplus.html +.. _`pygccxml` : ./../../../pygccxml/pygccxml.html +.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html +.. _`Python`: http://www.python.org +.. _`GCC-XML`: http://www.gccxml.org + Added: pyplusplus_dev/docs/documentation/ctypes/www_configuration.py =================================================================== --- pyplusplus_dev/docs/documentation/ctypes/www_configuration.py (rev 0) +++ pyplusplus_dev/docs/documentation/ctypes/www_configuration.py 2008-08-08 17:44:27 UTC (rev 1388) @@ -0,0 +1,6 @@ +name = 'ctypes integration' +main_html_file = 'ctypes_integration.html' + +names = { 'ctypes_integration' : 'ctypes integration' + , 'this_and_sizeof' : 'this & sizeof'} + Modified: pyplusplus_dev/docs/documentation/functions/call_policies.rest =================================================================== --- pyplusplus_dev/docs/documentation/functions/call_policies.rest 2008-08-08 14:32:06 UTC (rev 1387) +++ pyplusplus_dev/docs/documentation/functions/call_policies.rest 2008-08-08 17:44:27 UTC (rev 1388) @@ -209,6 +209,57 @@ mb.free_function( ... ).call_policies \ = call_policies.custom_call_policies( your call policies code, "xyz.hpp" ) +return_addressof +---------------- + +Class ``return_addressof`` is a model of `ResultConverterGenerator`_ which +can be used to wrap C++ functions returning any pointer, such that the pointer +value is converted to ``unsigned int`` and it is copied into a new Python object. + +This call policy was created to be used with ``ctypes`` package and provide access +to some raw\\low level data, without creating wrappers. + +Pay attention: you have to manage the memory by your own. + +Example +~~~~~~~ + +.. code-block:: C++ + + int* get_value(){ + static int buffer[] = { 0,1,2,3,4 }; + return buffer; + } + + namespace bpl = boost::python; + BOOST_PYTHON_MODULE(my_module){ + def( "get_value" + , bpl::return_value_policy< pyplusplus::call_policies::return_addressof<> >() ); + } + +The `Py++`_ code is not that different from what you already know: + +.. code-block:: Python + + from pyplusplus import module_builder + from pyplusplus.module_builder import call_policies + + mb = module_builder.module_builder_t( ... ) + mb.free_function( return_type='float *' ).call_policies \ + = call_policies.return_value_policy( call_policies.return_addressof ) + +Python code: + +.. code-block:: Python + + import ctypes + import my_module + + buffer_type = ctypes.c_int * 5 + buffer = buffer_type.from_address( my_module.get_value() ) + assert [0,1,2,3,4] == list( buffer ) + + return_pointee_value -------------------- Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-08-08 14:32:06 UTC (rev 1387) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-08-08 17:44:27 UTC (rev 1388) @@ -137,3 +137,4 @@ from properties import property_t from ctypes_integration_creators import expose_this_t +from ctypes_integration_creators import expose_sizeof_t Modified: pyplusplus_dev/pyplusplus/code_creators/ctypes_integration_creators.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/ctypes_integration_creators.py 2008-08-08 14:32:06 UTC (rev 1387) +++ pyplusplus_dev/pyplusplus/code_creators/ctypes_integration_creators.py 2008-08-08 17:44:27 UTC (rev 1388) @@ -37,3 +37,19 @@ def _get_system_headers_impl( self ): return [code_repository.ctypes_integration.file_name] + +class expose_sizeof_t( registration_based.registration_based_t + , declaration_based.declaration_based_t ): + """ + creates code that expose address of the object to Python + """ + + def __init__(self, class_ ): + registration_based.registration_based_t.__init__( self ) + declaration_based.declaration_based_t.__init__( self, declaration=class_) + + def _create_impl(self): + return 'def( pyplus_conv::register_sizeof( boost::type< %s >() ) )' % self.decl_identifier + + def _get_system_headers_impl( self ): + return [code_repository.ctypes_integration.file_name] Modified: pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py 2008-08-08 14:32:06 UTC (rev 1387) +++ pyplusplus_dev/pyplusplus/code_repository/ctypes_integration.py 2008-08-08 17:44:27 UTC (rev 1388) @@ -26,6 +26,7 @@ #include "boost/mpl/vector.hpp" #include "boost/function.hpp" #include "boost/cstdint.hpp" +#include "boost/type.hpp" #include "boost/bind.hpp" @@ -94,6 +95,29 @@ const char* m_name; }; + +class register_sizeof : public boost::python::def_visitor<register_sizeof> +{ + friend class boost::python::def_visitor_access; + +public: + + template< typename TType > + register_sizeof( boost::type< TType > ) + : m_sizeof( sizeof( TType ) ) + {} + + template <class classT> + void visit(classT& c) const{ + boost::python::scope cls_scope( c ); + cls_scope.attr("sizeof") = m_sizeof; + } + +private: + size_t m_sizeof; +}; + + } /*pyplusplus*/ } /*convenience*/ namespace pyplus_conv = pyplusplus::convenience; Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-08-08 14:32:06 UTC (rev 1387) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-08-08 17:44:27 UTC (rev 1388) @@ -191,6 +191,7 @@ self._require_self_reference = False self._exposed_class_type = self.EXPOSED_CLASS_TYPE.DECLARED self._expose_this = None + self._expose_sizeof = None def _get_redefine_operators( self ): return self._redefine_operators @@ -636,6 +637,13 @@ expose_this = property( _get_expose_this, _set_expose_this , doc="boolean, if True an object address( this pointer ) will be exposed to Python as integer.") + def _get_expose_sizeof( self ): + return self._expose_sizeof + def _set_expose_sizeof( self, new_value ): + self._expose_sizeof = new_value + expose_sizeof = property( _get_expose_sizeof, _set_expose_sizeof + , doc="boolean, if True the sizeof(obj) will be exposed to Python as integer.") + @property def introduces_new_scope(self): """returns True, if during exposing this class, new scope will be created Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-08 14:32:06 UTC (rev 1387) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-08 17:44:27 UTC (rev 1388) @@ -592,6 +592,9 @@ if cls_decl.expose_this: cls_cc.adopt_creator( code_creators.expose_this_t( cls_decl ) ) + if cls_decl.expose_sizeof: + cls_cc.adopt_creator( code_creators.expose_sizeof_t( cls_decl ) ) + for decl in exportable_members: if decl in exposed: continue Modified: pyplusplus_dev/unittests/classes_tester.py =================================================================== --- pyplusplus_dev/unittests/classes_tester.py 2008-08-08 14:32:06 UTC (rev 1387) +++ pyplusplus_dev/unittests/classes_tester.py 2008-08-08 17:44:27 UTC (rev 1388) @@ -19,6 +19,7 @@ def customize(self, mb ): mb.classes().expose_this = True + mb.classes().expose_sizeof = True mb.class_( 'fundamental2' ).alias = 'FUNDAMENTAL2' apple = mb.class_( 'apple' ) self.failUnless( apple.alias == 'the_tastest_fruit' ) @@ -53,6 +54,7 @@ self.failUnless( -24 == module.protected_static_t().invert_sign(24) ) self.failUnless( 67 == module.protected_static_t().invert_sign(-67) ) self.failUnless( module.protected_static_t().this ) + self.failUnless( module.protected_static_t().sizeof ) def create_suite(): suite = unittest.TestSuite() Modified: pyplusplus_dev/unittests/data/classes_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/classes_to_be_exported.hpp 2008-08-08 14:32:06 UTC (rev 1387) +++ pyplusplus_dev/unittests/data/classes_to_be_exported.hpp 2008-08-08 17:44:27 UTC (rev 1388) @@ -38,7 +38,7 @@ namespace abstracts{ class abstract{ -public: +public: abstract(){} abstract(int){} abstract(int, double, const abstract&){} @@ -48,13 +48,13 @@ virtual bool overloaded_virtual(){ return true;} virtual bool overloaded_virtual(int){ return true;} - + virtual int overloaded_pure_virtual(int) const = 0; virtual void overloaded_pure_virtual(double) const = 0; - + virtual int some_virtual(){ return 1; } -}; - +}; + } namespace constructors{ @@ -64,11 +64,11 @@ constructor1( const constructor1& ){} constructor1(int x, int y){} constructor1(int y, const constructor1& x ){} - + constructor1( const double ){} struct internal_data{}; constructor1( const internal_data ){} -}; +}; } @@ -76,15 +76,17 @@ struct scope_based_exposer{ enum EColor{ red, green, blue }; scope_based_exposer(EColor c=blue){} -}; +}; } namespace protected_static{ class protected_static_t{ protected: static int identity(int x){ return x; } - + int invert_sign(int x){ return -1*x; } +private: + int i; }; }; @@ -104,15 +106,15 @@ }; }; -}//classes +}//classes namespace pyplusplus{ namespace aliases{ - + typedef classes::hierarchical::apple the_tastest_fruit; - + typedef classes::protected_static::protected_static_t PROTECTED_STATIC_T_1; typedef classes::protected_static::protected_static_t PROTECTED_STATIC_T_2; - + }} #endif//__classes_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-08-08 14:32:00
|
Revision: 1387 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1387&view=rev Author: roman_yakovenko Date: 2008-08-08 14:32:06 +0000 (Fri, 08 Aug 2008) Log Message: ----------- adding new call policy, return_addressof, for better integration with ctypes Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_repository/call_policies.py pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py pyplusplus_dev/pyplusplus/module_builder/call_policies.py pyplusplus_dev/unittests/test_all.py Modified: pyplusplus_dev/pyplusplus/code_repository/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/call_policies.py 2008-08-08 12:18:18 UTC (rev 1386) +++ pyplusplus_dev/pyplusplus/code_repository/call_policies.py 2008-08-08 14:32:06 UTC (rev 1387) @@ -23,10 +23,13 @@ #define call_policies_pyplusplus_hpp__ #include "boost/python.hpp" +#include "boost/cstdint.hpp" #include "boost/mpl/int.hpp" #include "boost/function.hpp" +#include "boost/utility/addressof.hpp" +#include "boost/type_traits/is_same.hpp" #include "boost/python/object/class_detail.hpp" -#include "boost/type_traits/is_same.hpp" + namespace pyplusplus{ namespace call_policies{ namespace bpl = boost::python; @@ -37,19 +40,19 @@ template< typename T> static void deallocate_array(T*){} }; - + struct delete_{ template< typename T> static void deallocate_array(T* arr){ delete[] arr; } - }; - + }; + }/*memory_managers*/ namespace detail{ - + struct make_value_holder{ template <class T> @@ -62,7 +65,6 @@ return bpl::incref( p_value.ptr() ); } } - }; template <class R> @@ -72,25 +74,66 @@ # endif ; +struct make_addressof_holder{ + + template <class T> + static PyObject* execute(T* p){ + if (p == 0){ + return bpl::detail::none(); + } + else{ + boost::uint32_t addressof_p = reinterpret_cast< boost::uint32_t >( p ); + bpl::object p_address( addressof_p ); + return bpl::incref( p_address.ptr() ); + } + } + +}; + +template <class R> +struct return_addressof_value_requires_a_pointer_return_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) +{} +# endif +; + + } //detail struct return_pointee_value{ template <class T> struct apply{ - + BOOST_STATIC_CONSTANT( bool, ok = boost::is_pointer<T>::value ); - + typedef typename boost::mpl::if_c< ok , bpl::to_python_indirect<T, detail::make_value_holder> , detail::return_pointee_value_requires_a_pointer_return_type<T> >::type type; - + }; }; +struct return_addressof{ + + template <class T> + struct apply{ + + BOOST_STATIC_CONSTANT( bool, ok = boost::is_pointer<T>::value ); + + typedef typename boost::mpl::if_c< + ok + , bpl::to_python_indirect<T, detail::make_addressof_holder> + , detail::return_addressof_value_requires_a_pointer_return_type<T> + >::type type; + + }; + +}; + template< typename CallPolicies, class T > bpl::object make_object( T x ){ //constructs object using CallPolicies result_converter @@ -131,7 +174,7 @@ BOOST_STATIC_CONSTANT( bool, ok = boost::is_pointer<T>::value ); typedef details::as_tuple_impl<size, MemoryManager, MakeObjectCallPolicies> type; }; - + }; } /*arrays*/ Modified: pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2008-08-08 12:18:18 UTC (rev 1386) +++ pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2008-08-08 14:32:06 UTC (rev 1387) @@ -60,6 +60,7 @@ from call_policies import return_opaque_pointer from call_policies import return_value_policy from call_policies import return_pointee_value +from call_policies import return_addressof from call_policies import is_return_opaque_pointer_policy from call_policies import custom_call_policies_t from call_policies import custom_call_policies Modified: pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py 2008-08-08 12:18:18 UTC (rev 1386) +++ pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py 2008-08-08 14:32:06 UTC (rev 1387) @@ -195,7 +195,7 @@ return [ str( self.custodian ), str( self.ward ) ] def with_custodian_and_ward( custodian, ward, base=None): - """create boost::python::with_custodian_and_ward call policies code generator""" + """create boost::python::with_custodian_and_ward call policies code generator""" return with_custodian_and_ward_t( custodian, ward, base ) class with_custodian_and_ward_postcall_t( with_custodian_and_ward_t ): @@ -207,11 +207,11 @@ return '::boost::python::with_custodian_and_ward_postcall' def with_custodian_and_ward_postcall( custodian, ward, base=None): - """create boost::python::with_custodian_and_ward_postcall call policies code generator""" + """create boost::python::with_custodian_and_ward_postcall call policies code generator""" return with_custodian_and_ward_postcall_t( custodian, ward, base ) class return_value_policy_t( compound_policy_t ): - """implements code generation for boost::python::return_value_policy call policies""" + """implements code generation for boost::python::return_value_policy call policies""" def __init__( self, result_converter_generator, base=None): compound_policy_t.__init__( self, base ) self._result_converter_generator = result_converter_generator @@ -235,12 +235,13 @@ def is_predefined( self ): """Returns True if call policy is defined in Boost.Python library, False otherwise""" + global return_addressof global return_pointee_value - if self.result_converter_generator == return_pointee_value: + if self.result_converter_generator in (return_pointee_value, return_addressof ): return False else: return True - + @property def header_file(self): """Return name of the header file to be included""" @@ -257,9 +258,10 @@ return_by_value = '::boost::python::return_by_value' return_opaque_pointer = '::boost::python::return_opaque_pointer' return_pointee_value = '::pyplusplus::call_policies::return_pointee_value' +return_addressof = '::pyplusplus::call_policies::return_addressof' def return_value_policy( result_converter_generator, base=None): - """create boost::python::return_value_policy call policies code generator""" + """create boost::python::return_value_policy call policies code generator""" return return_value_policy_t( result_converter_generator, base ) def is_return_opaque_pointer_policy( policy ): @@ -293,13 +295,13 @@ class memory_managers: """implements code generation for Py++ defined memory managers - - For complete documentation and usage example see http://language-binding.net/pyplusplus/documentation/functions/call_policies.html + + For complete documentation and usage example see http://language-binding.net/pyplusplus/documentation/functions/call_policies.html """ none = 'none' delete_ = 'delete_' all = [ none, delete_ ] - + @staticmethod def create( manager, function_creator=None): mem_manager = 'pyplusplus::call_policies::memory_managers::' + manager @@ -309,7 +311,7 @@ class convert_array_to_tuple_t( compound_policy_t ): """implements code generation for Py++ defined "as_tuple" value policy - + For complete documentation and usage example see http://language-binding.net/pyplusplus/documentation/functions/call_policies.html """ def __init__( self, array_size, memory_manager, make_object_call_policies=None, base=None): @@ -317,7 +319,7 @@ self._array_size = array_size self._memory_manager = memory_manager self._make_objec_call_policies = make_object_call_policies - + def is_predefined( self ): """Returns True if call policy is defined in Boost.Python library, False otherwise""" return False @@ -359,14 +361,14 @@ if function_creator: as_tuple = algorithm.create_identifier( function_creator, as_tuple ) return [ declarations.templates.join( as_tuple, as_tuple_args ) ] - + def convert_array_to_tuple( array_size, memory_manager, make_object_call_policies=None, base=None ): - """create boost::python::return_value_policy< py++::as_tuple > call policies code generator""" + """create boost::python::return_value_policy< py++::as_tuple > call policies code generator""" return convert_array_to_tuple_t( array_size, memory_manager, make_object_call_policies, base ) class return_range_t( call_policy_t ): """implements code generation for Py++ defined "return_range" call policies - + For complete documentation and usage example see http://language-binding.net/pyplusplus/documentation/functions/call_policies.html """ HEADER_FILE = "__return_range.pypp.hpp" @@ -409,14 +411,14 @@ if not self.value_policies.is_default(): args.append( self.value_policies.create_type() ) return declarations.templates.join( name, args ) - + def return_range( function, get_size_class, value_policies=None ): - """create Py++ defined return_range call policies code generator""" + """create Py++ defined return_range call policies code generator""" r_type = function.return_type if not declarations.is_pointer( r_type ): raise TypeError( 'Function "%s" return type should be pointer, got "%s"' % r_type.decl_string ) - + value_type = declarations.remove_pointer( r_type ) if None is value_policies: if python_traits.is_immutable( value_type ): @@ -424,4 +426,4 @@ else: raise RuntimeError( "return_range call policies requieres specification of value_policies" ) return return_range_t( get_size_class, value_type, value_policies ) - + Modified: pyplusplus_dev/pyplusplus/module_builder/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/call_policies.py 2008-08-08 12:18:18 UTC (rev 1386) +++ pyplusplus_dev/pyplusplus/module_builder/call_policies.py 2008-08-08 14:32:06 UTC (rev 1387) @@ -18,6 +18,7 @@ from pyplusplus.decl_wrappers import return_opaque_pointer from pyplusplus.decl_wrappers import return_value_policy from pyplusplus.decl_wrappers import return_pointee_value +from pyplusplus.decl_wrappers import return_addressof from pyplusplus.decl_wrappers import custom_call_policies from pyplusplus.decl_wrappers import convert_array_to_tuple from pyplusplus.decl_wrappers import memory_managers Modified: pyplusplus_dev/unittests/test_all.py =================================================================== --- pyplusplus_dev/unittests/test_all.py 2008-08-08 12:18:18 UTC (rev 1386) +++ pyplusplus_dev/unittests/test_all.py 2008-08-08 14:32:06 UTC (rev 1387) @@ -105,6 +105,8 @@ import inner_tmpl_class_tester import bug_covariant_returns_tester import embeded_tester +import unions_tester +import cp_return_addressof_tester #import ogre_generate_tester testers = [ @@ -198,6 +200,8 @@ , inner_tmpl_class_tester , bug_covariant_returns_tester , embeded_tester + , unions_tester + , cp_return_addressof_tester # , ogre_generate_tester too much time ] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-08 12:18:11
|
Revision: 1386 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1386&view=rev Author: roman_yakovenko Date: 2008-08-08 12:18:18 +0000 (Fri, 08 Aug 2008) Log Message: ----------- adding new features: exposing anonymous structs and anonymous unions, exposing variables, that has union as a type Modified Paths: -------------- pyplusplus_dev/docs/documentation/www_configuration.py pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py pyplusplus_dev/pyplusplus/messages/warnings_.py pyplusplus_dev/pyplusplus/module_builder/builder.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py pyplusplus_dev/unittests/data/unnamed_classes_to_be_exported.hpp pyplusplus_dev/unittests/module_body_tester.py pyplusplus_dev/unittests/unnamed_classes_tester.py Added Paths: ----------- pyplusplus_dev/docs/documentation/ctypes/ pyplusplus_dev/unittests/data/unions_to_be_exported.hpp pyplusplus_dev/unittests/unions_tester.py Removed Paths: ------------- pyplusplus_dev/docs/documentation/ctypes_integration.rest Deleted: pyplusplus_dev/docs/documentation/ctypes_integration.rest =================================================================== --- pyplusplus_dev/docs/documentation/ctypes_integration.rest 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/docs/documentation/ctypes_integration.rest 2008-08-08 12:18:18 UTC (rev 1386) @@ -1,148 +0,0 @@ -================== -ctypes integration -================== - -.. contents:: Table of contents - ------------- -Introduction ------------- - -`Boost.Python`_ is really a very powerful library, but if you are working -with code written in plain "C" - you've got a problem. You have to create -wrappers for almost every function or variable. - -In general, if you want to work with plain "C" code from `Python`_ -you don't have to create any wrapper - you can use `ctypes`_ package. - -About ctypes ------------- -`ctypes`_ is a foreign function library for Python. It provides C -compatible data types, and allows to call functions in dlls/shared -libraries. It can be used to wrap these libraries in pure Python. - - - -The idea behind "ctypes integration" functionality is simple: you -configure `Py++`_ to expose address of the variables or return -values, as integer and than you can use `ctypes`_ `from_address`_ -functionality to access the data. - -Obviously, this approach has its price: - -* it could be very dangerous - you can corrupt your application memory - -* managing memory is not something a typical `Python`_ user get used to. - It is too "low level". - -In my opinion, the better way to go is to "mix": - -1. expose your native code using `Boost.Python`_ and "ctypes integration" - functionality - -2. use `ctypes`_ module to access your data - -3. create high level API: the wrappers, which will ensure the constraints - and will provide more "natural" interface - --------------- -Usage examples --------------- - -Variables ---------- - -Lets say you have the following C++ code: - - .. code-block:: C++ - - struct bytes_t{ - bytes_t(){ - data = new int[5]; - for(int i=0; i<5; i++){ - data[i] = i; - } - } - ... - int* data; - static int* x; - }; - - //somewhere in a cpp file - int* bytes_t::x = new int( 1997 ); - -In order to get access to the ``bytes_t::data`` and ``bytes_t::x`` you -have to turn on ``expose_address`` property to ``True``: - - .. code-block:: Python - - mb = module_builder_t( ... ) - bytes = mb.class_( 'bytes_t' ) - bytes.vars().expose_address = True - -`Py++`_ will generate code, which will expose the address of the variables. - -and now it is a time to show some `ctypes`_ magic: - - .. code-block:: Python - - import ctypes - import your_module as m - - bytes = m.bytes_t() - - data_type = ctypes.POINTER( ctypes.c_int ) - data = data_type.from_address( bytes.data ) - for j in range(5): - print '%d : %d' % ( j, data[j] ) - - data_type = ctypes.POINTER( ctypes.c_int ) - data = data_type.from_address( m.bytes_t.x ) - print x.contents.value - - -"this" pointer --------------- - -`Py++`_ can expose "this" pointer value to `Python`_: - - .. code-block:: Python - - mb = module_builder_t( ... ) - mb.class_( 'bytes_t' ).expose_this = True - -and the usage example: - - .. code-block:: Python - - import ctypes - import your_module as m - - print m.bytes_t().this - - -Warning: I hope you know what you are doing, otherwise don't blame me :-) - ------------------ -Future directions ------------------ - -The functionality is going to be developed father and I intend to add -next features: - -* to expose the result of "sizeof" applied on a class or variable - -* to add new call policy, which will return value of a pointer as integer - -* to port this functionality to 64bit systems - -* to add support for unions - -.. _`ctypes` : http://docs.python.org/lib/module-ctypes.html -.. _`from_address` : http://docs.python.org/lib/ctypes-data-types.html -.. _`Py++` : ./../pyplusplus.html -.. _`pygccxml` : ./../../pygccxml/pygccxml.html -.. _`Boost.Python`: http://www.boost.org/libs/python/doc/index.html -.. _`Python`: http://www.python.org -.. _`GCC-XML`: http://www.gccxml.org - Modified: pyplusplus_dev/docs/documentation/www_configuration.py =================================================================== --- pyplusplus_dev/docs/documentation/www_configuration.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/docs/documentation/www_configuration.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -8,5 +8,4 @@ , 'best_practices' : 'best practices' , 'multi_module_development' : 'multi-module development' , 'split_module' : 'splitting generated code to files' - , 'ctypes_integration' : 'ctypes integration' } Modified: pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/pyplusplus/decl_wrappers/calldef_wrapper.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -54,7 +54,7 @@ def _get_create_with_signature(self): if None is self._create_with_signature: self._create_with_signature = bool( self.overloads ) - + if not self._create_with_signature and declarations.templates.is_instantiation( self.name ): self._create_with_signature = True @@ -73,7 +73,7 @@ self._create_with_signature \ = bool( self.parent.calldefs( self.name, recursive=False, allow_empty=True ) ) return self._create_with_signature - + def _set_create_with_signature(self, create_with_signature): self._create_with_signature = create_with_signature create_with_signature = property( _get_create_with_signature, _set_create_with_signature @@ -159,6 +159,8 @@ return '' def _exportable_impl( self ): + if not self.parent.name: + return messages.W1057 % str( self ) all_types = [ arg.type for arg in self.arguments ] all_types.append( self.return_type ) for some_type in all_types: @@ -398,7 +400,7 @@ included = filter( lambda decl: decl.ignore == False, oper.class_types ) if not included: return messages.W1052 % str(oper) - + return '' class member_operator_t( declarations.member_operator_t, calldef_t ): Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -370,10 +370,16 @@ def _exportable_impl( self ): if not self.name: - return messages.W1018 - #it is possible to do so, but not for unnamed classes defined under namespace. + named_parent = declarations.get_named_parent( self ) + if not named_parent: + return messages.W1057 % str( self ) + if isinstance( named_parent, declarations.namespace_t ): + return messages.W1018 % str( self ) if self.class_type == declarations.CLASS_TYPES.UNION: - return messages.W1054 + if self.is_wrapper_needed(): + return messages.W1059 % str( self ) + if self.name: + return messages.W1060 % str( self ) if isinstance( self.parent, declarations.namespace_t ): return '' if not self in self.parent.public_members: @@ -587,14 +593,7 @@ if isinstance( member, declarations.destructor_t ): continue if isinstance( member, declarations.variable_t ): - if member.bits: - explanation.append( messages.W1024 % member.name ) - if declarations.is_pointer( member.type ): - explanation.append( messages.W1025 % member.name ) - if declarations.is_reference( member.type ): - explanation.append( messages.W1026 % member.name ) - if declarations.is_array( member.type ): - explanation.append( messages.W1027 % member.name) + explanation.extend( member.is_wrapper_needed() ) if isinstance( member, declarations.class_t ) and member.is_wrapper_needed(): explanation.append( messages.W1028 % member.name) if isinstance( member, declarations.calldef_t ): @@ -636,3 +635,16 @@ self._expose_this = new_value expose_this = property( _get_expose_this, _set_expose_this , doc="boolean, if True an object address( this pointer ) will be exposed to Python as integer.") + + @property + def introduces_new_scope(self): + """returns True, if during exposing this class, new scope will be created + + For example, anonymous structs will be exposed in a parent scope. + """ + if not self.name: + return False + elif self.class_type == declarations.CLASS_TYPES.UNION: + return False + else: + return True Modified: pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/pyplusplus/decl_wrappers/enumeration_wrapper.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -75,3 +75,8 @@ if len( set( name2value.keys() ) ) != len( set( name2value.values() ) ): msgs.append( messages.W1032 ) return msgs + + def _exportable_impl( self ): + if not self.parent.name: + return messages.W1057 % str( self ) + return '' Modified: pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -23,7 +23,8 @@ self._is_read_only = None self._use_make_functions = None self._expose_address = None - + self._expose_value = None + __call_policies_doc__ = \ """There are usecase, when exporting member variable forces Py++ to create accessors functions. Sometime, those functions requires call policies. @@ -56,7 +57,7 @@ def get_setter_call_policies( self ): if None is self._getter_call_policies: if self.apply_smart_ptr_wa or self.use_make_functions: - self._setter_call_policies = call_policies.default_call_policies() + self._setter_call_policies = call_policies.default_call_policies() return self._setter_call_policies def set_setter_call_policies( self, call_policies ): self._setter_call_policies = call_policies @@ -65,15 +66,15 @@ __use_make_functions_doc__ = \ """Generate code using make_getter and make_setter functions - + Basically you don't need to use this, untill you have one of the next use-cases: * member variable is smart pointer - in this case Boost.Python has small problem to expose it right. Using the functions is a work around to the problem. * member variable defined custom r-value converter - may be you don't know - but the conversion is applied only on functions arguments. So you need to + but the conversion is applied only on functions arguments. So you need to use make_getter/make_setter in order to allow user to enjoy from the conversion. - + Setting "apply_smart_ptr_wa" and/or "use_make_functions" to "True" will tell Py++ to generate such code. """ @@ -92,32 +93,64 @@ use_make_functions = property( get_use_make_functions, set_use_make_functions , doc=__use_make_functions_doc__) + def __should_be_exposed_by_address_only(self): + type_ = declarations.remove_alias( self.type ) + type_ = declarations.remove_const( type_ ) + type_ = declarations.remove_pointer( type_ ) + if not declarations.class_traits.is_my_case( type_ ): + return False + cls = declarations.class_traits.get_declaration( type_ ) + if cls.class_type == declarations.CLASS_TYPES.UNION: + return True + elif not cls.name: + return True + else: + return False + __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 + + 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. + package to edit the content of the variable. """ def get_expose_address( self ): + if None is self._expose_address: + self._expose_address = self.__should_be_exposed_by_address_only() 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__ ) - + __expose_value_doc__ = \ + """Boost.Python is not able to expose unions. Using ctypes module + it is possible to get access to the data stored in a variable, which + has some union type. + + This property controls whether Py++ should expose the variable value + or not. In case, this variable has type union, this property will be False. + """ + def get_expose_value( self ): + if None is self._expose_value: + self._expose_value = not self.__should_be_exposed_by_address_only() + return self._expose_value + def set_expose_value( self, value ): + self._expose_value = value + expose_value = property( get_expose_value, set_expose_value + , doc= __expose_value_doc__ ) + def __find_out_is_read_only(self): type_ = declarations.remove_alias( self.type ) - + if isinstance( type_, declarations.const_t ): return True - + if declarations.is_pointer( type_ ): type_ = declarations.remove_pointer( type_ ) @@ -126,16 +159,16 @@ if isinstance( type_, declarations.const_t ): return True - + if self.apply_smart_ptr_wa: return False #all smart pointers has assign operator - + if isinstance( type_, declarations.declarated_t ) \ and isinstance( type_.declaration, declarations.class_t ) \ and not declarations.has_public_assign( type_.declaration ): return True return False - + def get_is_read_only( self ): if None is self._is_read_only: self._is_read_only = self.__find_out_is_read_only() @@ -145,8 +178,9 @@ is_read_only = property( get_is_read_only, set_is_read_only ) def _exportable_impl( self ): - if self.name == 'f': - i = 0 + if not self.parent.name and self.is_wrapper_needed(): + #return messages.W1057 % str( self ) + return messages.W1058 % str( self ) if not self.name: return messages.W1033 if self.bits == 0 and self.name == "": @@ -172,6 +206,8 @@ cls = declarations.class_traits.get_declaration( type_ ) if not cls.name: return messages.W1038 + #if cls.class_type == declarations.CLASS_TYPES.UNION: + # return messages.W1061 % ( str( self ), str( cls ) ) if isinstance( self.parent, declarations.class_t ): if self.access_type != declarations.ACCESS_TYPES.PUBLIC: return messages.W1039 @@ -182,3 +218,19 @@ if python_traits.is_immutable( item_type_no_ptr ): return messages.W1056 return '' + + def is_wrapper_needed(self): + """returns an explanation( list of str ) why wrapper is needed. + + If wrapper is not needed than [] will be returned. + """ + explanation = [] + if self.bits: + explanation.append( messages.W1024 % self.name ) + if declarations.is_pointer( self.type ): + explanation.append( messages.W1025 % self.name ) + if declarations.is_reference( self.type ): + explanation.append( messages.W1026 % self.name ) + if declarations.is_array( self.type ): + explanation.append( messages.W1027 % self.name) + return explanation Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -99,11 +99,11 @@ W1016 = warning( 'Py++ does not exports non-const casting operators with user defined type as return value. ' - 'This could be change in future.' ) + 'This could be changed in future.' ) W1017 = compilation_error( "Py++ doesn't export non-public casting operators." ) -W1018 = compilation_error( 'Py++ can not expose unnamed classes.' ) +W1018 = compilation_error( 'Py++ can not expose anonymous class "%s", declared in a namespace.' ) W1019 = compilation_error( 'Py++ can not expose private class.' ) @@ -139,7 +139,7 @@ "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" ) +W1033 = compilation_error( "Py++ can not expose anonymous variables" ) W1034 = compilation_error( "Py++ can not expose alignment bit." ) @@ -151,7 +151,7 @@ "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." ) +W1038 = compilation_error( "Py++ can not expose variables of with anonymous type." ) W1039 = compilation_error( "Py++ doesn't expose private or protected member variables." ) @@ -222,6 +222,21 @@ W1056 = compilation_error( "Py++ can not expose array of pointers of Python immutable types. Take a look on 'ctypes integration' feature." ) +W1057 = compilation_error( 'Py++ can not expose "%s" - it does not belong to named class.' ) + +W1058 = compilation_error( 'Py++ can not expose "%s" it belongs to anonymous class' + ' and requires additional code to expose.' + ' This could be changed in future.') + +W1059 = compilation_error( 'Py++ can not expose "%s" - it requires additional code to expose.' + ' This could be changed in future.') + +W1060 = compilation_error( 'Py++ can not expose "%s" - it has name, Py++ only exposes anonymous unions.' + ' This could be changed in future.') + +W1061 = compilation_error( 'Py++ can not expose "%s" - its type is "%s".' + ' This could be changed in future.') + warnings = globals() all_warning_msgs = [] Modified: pyplusplus_dev/pyplusplus/module_builder/builder.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/builder.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/pyplusplus/module_builder/builder.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -6,7 +6,7 @@ import os import sys import time - +import types import warnings from pygccxml import parser @@ -97,7 +97,7 @@ self.__registrations_code_head = [] self.__registrations_code_tail = [] - + @property def global_ns( self ): """reference to global namespace""" @@ -108,19 +108,19 @@ return self.__encoding def register_module_dependency( self, other_module_generated_code_dir ): - """``already_exposed`` solution is pretty good when you mix hand-written - modules with Py++ generated. It doesn't work/scale for "true" - multi-module development. This is exactly the reason why ``Py++``_ + """``already_exposed`` solution is pretty good when you mix hand-written + modules with Py++ generated. It doesn't work/scale for "true" + multi-module development. This is exactly the reason why ``Py++``_ offers "semi automatic" solution. - For every exposed module, ``Py++``_ generates "exposed_decl.pypp.txt" file. - This file contains the list of all parsed declarations and whether they - were included or excluded. Later, when you work on another module, you - can tell ``Py++``_ that the current module depends on the previously - generated one. ``Py++``_ will load "exposed_decl.pypp.txt" file and + For every exposed module, ``Py++``_ generates "exposed_decl.pypp.txt" file. + This file contains the list of all parsed declarations and whether they + were included or excluded. Later, when you work on another module, you + can tell ``Py++``_ that the current module depends on the previously + generated one. ``Py++``_ will load "exposed_decl.pypp.txt" file and update the declarations. """ - + db = utils.exposed_decls_db_t() db.load( other_module_generated_code_dir ) db.update_decls( self.global_ns ) @@ -305,6 +305,23 @@ else: self.__registrations_code_head.append( code ) + def add_constants( self, **keywds ): + """adds code that exposes some constants to Python. + + For example: + mb.add_constants( version='"1.2.3"' ) + or + mb.add_constants( **{ version:'"1.2.3"' } ) + will generate next code: + boost::python::scope().attr("version") = "1.2.3"; + """ + tmpl = 'boost::python::scope().attr("%(name)s") = %(value)s;' + for name, value in keywds.items(): + if not isinstance( value, types.StringTypes ): + value = str( value ) + self.add_registration_code( tmpl % dict( name=name, value=value) ) + + def __merge_user_code( self ): for code in self.__declarations_code_tail: self.code_creator.add_declaration_code( code, -1 ) @@ -365,24 +382,24 @@ This could speed-up code generation process by 10-15%. """ self.__merge_user_code() - - files_sum_repository = None + + files_sum_repository = None if use_files_sum_repository: cache_file = os.path.join( dir_name, self.code_creator.body.name + '.md5.sum' ) files_sum_repository = file_writers.cached_repository_t( cache_file ) - + written_files = [] if None is huge_classes: - written_files = file_writers.write_multiple_files( + written_files = file_writers.write_multiple_files( self.code_creator , dir_name , files_sum_repository=files_sum_repository , encoding=self.encoding) else: - written_files = file_writers.write_class_multiple_files( + written_files = file_writers.write_class_multiple_files( self.code_creator , dir_name - , huge_classes + , huge_classes , files_sum_repository=files_sum_repository , encoding=self.encoding) self.__work_on_unused_files( dir_name, written_files, on_unused_file_found ) @@ -411,18 +428,18 @@ This could speed-up code generation process by 10-15%. """ self.__merge_user_code() - - files_sum_repository = None + + files_sum_repository = None if use_files_sum_repository: cache_file = os.path.join( dir_name, self.code_creator.body.name + '.md5.sum' ) files_sum_repository = file_writers.cached_repository_t( cache_file ) - + written_files = file_writers.write_balanced_files( self.code_creator , dir_name , number_of_buckets=number_of_files , files_sum_repository=files_sum_repository , encoding=self.encoding) - + self.__work_on_unused_files( dir_name, written_files, on_unused_file_found ) return written_files @@ -470,7 +487,7 @@ , header_file=header_file , recursive=recursive) var = variable - + def variables( self, name=None, function=None, type=None, header_dir=None, header_file=None, recursive=None ): """Please see L{decl_wrappers.scopedef_t} class documentation""" return self.global_ns.variables( name=name @@ -480,7 +497,7 @@ , header_file=header_file , recursive=recursive) vars = variables - + def calldef( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): """Please see L{decl_wrappers.scopedef_t} class documentation""" return self.global_ns.calldef( name=name @@ -651,7 +668,7 @@ , header_file=header_file , recursive=recursive ) free_fun = free_function - + def free_functions( self, name=None, function=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): """Please see L{decl_wrappers.namespace_t} class documentation""" return self.global_ns.free_functions( name=name @@ -662,7 +679,7 @@ , header_file=header_file , recursive=recursive) free_funs = free_functions - + def free_operator( self, name=None, function=None, symbol=None, return_type=None, arg_types=None, header_dir=None, header_file=None, recursive=None ): """Please see L{decl_wrappers.namespace_t} class documentation""" return self.global_ns.free_operator( name=name Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -19,16 +19,6 @@ ACCESS_TYPES = declarations.ACCESS_TYPES VIRTUALITY_TYPES = declarations.VIRTUALITY_TYPES -#TODO: add print decl_wrapper.readme messages -#class Foo{ -# union { -# struct { -# float r,g,b,a; -# }; -# float val[4]; -# }; -# }; - class creator_t( declarations.decl_visitor_t ): """Creating code creators. @@ -561,7 +551,11 @@ exportable_members = self.curr_decl.get_exportable_members(sort_algorithms.sort) wrapper = None - cls_cc = code_creators.class_t( class_inst=self.curr_decl ) + cls_cc = None + if cls_decl.introduces_new_scope: + cls_cc = code_creators.class_t( class_inst=self.curr_decl ) + else: + cls_cc = self.curr_code_creator if self.curr_decl.is_wrapper_needed(): wrapper = code_creators.class_wrapper_t( declaration=self.curr_decl @@ -591,7 +585,8 @@ exposed = self.expose_overloaded_mem_fun_using_macro( cls_decl, cls_cc ) - cls_parent_cc.adopt_creator( cls_cc ) + if cls_decl.introduces_new_scope: + cls_parent_cc.adopt_creator( cls_cc ) self.curr_code_creator = cls_cc if cls_decl.expose_this: @@ -672,6 +667,9 @@ self.curr_code_creator.adopt_creator( creator_type(self.curr_decl) ) return + if not self.curr_decl.expose_value: + 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/pyplusplus/module_creator/dependencies_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -6,7 +6,7 @@ """defines class, which informs user about used, but unexposed declarations""" import os -from pyplusplus import utils +from pyplusplus import utils from pyplusplus import messages from pygccxml import declarations from pyplusplus import decl_wrappers @@ -17,19 +17,19 @@ object.__init__( self ) self.__exported_decls = [] self.__logger = logger - + def add_exported( self, decl ): - self.__exported_decls.append( decl ) + self.__exported_decls.append( decl ) def __select_duplicate_aliases( self, decls ): duplicated = {} for decl in decls: if not duplicated.has_key( decl.alias ): duplicated[ decl.alias ] = set() - duplicated[ decl.alias ].add( decl ) + duplicated[ decl.alias ].add( decl ) for alias, buggy_decls in duplicated.items(): if 1 == len( buggy_decls ): - del duplicated[ alias ] + del duplicated[ alias ] return duplicated def __report_duplicate_aliases_impl( self, control_decl, duplicated ): @@ -39,7 +39,7 @@ warning = messages.W1047 % ( control_decl.alias , os.linesep.join( map( str, buggy_decls ) ) ) self.__logger.warn( "%s;%s" % ( control_decl, warning ) ) - + if isinstance( control_decl, declarations.class_t ): query = lambda i_decl: isinstance( i_decl, declarations.class_types ) \ and i_decl.ignore == False @@ -55,7 +55,7 @@ duplicated = self.__select_duplicate_aliases( decls ) for decl in decls: self.__report_duplicate_aliases_impl( decl, duplicated ) - + def __is_std_decl( self, decl ): #Every class under std should be exported by Boost.Python and\\or Py++ #Also this is not the case right now, I prefer to hide the warnings @@ -80,7 +80,7 @@ dependencies = filter( lambda d: d.access_type != declarations.ACCESS_TYPES.PRIVATE , dependencies ) return dependencies - + def __find_out_used_but_not_exported( self ): used_not_exported = [] exported_ids = set( map( lambda d: id( d ), self.__exported_decls ) ) @@ -97,10 +97,13 @@ if isinstance( depend_on_decl, declarations.class_types ): if depend_on_decl.opaque: continue + if isinstance( decl, declarations.variable_t ): + if not decl.expose_value: + continue if id( depend_on_decl ) not in exported_ids: report = messages.filter_disabled_msgs([messages.W1040], depend_on_decl.disabled_messaged ) if report: - used_not_exported.append( dependency ) + used_not_exported.append( dependency ) return used_not_exported def __group_by_unexposed( self, dependencies ): @@ -118,7 +121,7 @@ for dependency in dependencies: decls.append( os.linesep + ' ' + str( dependency.declaration ) ) return "%s;%s" % ( depend_on_decl, messages.W1040 % ''.join( decls ) ) - + def inform_user( self ): used_not_exported_decls = self.__find_out_used_but_not_exported() groups = self.__group_by_unexposed( used_not_exported_decls ) Added: pyplusplus_dev/unittests/data/unions_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/unions_to_be_exported.hpp (rev 0) +++ pyplusplus_dev/unittests/data/unions_to_be_exported.hpp 2008-08-08 12:18:18 UTC (rev 1386) @@ -0,0 +1,35 @@ +namespace unions{ + +struct data_t{ + union actual_data_t{ + int i; + double d; + }; + actual_data_t data; + + double get_d() const{ return data.d; } + int get_i() const{ return data.i; } + + void set_d( double d ){ data.d = d; } + void set_i( int i ){ data.i = i; } +}; + +} + +namespace anonymous_unions{ + +struct data2_t{ + union{ + int i; + double d; + }; + + double get_d() const{ return d; } + int get_i() const{ return i; } + + void set_d( double _d ){ d = _d; } + void set_i( int _i ){ i = _i; } + +}; + +} Modified: pyplusplus_dev/unittests/data/unnamed_classes_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/unnamed_classes_to_be_exported.hpp 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/unittests/data/unnamed_classes_to_be_exported.hpp 2008-08-08 12:18:18 UTC (rev 1386) @@ -6,21 +6,21 @@ #ifndef __unnamed_enums_to_be_exported_hpp__ #define __unnamed_enums_to_be_exported_hpp__ -namespace unnamed_enums{ - -class color{ - union{ - struct { - float r,g,b,a; - }; - float val[4]; - }; -}; - -struct{ - int x; -} unnamed_struct_with_mem_var_x; +namespace unnamed_enums{ +struct color{ + union{ + struct { + float r,g,b,a; + }; + float val[4]; + }; +}; + +struct{ + int x; +} unnamed_struct_with_mem_var_x; + } #endif//__unnamed_enums_to_be_exported_hpp__ Modified: pyplusplus_dev/unittests/module_body_tester.py =================================================================== --- pyplusplus_dev/unittests/module_body_tester.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/unittests/module_body_tester.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -10,14 +10,14 @@ class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'module_body' - + 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): item = mb.class_( 'item_t' ) item.include() item.add_declaration_code( "int get11( const mb::item_t& item ){ return 11;}" ) @@ -31,12 +31,14 @@ mb.build_code_creator( self.EXTENSION_NAME ) - def run_tests(self, module): + mb.add_constants( version='"0.0.0"') + + def run_tests(self, module): self.failUnless( 1 == module.get1() ) self.failUnless( 11 == module.item_t().get11() ) - + self.failUnless( "0.0.0" == module.version ) def create_suite(): - suite = unittest.TestSuite() + suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) return suite @@ -44,4 +46,4 @@ unittest.TextTestRunner(verbosity=2).run( create_suite() ) if __name__ == "__main__": - run_suite() \ No newline at end of file + run_suite() Added: pyplusplus_dev/unittests/unions_tester.py =================================================================== --- pyplusplus_dev/unittests/unions_tester.py (rev 0) +++ pyplusplus_dev/unittests/unions_tester.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -0,0 +1,53 @@ +# 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 ctypes +import unittest +import fundamental_tester_base + +class actual_data_t( ctypes.Union ): + _fields_ = [( "i", ctypes.c_int ), ( 'd', ctypes.c_double )] + +#this is compilation test +class tester_t(fundamental_tester_base.fundamental_tester_base_t): + EXTENSION_NAME = 'unions' + + def __init__( self, *args ): + fundamental_tester_base.fundamental_tester_base_t.__init__( + self + , tester_t.EXTENSION_NAME + , *args ) + + def run_tests(self, module): + obj = module.data_t() + actual_data = actual_data_t.from_address( obj.data ) + obj.set_d( 4.0 ) + self.failUnless( actual_data.d == 4.0 ) + obj.set_i( 1977 ) + self.failUnless( actual_data.i == 1977 ) + actual_data.i = 18 + self.failUnless( obj.get_i() == 18 ) + actual_data.d = 12.12 + self.failUnless( obj.get_d() == 12.12 ) + + obj2 = module.data2_t() + obj2.set_d( 4.0 ) + self.failUnless( obj2.d == 4.0 ) + obj2.set_i( 1977 ) + self.failUnless( obj2.i == 1977 ) + + +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/unnamed_classes_tester.py =================================================================== --- pyplusplus_dev/unittests/unnamed_classes_tester.py 2008-08-08 10:51:47 UTC (rev 1385) +++ pyplusplus_dev/unittests/unnamed_classes_tester.py 2008-08-08 12:18:18 UTC (rev 1386) @@ -7,22 +7,24 @@ import sys import unittest import fundamental_tester_base -from pyplusplus import code_creators +from pygccxml import declarations +from pyplusplus import code_creators class unnamed_enums_tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'unnamed_classes' - + def __init__( self, *args ): - fundamental_tester_base.fundamental_tester_base_t.__init__( + fundamental_tester_base.fundamental_tester_base_t.__init__( self , unnamed_enums_tester_t.EXTENSION_NAME , *args ) - def run_tests(self, module): - pass - + def run_tests(self, module): + color = module.color() + r,g,b,a = color.r, color.g, color.b, color.a + def create_suite(): - suite = unittest.TestSuite() + suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(unnamed_enums_tester_t)) return suite @@ -30,4 +32,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-08-08 10:51:37
|
Revision: 1385 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1385&view=rev Author: roman_yakovenko Date: 2008-08-08 10:51:47 +0000 (Fri, 08 Aug 2008) Log Message: ----------- deleting old file Removed Paths: ------------- pyplusplus_dev/unittests/data/tnfox_bugs.hpp Deleted: pyplusplus_dev/unittests/data/tnfox_bugs.hpp =================================================================== --- pyplusplus_dev/unittests/data/tnfox_bugs.hpp 2008-08-08 07:31:03 UTC (rev 1384) +++ pyplusplus_dev/unittests/data/tnfox_bugs.hpp 2008-08-08 10:51:47 UTC (rev 1385) @@ -1,136 +0,0 @@ -#include <string> -#include <iostream> - -namespace FX { - -struct FXWinShellLink -{ - struct Header - { - unsigned int length; - char guid[16]; - union Flags - { - struct - { - unsigned int hasItemIdList : 1; - unsigned int pointsToFileOrDir : 1; - unsigned int hasDescription : 1; - unsigned int hasRelativePath : 1; - unsigned int hasWorkingDir : 1; - unsigned int hasCmdLineArgs : 1; - unsigned int hasCustomIcon : 1; - unsigned int useWorkingDir : 1; // Seems to need to be set to enable working dir - unsigned int unused : 24; - }; - unsigned int raw; - } flags; - union FileAttribs - { // = return from GetFileAttributes() - struct - { - unsigned int isReadOnly : 1; - unsigned int isHidden : 1; - unsigned int isSystem : 1; - unsigned int isVolumeLabel : 1; - unsigned int isDir : 1; - unsigned int isModified : 1; // =archive bit set, ie; is a file normally - unsigned int isEncrypted : 1; - unsigned int isNormal : 1; // Doesn't seem to get set - unsigned int isTemporary : 1; - unsigned int isSparse : 1; - unsigned int hasReparsePoint : 1; - unsigned int isCompressed : 1; - unsigned int isOffline : 1; - unsigned int unused : 19; - }; - unsigned int raw; - } fileattribs; // in GetFileAttributes() format - unsigned long creation, modified, lastAccess; // in FILETIME format - unsigned int filelength; - unsigned int iconno; - enum ShowWnd - { - HIDE=0, - NORMAL, - SHOWMINIMIZED, - SHOWMAXIMIZED - }; - ShowWnd showWnd; - unsigned int hotkey; - unsigned int unknown1, unknown2; - - Header(); - - friend std::ostream &operator<<(std::ostream &s, const Header &i); - friend std::istream &operator>>(std::istream &s, Header &i); - } header; - - struct ItemIdListTag - { - unsigned short length; - char path1[260]; // In ASCII - char path2[260]; // In unicode - ItemIdListTag(); - char originalPath[260]; // [not in lnk file] Used so code knows the non-decoded path - } itemIdList; - struct FileLocationTag - { - unsigned int length; // to end of whole tag - unsigned int firstOffset; // to end of this tag header - union Flags - { - struct - { - unsigned int onLocalVolume : 1; - unsigned int onNetworkShare : 1; - unsigned int unused : 30; - }; - unsigned int raw; - } flags; - struct LocalVolume - { - unsigned int length; - enum Type - { - Unknown=0, - NoRoot, - Removable, // ie; floppy, usb drive etc. - Fixed, // ie; hard disc - Remote, // ie; network share - CDROM, - RamDrive - }; - Type type; - unsigned int serialNo; - char volumeLabel[64]; - LocalVolume(); - } localVolume; - char basePath[260]; - struct NetworkVolume - { - unsigned int length; - unsigned int type; - char shareName[260]; - NetworkVolume(); - } networkVolume; - char remainingPath[64]; - - FileLocationTag(); - } fileLocation; - struct StringTag - { - unsigned short length; // in characters - char string[260]; // Unicode string - StringTag(); - }; - StringTag description; - StringTag relativePath; - StringTag workingDir; - StringTag cmdLineArgs; - StringTag customIcon; - -}; - -} // namespace - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-08 07:30:56
|
Revision: 1384 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1384&view=rev Author: roman_yakovenko Date: 2008-08-08 07:31:03 +0000 (Fri, 08 Aug 2008) Log Message: ----------- updating documentation Modified Paths: -------------- pygccxml_dev/docs/history/history.rest Modified: pygccxml_dev/docs/history/history.rest =================================================================== --- pygccxml_dev/docs/history/history.rest 2008-08-06 13:00:27 UTC (rev 1383) +++ pygccxml_dev/docs/history/history.rest 2008-08-08 07:31:03 UTC (rev 1384) @@ -62,6 +62,9 @@ 6. ``declarations.is_same_function`` was fixed and now it treats "covariant returns" right. +7. Search algorithm was improved for template instantiated classes. From + now, a spaces within the class name doesn't matter. + ------------- Version 0.9.5 ------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rom...@us...> - 2008-08-06 13:00:18
|
Revision: 1383 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1383&view=rev Author: roman_yakovenko Date: 2008-08-06 13:00:27 +0000 (Wed, 06 Aug 2008) Log Message: ----------- implement better algorithm for searching template instantiatd classes Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/matchers.py pygccxml_dev/pygccxml/declarations/pattern_parser.py pygccxml_dev/pygccxml/declarations/scopedef.py pygccxml_dev/pygccxml/declarations/templates.py pygccxml_dev/unittests/test_all.py Added Paths: ----------- pygccxml_dev/unittests/better_templates_matcher_tester.py pygccxml_dev/unittests/data/better_templates_matcher_tester.hpp Modified: pygccxml_dev/pygccxml/declarations/matchers.py =================================================================== --- pygccxml_dev/pygccxml/declarations/matchers.py 2008-08-05 15:40:28 UTC (rev 1382) +++ pygccxml_dev/pygccxml/declarations/matchers.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -177,6 +177,7 @@ else: self.__opt_is_full_name = False self.__decl_name_only = self.__opt_tmpl_name + self.__name = templates.normalize( name ) else: if '::' in self.__name: self.__opt_is_full_name = True @@ -225,11 +226,12 @@ assert not None is self.name if self.__opt_is_tmpl_inst: if not self.__opt_is_full_name: - if self.name != decl.name and self.name != decl.partial_name: + if self.name != templates.normalize( decl.name ) \ + and self.name != templates.normalize( decl.partial_name ): return False - else: - if self.name != algorithm.full_name( decl, with_defaults=True ) \ - and self.name != algorithm.full_name( decl, with_defaults=False ): + else: + if self.name != templates.normalize( algorithm.full_name( decl, with_defaults=True ) ) \ + and self.name != templates.normalize( algorithm.full_name( decl, with_defaults=False ) ): return False else: if not self.__opt_is_full_name: Modified: pygccxml_dev/pygccxml/declarations/pattern_parser.py =================================================================== --- pygccxml_dev/pygccxml/declarations/pattern_parser.py 2008-08-05 15:40:28 UTC (rev 1382) +++ pygccxml_dev/pygccxml/declarations/pattern_parser.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -24,7 +24,7 @@ def has_pattern( self, decl_string ): """implementation details""" last_part = decl_string.split( '::' )[-1] - return -1 != last_part.find( self.__end ) + return -1 != decl_string.find( self.__begin ) and -1 != last_part.find( self.__end ) def name( self, decl_string ): """implementation details""" @@ -127,3 +127,14 @@ return ''.join( [ name, self.__begin, args_str, self.__end ] ) + def normalize( self, decl_string, arg_separator=None ): + """implementation details""" + if not self.has_pattern( decl_string ): + return decl_string + name, args = self.split( decl_string ) + for i, arg in enumerate( args ): + args[i] = self.normalize( arg ) + return self.join( name, args, arg_separator ) + + + Modified: pygccxml_dev/pygccxml/declarations/scopedef.py =================================================================== --- pygccxml_dev/pygccxml/declarations/scopedef.py 2008-08-05 15:40:28 UTC (rev 1382) +++ pygccxml_dev/pygccxml/declarations/scopedef.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -10,6 +10,7 @@ import time import algorithm import filtering +import templates import declaration import mdecl_wrapper from pygccxml import utils @@ -301,8 +302,15 @@ decls = self.declarations if recursive: decls = algorithm.make_flatten( self.declarations ) + if decl_type: + decls = filter( lambda d: isinstance( d, decl_type ), decls ) return decls + if name and templates.is_instantiation( name ): + #templates has tricky mode to compare them, so lets check the whole + #range + name = None + if name and decl_type: matcher = scopedef_t._impl_matchers[ scopedef_t.decl ]( name=name ) if matcher.is_full_name(): Modified: pygccxml_dev/pygccxml/declarations/templates.py =================================================================== --- pygccxml_dev/pygccxml/declarations/templates.py 2008-08-05 15:40:28 UTC (rev 1382) +++ pygccxml_dev/pygccxml/declarations/templates.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -64,4 +64,13 @@ def join( name, args ): """returns name< argument_1, argument_2, ..., argument_n >""" global __THE_PARSER - return __THE_PARSER.join( name, args ) \ No newline at end of file + return __THE_PARSER.join( name, args ) + +def normalize( decl_string ): + """returns decl_string, which contains "normalized" spaces + + this functionality allows to implement comparison of 2 different string + which are actually same: x::y< z > and x::y<z> + """ + global __THE_PARSER + return __THE_PARSER.normalize( decl_string ) Added: pygccxml_dev/unittests/better_templates_matcher_tester.py =================================================================== --- pygccxml_dev/unittests/better_templates_matcher_tester.py (rev 0) +++ pygccxml_dev/unittests/better_templates_matcher_tester.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -0,0 +1,44 @@ +# 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 unittest +import autoconfig +import parser_test_case + +from pygccxml import utils +from pygccxml import parser +from pygccxml import declarations + +class tester_t( parser_test_case.parser_test_case_t ): + + global_ns = None + + def __init__(self, *args ): + parser_test_case.parser_test_case_t.__init__( self, *args ) + self.header = 'better_templates_matcher_tester.hpp' + + def setUp(self): + if not tester_t.global_ns: + decls = parser.parse( [self.header], self.config ) + tester_t.global_ns = declarations.get_global_namespace( decls ) + tester_t.global_ns.init_optimizer() + + def test( self ): + classes = [ '::std::vector<Ogre::PlaneBoundedVolume,std::allocator<Ogre::PlaneBoundedVolume>>' + , '::std::vector<Ogre::Plane, std::allocator<Ogre::Plane>>' + , '::Ogre::Singleton< Ogre::PCZoneFactoryManager>' ] + for i in classes: + c = self.global_ns.class_( i ) + +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() \ No newline at end of file Added: pygccxml_dev/unittests/data/better_templates_matcher_tester.hpp =================================================================== --- pygccxml_dev/unittests/data/better_templates_matcher_tester.hpp (rev 0) +++ pygccxml_dev/unittests/data/better_templates_matcher_tester.hpp 2008-08-06 13:00:27 UTC (rev 1383) @@ -0,0 +1,31 @@ +// 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) + +#include <vector> +#include <map> + +namespace Ogre{ + struct PlaneBoundedVolume{}; + + struct Plane{}; + + std::vector<PlaneBoundedVolume> do_smth(){ + return std::vector<PlaneBoundedVolume>(); + } + + std::vector<Plane> do_smth2(){ + return std::vector<Plane>(); + } + + template< class X > + struct Singleton{ + }; + + struct PCZoneFactoryManager{}; + + Singleton<PCZoneFactoryManager> do_smth3(){ + return Singleton<PCZoneFactoryManager>(); + } +} Modified: pygccxml_dev/unittests/test_all.py =================================================================== --- pygccxml_dev/unittests/test_all.py 2008-08-05 15:40:28 UTC (rev 1382) +++ pygccxml_dev/unittests/test_all.py 2008-08-06 13:00:27 UTC (rev 1383) @@ -50,6 +50,7 @@ import copy_constructor_tester import plain_c_tester import function_traits_tester +import better_templates_matcher_tester testers = [ decl_string_tester @@ -96,6 +97,7 @@ , copy_constructor_tester , plain_c_tester , function_traits_tester + , better_templates_matcher_tester ] def create_suite(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |