[pygccxml-commit] SF.net SVN: pygccxml: [1372] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
|
From: <rom...@us...> - 2008-07-14 18:58:35
|
Revision: 1372
http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1372&view=rev
Author: roman_yakovenko
Date: 2008-07-14 11:58:40 -0700 (Mon, 14 Jul 2008)
Log Message:
-----------
adding ablity to generate class wrapper destructor
Modified Paths:
--------------
pyplusplus_dev/pyplusplus/code_creators/__init__.py
pyplusplus_dev/pyplusplus/code_creators/calldef.py
pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py
pyplusplus_dev/pyplusplus/messages/warnings_.py
pyplusplus_dev/pyplusplus/module_creator/creator.py
pyplusplus_dev/unittests/transfer_ownership_tester.py
Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py
===================================================================
--- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-14 18:14:53 UTC (rev 1371)
+++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-07-14 18:58:40 UTC (rev 1372)
@@ -68,6 +68,7 @@
from calldef import casting_operator_t
from calldef import mem_fun_overloads_t
from calldef import free_fun_overloads_t
+from calldef import destructor_wrapper_t
from calldef import casting_constructor_t
from calldef import constructor_wrapper_t
from calldef import mem_fun_overloads_class_t
Modified: pyplusplus_dev/pyplusplus/code_creators/calldef.py
===================================================================
--- pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-07-14 18:14:53 UTC (rev 1371)
+++ pyplusplus_dev/pyplusplus/code_creators/calldef.py 2008-07-14 18:58:40 UTC (rev 1372)
@@ -1157,7 +1157,25 @@
def _get_system_headers_impl( self ):
return []
+class destructor_wrapper_t( code_creator.code_creator_t
+ , declaration_based.declaration_based_t ):
+ """
+ Creates class wrapper destructor from the code provided by the user
+ """
+ def __init__( self, class_ ):
+ code_creator.code_creator_t.__init__( self )
+ declaration_based.declaration_based_t.__init__( self, declaration=class_ )
+ def _create_impl(self):
+ answer = [ 'virtual ~%s(){' % self.declaration.wrapper_alias ]
+ answer.append( self.indent( os.linesep.join( self.declaration.destructor_code ) ) )
+ answer.append( '}' )
+ return os.linesep.join( answer )
+
+ def _get_system_headers_impl( self ):
+ return []
+
+
class calldef_overloads_class_t( code_creator.code_creator_t ):
def __init__( self, functions ):
#precondition: all member functions belong to same class and
Modified: pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py
===================================================================
--- pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-07-14 18:14:53 UTC (rev 1371)
+++ pyplusplus_dev/pyplusplus/decl_wrappers/class_wrapper.py 2008-07-14 18:58:40 UTC (rev 1372)
@@ -76,8 +76,8 @@
@property
def indexing_suite( self ):
- """reference to indexing suite configuration class.
-
+ """reference to indexing suite configuration class.
+
If the class is not STD container, this property will contain None"
"""
if self._indexing_suite is None:
@@ -105,7 +105,7 @@
else:
self._always_expose_using_scope = False
return self._always_expose_using_scope
-
+
def _set_always_expose_using_scope( self, value ):
self._always_expose_using_scope = value
always_expose_using_scope = property( _get_always_expose_using_scope, _set_always_expose_using_scope
@@ -134,12 +134,12 @@
less_than_comparable = property( _get_less_than_comparable, _set_less_than_comparable
, doc="indicates existence of public operator<. " \
+"Default value is calculated, based on information presented in the declarations tree" )
-
+
def _get_opaque( self ):
return self._opaque
def _set_opaque( self, value ):
- self._opaque = value
+ self._opaque = value
self.ignore = value #don't expose opaque type
opaque = property( _get_opaque, _set_opaque
@@ -163,12 +163,12 @@
class class_t( class_common_details_t
, scopedef_wrapper.scopedef_t
, declarations.class_t):
-
+
class EXPOSED_CLASS_TYPE:
DECLARED = 'declared'
WRAPPER = 'wrapper'
ALL = ( DECLARED, WRAPPER )
-
+
def __init__(self, *arguments, **keywords):
class_common_details_t.__init__( self )
declarations.class_t.__init__(self, *arguments, **keywords )
@@ -177,19 +177,20 @@
self._redefine_operators = False
self._held_type = None
self._noncopyable = None
- self._wrapper_alias = None
+ self._wrapper_alias = None
self._registration_code_head = []
self._registration_code_tail = []
self._declaration_code = []
self._wrapper_code = []
self._null_constructor_body = ''
self._copy_constructor_body = ''
+ self._destructor_code = []
self._exception_translation_code = None
self._properties = []
self._redefined_funcs = None
self._require_self_reference = False
self._exposed_class_type = self.EXPOSED_CLASS_TYPE.DECLARED
-
+
def _get_redefine_operators( self ):
return self._redefine_operators
def _set_redefine_operators( self, new_value ):
@@ -288,6 +289,15 @@
, doc="copy constructor code, that will be added as is to the copy constructor of class-wrapper")
@property
+ def destructor_code(self):
+ """list of code to be added to wrapper destructor"""
+ return self._destructor_code
+
+ def add_destructor_code(self, code):
+ """adds code to the class-wrapper destructor"""
+ self._destructor_code.append( code )
+
+ @property
def exception_argument_name( self ):
"""exception argument name for translate exception function
@@ -341,7 +351,7 @@
self.registration_code_tail.append( user_text.class_user_text_t( code, works_on_instance ) )
else:
self.registration_code_head.append( user_text.class_user_text_t( code, works_on_instance ) )
-
+
#preserving backward computability
add_code = add_registration_code
@@ -385,7 +395,7 @@
vfunction_selector = lambda member: isinstance( member, declarations.member_function_t ) \
and member.virtuality == declarations.VIRTUALITY_TYPES.PURE_VIRTUAL
members.extend( filter( vfunction_selector, self.private_members ) )
-
+
def is_exportable( decl ):
#filter out non-public member operators - Py++ does not support them right now
if isinstance( decl, declarations.member_operator_t ) \
@@ -396,7 +406,7 @@
return False
if decl.ignore == True or decl.exportable == False:
return False
- return True
+ return True
#-#if declarations.has_destructor( self ) \
#-# and not declarations.has_public_destructor( self ):
members = filter( is_exportable, members )
@@ -425,7 +435,7 @@
def add_properties( self, recognizer=None, exclude_accessors=False ):
props = properties.find_properties( self, recognizer, exclude_accessors )
self.properties.extend( props )
-
+
def add_static_property( self, name, fget, fset=None, doc='' ):
"""adds new static property to the class"""
self._properties.append( properties.property_t( name, fget, fset, doc, True ) )
@@ -456,14 +466,14 @@
all_included = declarations.custom_matcher_t( lambda decl: decl.ignore == False and decl.exportable )
all_protected = declarations.access_type_matcher_t( 'protected' ) & all_included
- all_pure_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.PURE_VIRTUAL )
+ all_pure_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.PURE_VIRTUAL )
all_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.VIRTUAL ) \
& ( declarations.access_type_matcher_t( 'public' ) \
- | declarations.access_type_matcher_t( 'protected' ))
+ | declarations.access_type_matcher_t( 'protected' ))
all_not_pure_virtual = ~all_pure_virtual
- query = all_protected | all_pure_virtual
- mf_query = query | all_virtual
+ query = all_protected | all_pure_virtual
+ mf_query = query | all_virtual
relevant_opers = declarations.custom_matcher_t( lambda decl: decl.symbol in ('()', '[]') )
funcs = []
defined_funcs = []
@@ -493,7 +503,7 @@
if declarations.is_base_and_derived( f_impl.parent, f.parent ):
#add function from the most derived class
not_reimplemented_funcs.remove( f_impl )
- not_reimplemented_funcs.add( f )
+ not_reimplemented_funcs.add( f )
break
else:
#should test whether this function is implemented in base class
@@ -504,18 +514,18 @@
if is_same_function( f, f_defined ):
break
else:
- not_reimplemented_funcs.add( f )
+ not_reimplemented_funcs.add( f )
functions = filter( lambda f: ( False == f.ignore and True == f.exportable )
or all_pure_virtual( f )
, list( not_reimplemented_funcs ) )
-
+
#Boost.Python is not able to call for non-virtual function, from the base
#class if there is a virtual function with the same within base class
#See override_bug tester for more information
def buggy_bpl_filter( f ):
- if f.parent is self:
+ if f.parent is self:
return False
if f.access_type != ACCESS_TYPES.PUBLIC:
return False
@@ -564,6 +574,9 @@
if self.copy_constructor_body:
explanation.append( messages.W1022 )
+ if self.destructor_code:
+ explanation.append( messages.W1055 )
+
redefined_funcs = self.redefined_funcs()
if redefined_funcs:
funcs = map( lambda f: f.name, redefined_funcs )
@@ -607,7 +620,7 @@
#MSVC 7.1 has problem with taking reference to operator=
if self.member_operators( is_assign, allow_empty=True, recursive=False ):
return impl_details.GUESS_VALUES.ALWAYS_TRUE
- return super(class_t, self).guess_always_expose_using_scope_value()
+ return super(class_t, self).guess_always_expose_using_scope_value()
def _get_require_self_reference(self):
return self._require_self_reference
Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py
===================================================================
--- pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-07-14 18:14:53 UTC (rev 1371)
+++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-07-14 18:58:40 UTC (rev 1372)
@@ -3,7 +3,7 @@
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
-"""This package defines all user messages (warnings + errors), which will be
+"""This package defines all user messages (warnings + errors), which will be
reported to user.
"""
@@ -11,13 +11,13 @@
"""implementation details"""
def __new__(self, value, identifier=None):
return str.__new__(self, value )
-
+
def __init__(self, value, identifier=None):
- self.__identifier = identifier
-
+ self.__identifier = identifier
+
@property
def identifier( self ):
- return self.__identifier
+ return self.__identifier
def __mod__( self, values ):
str_value = super( message_type, self ).__str__()
@@ -34,55 +34,55 @@
W0000 = warning( '%s' ) #general message, usefull in few cases
-W1000 = compilation_error(
+W1000 = compilation_error(
'Py++, by default, does not expose internal compilers declarations. '
'Names of those declarations usually start with "__".' )
-W1001 = compilation_error(
+W1001 = compilation_error(
'Py++, by default, does not expose internal declarations. '
'GCC-XML reports that these declaration belong to "<internal>" header.' )
-W1002 = compilation_error(
+W1002 = compilation_error(
'Py++, by default, does not expose compiler generated declarations.' )
-W1003 = warning(
- 'Virtual functions that returns const reference cannot be overridden from Python. '
- 'Reason: boost::python::override::operator()(...) saves the result of the marshaling '
- '(from Python to C++) on the stack. Thus operator() returns reference '
- 'to a temporary variable. Consider to use "Function Transformation" functionality '
+W1003 = warning(
+ 'Virtual functions that returns const reference cannot be overridden from Python. '
+ 'Reason: boost::python::override::operator()(...) saves the result of the marshaling '
+ '(from Python to C++) on the stack. Thus operator() returns reference '
+ 'to a temporary variable. Consider to use "Function Transformation" functionality '
'to solve the problem.' )
-W1004 = compilation_error(
- 'Boost.Python library can not expose function, which takes as argument/returns '
- 'pointer to function. '
+W1004 = compilation_error(
+ 'Boost.Python library can not expose function, which takes as argument/returns '
+ 'pointer to function. '
' See http://www.boost.org/libs/python/doc/v2/faq.html#funcptr for more information.' )
-W1005 = compilation_error(
- 'Py++ cannot expose function that takes as argument/returns instance of non-public class. '
+W1005 = compilation_error(
+ 'Py++ cannot expose function that takes as argument/returns instance of non-public class. '
'Generated code will not compile.' )
-W1006 = compilation_error(
+W1006 = compilation_error(
'Py++ need your help to expose function that takes as argument/returns C++ arrays. '
'Take a look on "Function Transformation" functionality and define the transformation.' )
-W1007 = warning(
- 'The function has more than %d arguments ( %d ). '
- 'You should adjust BOOST_PYTHON_MAX_ARITY macro. '
+W1007 = warning(
+ 'The function has more than %d arguments ( %d ). '
+ 'You should adjust BOOST_PYTHON_MAX_ARITY macro. '
'For more information see: http://www.boost.org/libs/python/doc/v2/configuration.html' )
-W1008 = warning(
- 'The function returns non-const reference to "Python immutable" type. '
+W1008 = warning(
+ 'The function returns non-const reference to "Python immutable" type. '
'The value cannot be modified from Python. ' )
-W1009 = execution_error(
- 'The function takes as argument (name=%s, pos=%d) non-const reference '
- 'to Python immutable type - function could not be called from Python. '
+W1009 = execution_error(
+ 'The function takes as argument (name=%s, pos=%d) non-const reference '
+ 'to Python immutable type - function could not be called from Python. '
'Take a look on "Function Transformation" functionality and define the transformation.' )
W1010 = execution_error(
- 'The function introduces registration order problem. '
- 'For more information about the problem read next document: '
- 'http://language-binding.net/pyplusplus/documentation/functions/registration_order.html '
+ 'The function introduces registration order problem. '
+ 'For more information about the problem read next document: '
+ 'http://language-binding.net/pyplusplus/documentation/functions/registration_order.html '
'Problematic functions list: %s' )
W1011 = warning( "Py++ doesn't export private not virtual functions." )
@@ -91,14 +91,14 @@
W1013 = compilation_error( "Py++ doesn't export private constructor." )
-W1014 = compilation_error(
+W1014 = compilation_error(
'"%s" is not supported. '
'See Boost.Python documentation: http://www.boost.org/libs/python/doc/v2/operators.html#introduction.' )
W1015 = compilation_error( "Py++ doesn't export private operators." )
-W1016 = warning(
- 'Py++ does not exports non-const casting operators with user defined type as return value. '
+W1016 = warning(
+ 'Py++ does not exports non-const casting operators with user defined type as return value. '
'This could be change in future.' )
W1017 = compilation_error( "Py++ doesn't export non-public casting operators." )
@@ -113,7 +113,7 @@
W1022 = warning( "Py++ will generate class wrapper - hand written code should be added to the wrapper class copy constructor body" )
-W1023 = warning(
+W1023 = warning(
"Py++ will generate class wrapper - there are few functions that should be redefined in class wrapper. "
"The functions are: %s." )
@@ -133,10 +133,10 @@
W1031 = warning( 'Py++ will generate class wrapper - user asked to expose non - public member function "%s"' )
-W1032 = execution_error(
- "Boost.Python library does not support enums with duplicate values. "
- "You can read more about this here: "
- "http://boost.org/libs/python/todo.html#support-for-enums-with-duplicate-values . "
+W1032 = execution_error(
+ "Boost.Python library does not support enums with duplicate values. "
+ "You can read more about this here: "
+ "http://boost.org/libs/python/todo.html#support-for-enums-with-duplicate-values . "
"The quick work around is to add new class variable to the exported enum, from Python. " )
W1033 = compilation_error( "Py++ can not expose unnamed variables" )
@@ -147,21 +147,21 @@
W1036 = compilation_error( "Py++ can not expose pointer to Python immutable member variables. This could be changed in future." )
-W1037 = compilation_error(
- "Boost.Python library can not expose variables, which are pointer to function."
+W1037 = compilation_error(
+ "Boost.Python library can not expose variables, which are pointer to function."
" See http://www.boost.org/libs/python/doc/v2/faq.html#funcptr for more information." )
W1038 = compilation_error( "Py++ can not expose variables of with unnamed type." )
W1039 = compilation_error( "Py++ doesn't expose private or protected member variables." )
-W1040 = execution_error(
+W1040 = execution_error(
'The declaration is unexposed, but there are other declarations, which refer to it. '
- 'This could cause "no to_python converter found" run time error. '
+ 'This could cause "no to_python converter found" run time error. '
'Declarations: %s' )
-W1041 = warning(
- 'Property "%s" could not be created. There is another exposed declaration with the same name( alias )." '
+W1041 = warning(
+ 'Property "%s" could not be created. There is another exposed declaration with the same name( alias )." '
'The property will make it inaccessible.' )
W1042 = warning(
@@ -175,15 +175,15 @@
W1044 = warning( 'Py++ created an ugly alias ("%s") for function wrapper.' )
-W1045 = compilation_error(
+W1045 = compilation_error(
'Py++ does not expose static arrays with unknown size. '
'You can fix this by setting array size to the actual one.'
'For more information see "array_t" class documentation.' )
-W1046 = warning(
- 'The virtual function was declared with empty throw. '
- 'Adding the ability to override the function from Python breaks the exception specification. '
- 'The function wrapper can throw any exception. '
+W1046 = warning(
+ 'The virtual function was declared with empty throw. '
+ 'Adding the ability to override the function from Python breaks the exception specification. '
+ 'The function wrapper can throw any exception. '
'In case of exception in run-time, the behaviour of the program is undefined! ' )
W1047 = warning(
@@ -192,32 +192,34 @@
'of the classes will not be exposed to Python.'
'Other classes : %s' )
-W1048 = warning(
+W1048 = warning(
'There are two or more aliases within "pyplusplus::aliases" namespace for '
'the class. Py++ selected "%s" as class alias. Other aliases: %s' )
-W1049 = warning(
- 'This method could not be overriden in Python - method returns reference '
+W1049 = warning(
+ 'This method could not be overriden in Python - method returns reference '
'to local variable!' )
W1050 = compilation_error(
- 'The function returns "%s" type. You have to specify a call policies.'
- 'Be sure to take a look on Py++ defined call policies: '
+ 'The function returns "%s" type. You have to specify a call policies.'
+ 'Be sure to take a look on Py++ defined call policies: '
'http://language-binding.net/pyplusplus/documentation/functions/call_policies.html#py-defined-call-policies' )
-W1051 = warning(
+W1051 = warning(
'The function takes as argument (name=%s, pos=%d) "%s" type. '
'You have to specify a call policies or to use "Function Transformation" '
'functionality.' )
-W1052 = warning(
+W1052 = warning(
'Py++ will not expose free operator "%s" - all classes, this operator works on, are excluded.' )
-W1053 = warning(
+W1053 = warning(
'Py++ will not expose function "%s" - the function has variable-argument list, spicified by ellipsis (...).' )
W1054 = compilation_error( 'Py++ can not expose unions.' )
+W1055 = warning( "Py++ will generate class wrapper - hand written code should be added to the wrapper class destructor body" )
+
warnings = globals()
all_warning_msgs = []
@@ -230,13 +232,13 @@
try:
int( identifier[1:] )
except:
- continue
- msg = '%s %s: %s' % ( explanation.__class__.prefix, identifier, str(explanation) )
+ continue
+ msg = '%s %s: %s' % ( explanation.__class__.prefix, identifier, str(explanation) )
msg_inst = explanation.__class__( msg, identifier )
globals()[ identifier ] = msg_inst
all_warning_msgs.append( msg_inst )
-
+
del warnings
del identifier
del explanation
Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py
===================================================================
--- pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-14 18:14:53 UTC (rev 1371)
+++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2008-07-14 18:58:40 UTC (rev 1372)
@@ -624,6 +624,10 @@
for property_def in cls_decl.properties:
cls_cc.adopt_creator( code_creators.property_t(property_def) )
+ if wrapper and cls_decl.destructor_code:
+ destructor = code_creators.destructor_wrapper_t( class_=cls_decl )
+ wrapper.adopt_creator( destructor )
+
self.curr_decl = cls_decl
self.curr_code_creator = cls_parent_cc
Modified: pyplusplus_dev/unittests/transfer_ownership_tester.py
===================================================================
--- pyplusplus_dev/unittests/transfer_ownership_tester.py 2008-07-14 18:14:53 UTC (rev 1371)
+++ pyplusplus_dev/unittests/transfer_ownership_tester.py 2008-07-14 18:58:40 UTC (rev 1372)
@@ -12,14 +12,10 @@
from pyplusplus.module_builder import call_policies
decref_code = \
-"""
- virtual ~%(cls)s(){
- if (this->m_pyobj) {
- //Py_DECREF(this->m_pyobj);
- this->m_pyobj = 0;
- }
- }
-"""
+"""if (this->m_pyobj) {
+ //Py_DECREF(this->m_pyobj);
+ this->m_pyobj = 0;
+}"""
incref_code = \
"""
@@ -36,9 +32,9 @@
class tester_t(fundamental_tester_base.fundamental_tester_base_t):
EXTENSION_NAME = 'transfer_ownership'
-
+
def __init__( self, *args ):
- fundamental_tester_base.fundamental_tester_base_t.__init__(
+ fundamental_tester_base.fundamental_tester_base_t.__init__(
self
, tester_t.EXTENSION_NAME
, *args )
@@ -46,12 +42,12 @@
def customize( self, mb ):
event_clss = mb.classes( lambda cls: cls.name in ( 'event_t', 'do_nothing_t' ) )
for cls in event_clss:
- cls.add_wrapper_code( decref_code % { 'cls' : cls.wrapper_alias } )
+ cls.add_destructor_code( decref_code )
cls.add_wrapper_code( 'PyObject* m_pyobj;' )
cls.set_constructors_body( 'm_pyobj=0;' )
cls.mem_fun( 'notify' ).add_override_precall_code( incref_code )
cls.mem_fun( 'notify' ).add_default_precall_code( incref_code )
-
+
cls.held_type = 'std::auto_ptr< %s >' % cls.wrapper_alias
cls.add_registration_code( impl_conv_code % { 'from' : cls.wrapper_alias
, 'to' : cls.decl_string }
@@ -62,7 +58,7 @@
impl_conv_code % { 'from' : cls.decl_string
, 'to' : base.related_class.decl_string }
, False)
-
+
cls.add_registration_code( #from wrapper to clas base class
impl_conv_code % { 'from' : cls.wrapper_alias
, 'to' : base.related_class.decl_string }
@@ -73,16 +69,16 @@
simulator = mb.class_( 'simulator_t' )
simulator.mem_fun( 'get_event' ).call_policies \
= call_policies.return_internal_reference()
-
+
def run_tests( self, module):
class py_event_t( module.event_t ):
def __init__( self, container ):
module.event_t.__init__( self )
self.container = container
-
+
def notify( self ):
self.container.append( 1 )
-
+
print '1'
notify_data = []
simulator = module.simulator_t()
@@ -97,9 +93,9 @@
simulator.run()
print '6'
self.failUnless( notify_data[0] == 1 )
-
+
def create_suite():
- suite = unittest.TestSuite()
+ suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite(tester_t))
return suite
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|