Package pyplusplus :: Package decl_wrappers :: Module class_wrapper

Source Code for Module pyplusplus.decl_wrappers.class_wrapper

  1  # Copyright 2004-2008 Roman Yakovenko. 
  2  # Distributed under the Boost Software License, Version 1.0. (See 
  3  # accompanying file LICENSE_1_0.txt or copy at 
  4  # http://www.boost.org/LICENSE_1_0.txt) 
  5   
  6  """defines class that configure class definition and class declaration exposing""" 
  7   
  8  import os 
  9  import user_text 
 10  import properties 
 11  import decl_wrapper 
 12  import scopedef_wrapper 
 13  from pyplusplus import messages 
 14  from pygccxml import declarations 
 15  import indexing_suite1 as isuite1 
 16  import indexing_suite2 as isuite2 
 17   
 18  ACCESS_TYPES = declarations.ACCESS_TYPES 
 19  VIRTUALITY_TYPES = declarations.VIRTUALITY_TYPES 
20 21 -class impl_details:
22 - class GUESS_VALUES: #guess always expose using scope values
23 TRUE = 'true' 24 FALSE = 'false' 25 ALWAYS_TRUE = 'always true' 26 all = [ TRUE, FALSE, ALWAYS_TRUE ]
27 28 29 always_expose_using_scope_documentation = \ 30 """boolean, configures how Py++ should generate code for class. 31 Py can generate code using IDL like syntax: 32 33 class_< ... >( ... ) 34 .def( ... ); 35 36 Or it can generate code using more complex form: 37 38 typedef bp::class_< my_class > my_class_exposer_t; 39 my_class_exposer_t my_class_exposer = my_class_exposer_t( "my_class" ); 40 boost::python::scope my_class_scope( my_class_exposer ); 41 my_class_exposer.def( ... ); 42 43 Also, the second way is much longer, it solves few problems: 44 45 - you can not expose enums and internal classes defined within the class using first method 46 - you will get much better compilation errors 47 - the code looks like regular C++ code after all :-) 48 49 By default, this property is set to False. Also, Py++ knows pretty well 50 when it have to ignore this property and generate right code 51 """
52 53 -class class_common_details_t( object ):
54 """defines few properties that are common to 55 L{class declaration<pygccxml.declarations.class_declaration_t>} and 56 L{definition<pygccxml.declarations.class_t>} classes 57 """
58 - def __init__(self):
59 object.__init__( self ) 60 self._always_expose_using_scope = None 61 self._indexing_suite = None 62 self._equality_comparable = None 63 self._less_than_comparable = None 64 self._isuite_version = 1 65 self._opaque = False
66
67 - def _get_indexing_suite_version( self ):
68 return self._isuite_version
69 - def _set_indexing_suite_version( self, version ):
70 assert version in ( 1, 2 ) 71 if self._isuite_version != version: 72 self._isuite_version = version 73 self._indexing_suite = None
74 indexing_suite_version = property( _get_indexing_suite_version, _set_indexing_suite_version 75 , doc="indexing suite version") 76 77 @property
78 - def indexing_suite( self ):
79 """reference to indexing suite configuration class. 80 81 If the class is not STD container, this property will contain None" 82 """ 83 if self._indexing_suite is None: 84 if self.container_traits: 85 if self._isuite_version == 1: 86 self._indexing_suite = isuite1.indexing_suite1_t( self ) 87 else: 88 self._indexing_suite = isuite2.indexing_suite2_t( self ) 89 return self._indexing_suite
90 97
99 tmp = self.guess_always_expose_using_scope_value() 100 if tmp == impl_details.GUESS_VALUES.ALWAYS_TRUE: 101 return True 102 if None is self._always_expose_using_scope: 103 if impl_details.GUESS_VALUES.TRUE == tmp: 104 self._always_expose_using_scope = True 105 else: 106 self._always_expose_using_scope = False 107 return self._always_expose_using_scope
108
109 - def _set_always_expose_using_scope( self, value ):
110 self._always_expose_using_scope = value
111 always_expose_using_scope = property( _get_always_expose_using_scope, _set_always_expose_using_scope 112 , doc="please see L{class_wrapper.always_expose_using_scope_documentation} variable for documentation." ) 113
114 - def _get_equality_comparable( self ):
115 if None is self._equality_comparable: 116 self._equality_comparable = declarations.has_public_equal( self ) 117 return self._equality_comparable
118
119 - def _set_equality_comparable( self, value ):
120 self._equality_comparable = value
121 122 equality_comparable = property( _get_equality_comparable, _set_equality_comparable 123 , doc="indicates existence of public operator=" \ 124 +"Default value is calculated, based on information presented in the declarations tree" ) 125
126 - def _get_less_than_comparable( self ):
127 if None is self._less_than_comparable: 128 self._less_than_comparable = declarations.has_public_less( self ) 129 return self._less_than_comparable
130
131 - def _set_less_than_comparable( self, value ):
132 self._less_than_comparable = value
133 134 less_than_comparable = property( _get_less_than_comparable, _set_less_than_comparable 135 , doc="indicates existence of public operator<. " \ 136 +"Default value is calculated, based on information presented in the declarations tree" ) 137
138 - def _get_opaque( self ):
139 return self._opaque
140
141 - def _set_opaque( self, value ):
142 self._opaque = value 143 self.ignore = value #don't expose opaque type
144 145 opaque = property( _get_opaque, _set_opaque 146 , doc="If True, Py++ will treat return types and arguments T* as opaque types." \ 147 +"Thus it will be able to generate code, that uses " \ 148 +" BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID macro in a right places." ) 149 150 @property
151 - def class_var_name(self):
152 return self.alias + '_exposer'
153
154 #this will only be exported if indexing suite is not None and only when needed 155 -class class_declaration_t( class_common_details_t 156 , decl_wrapper.decl_wrapper_t 157 , declarations.class_declaration_t ):
158 - def __init__(self, *arguments, **keywords):
162
163 -class class_t( class_common_details_t 164 , scopedef_wrapper.scopedef_t 165 , declarations.class_t):
166
167 - class EXPOSED_CLASS_TYPE:
168 DECLARED = 'declared' 169 WRAPPER = 'wrapper' 170 ALL = ( DECLARED, WRAPPER )
171 172 FAKE_CONSTRUCTOR_TYPES = ( declarations.member_function_t, declarations.free_function_t ) 173 FAKE_CONSTRUCTOR_TYPE_NAMES = 'member and free functions' 174
175 - def __init__(self, *arguments, **keywords):
176 class_common_details_t.__init__( self ) 177 declarations.class_t.__init__(self, *arguments, **keywords ) 178 scopedef_wrapper.scopedef_t.__init__( self ) 179 180 self._redefine_operators = False 181 self._held_type = None 182 self._noncopyable = None 183 self._wrapper_alias = None 184 self._registration_code_head = [] 185 self._registration_code_tail = [] 186 self._declaration_code = [] 187 self._wrapper_code = [] 188 self._destructor_code = [] 189 self._exception_translation_code = None 190 self._properties = [] 191 self._redefined_funcs = None 192 self._require_self_reference = False 193 self._exposed_class_type = self.EXPOSED_CLASS_TYPE.DECLARED 194 self._expose_this = None 195 self._expose_sizeof = None 196 self._fake_constructors = [] 197 self._no_init = None
198 199 @property
200 - def fake_constructors(self):
201 """list of fake constructors""" 202 return self._fake_constructors
203
204 - def add_fake_constructors( self, f ):
205 """f - reference to a calldef_t object or list of them 206 207 boost::python::make_constructor allows to register a C++ function, as a 208 class constructor. 209 """ 210 if isinstance( f, declarations.calldef_t ): 211 self._fake_constructors.add( f ) 212 else: 213 self._fake_constructors.extend( f )
214
215 - def _get_redefine_operators( self ):
216 return self._redefine_operators
217 - def _set_redefine_operators( self, new_value ):
218 self._redefine_operators = new_value
219 redefine_operators = property( _get_redefine_operators, _set_redefine_operators 220 , doc="tells Py++ to redefine operators from base class in this class, False by default") 221
222 - def _get_exposed_class_type(self):
223 return self._exposed_class_type
224 - def _set_exposed_class_type(self, class_type):
225 assert class_type in self.EXPOSED_CLASS_TYPE.ALL 226 self._class_type = class_type
227 exposed_class_type = property( _get_exposed_class_type, _set_exposed_class_type 228 , doc="set this value to CLASS_TYPE.WRAPPER, if you need to transfer ownership of" \ 229 "polymorphic class" ) 230
231 - def _get_held_type(self):
232 return self._held_type
233 - def _set_held_type(self, held_type):
234 self._held_type = held_type
235 held_type = property( _get_held_type, _set_held_type 236 , doc="string, this property tells Py++ what HeldType this class has" \ 237 +"Default value is calculated, based on information presented in exposed declarations" ) 238
239 - def _get_noncopyable(self):
240 if self._noncopyable is None: 241 self._noncopyable = declarations.is_noncopyable( self ) 242 return self._noncopyable
243 - def _set_noncopyable(self, noncopyable):
244 self._noncopyable= noncopyable
245 noncopyable = property( _get_noncopyable, _set_noncopyable 246 , doc="True if the class is noncopyable, False otherwies" \ 247 +"Default value is calculated, based on information presented in the declarations tree" ) 248
249 - def _get_wrapper_alias( self ):
250 if None is self._wrapper_alias: 251 self._wrapper_alias = self._generate_valid_name(self.partial_name) + "_wrapper" 252 return self._wrapper_alias
253 - def _set_wrapper_alias( self, walias ):
254 self._wrapper_alias = walias
255 wrapper_alias = property( _get_wrapper_alias, _set_wrapper_alias 256 , doc="class-wrapper name") 257 258 @property
259 - def declaration_code( self ):
260 """ 261 List of strings, that contains valid C++ code, that will be added to 262 the class declaration section 263 """ 264 return self._declaration_code
265 266 @property
267 - def registration_code_head( self ):
268 """ 269 List of strings, that contains valid C++ code, that will be added to 270 the head of the class registration section 271 """ 272 return self._registration_code_head
273 274 @property
275 - def registration_code_tail( self ):
276 """ 277 List of strings, that contains valid C++ code, that will be added to 278 the tail of the class registration section 279 """ 280 return self._registration_code_tail
281 282 @property
283 - def registration_code( self ):
284 """ 285 List of strings, that contains all C++ code, that will be added to 286 the class registration section 287 """ 288 return self.registration_code_head + self.registration_code_tail
289 290 @property
291 - def wrapper_code( self ):
292 """ 293 List of strings, that contains valid C++ code, that will be added to 294 the class wrapper. 295 """ 296 return self._wrapper_code
297
299 c = self.find_trivial_constructor() 300 if c: 301 return c.body 302 else: 303 return ''
304 - def _set_null_constructor_body(self, body):
305 c = self.find_trivial_constructor() 306 if c: 307 c.body = body
308 null_constructor_body = property( _get_null_constructor_body, _set_null_constructor_body 309 , doc="null constructor code, that will be added as is to the null constructor of class-wrapper" ) 310
312 c = self.find_copy_constructor() 313 if c: 314 return c.body 315 else: 316 return ''
317
318 - def _set_copy_constructor_body(self, body):
319 c = self.find_copy_constructor() 320 if c: 321 c.body = body
322 copy_constructor_body = property( _get_copy_constructor_body, _set_copy_constructor_body 323 , doc="copy constructor code, that will be added as is to the copy constructor of class-wrapper") 324 325 @property
326 - def destructor_code(self):
327 """list of code to be added to wrapper destructor""" 328 return self._destructor_code
329
330 - def add_destructor_code(self, code):
331 """adds code to the class-wrapper destructor""" 332 self._destructor_code.append( code )
333 334 @property
335 - def exception_argument_name( self ):
336 """exception argument name for translate exception function 337 338 If you don't understand what this argument is, please take a look on 339 Boost.Python documentation: http://www.boost.org/libs/python/doc/v2/exception_translator.html 340 """ 341 return 'exc'
342
344 return self._exception_translation_code
345 - def _set_exception_translation_code( self, code ):
346 self._exception_translation_code = code
347 exception_translation_code = property( _get_exception_translation_code, _set_exception_translation_code 348 , doc="C++ exception to Python exception translation code" \ 349 +"\nExample: PyErr_SetString(PyExc_RuntimeError, exc.what()); " \ 350 +"\nPy++ will generate the rest of the code." \ 351 +"\nPay attention: the exception variable name is exc." ) 352
353 - def translate_exception_to_string( self, python_exception_type, to_string ):
354 """registers exception translation to string 355 356 @param python_exception_type: Python exception type, for example PyExc_RuntimeError 357 @type python_exception_type: str 358 359 @param to_string: C++ expression that extracts information from exception. 360 The type of expression should be char*. 361 @type to_string: str 362 """ 363 #NICE TO HAVE: 364 #1. exception\assert\warning should be raised if python_exception_type 365 # does not contain valid Python exception 366 #2. Py++ can validate, that member function returns char* 367 code = "PyErr_SetString( %(exception_type)s, %(to_string)s ); " \ 368 % { 'exception_type' : python_exception_type, 'to_string' : to_string } 369 self.exception_translation_code = code
370
371 - def add_declaration_code( self, code ):
372 """adds the code to the declaration section""" 373 self.declaration_code.append( user_text.user_text_t( code ) )
374
375 - def add_registration_code( self, code, works_on_instance=True, tail=True ):
376 """adds the code to the class registration section 377 378 @param works_on_instance: If true, the custom code can be applied directly to obj inst. Example: ObjInst.code 379 @type works_on_instance: bool 380 381 @param tail: if True, the custom code is appended to the end of the class registration code. 382 @type tail: bool 383 """ 384 if tail: 385 self.registration_code_tail.append( user_text.class_user_text_t( code, works_on_instance ) ) 386 else: 387 self.registration_code_head.append( user_text.class_user_text_t( code, works_on_instance ) )
388 389 #preserving backward computability 390 add_code = add_registration_code 391
392 - def add_wrapper_code( self, code ):
393 """adds code to the class wrapper class definition""" 394 self.wrapper_code.append( user_text.user_text_t( code ) )
395
396 - def set_constructors_body( self, body ):
397 """Sets the body for all constructors""" 398 constrs = self.constructors(allow_empty=True, recursive=False) 399 if constrs: 400 constrs.body = body 401 self.null_constructor_body = body 402 self.copy_constructor_body = body
403
404 - def _exportable_impl( self ):
405 if not self.name: 406 named_parent = declarations.get_named_parent( self ) 407 if not named_parent: 408 return messages.W1057 % str( self ) 409 if isinstance( named_parent, declarations.namespace_t ): 410 return messages.W1018 % str( self ) 411 if self.class_type == declarations.CLASS_TYPES.UNION: 412 if self.is_wrapper_needed(): 413 return messages.W1059 % str( self ) 414 if self.name: 415 return messages.W1060 % str( self ) 416 if isinstance( self.parent, declarations.namespace_t ): 417 return '' 418 if not self in self.parent.public_members: 419 return messages.W1019 420 return ''
421
422 - def get_exportable_members( self, sort=None ):
423 """returns list of internal declarations that should\\could be exported""" 424 #TODO: obviously this function should be shorter. Almost all logic of this class 425 # should be spread between decl_wrapper classes 426 members = filter( lambda mv: mv.ignore == False and mv.exportable, self.public_members ) 427 #protected and private virtual functions that not overridable and not pure 428 #virtual should not be exported 429 for member in self.protected_members: 430 if not isinstance( member, declarations.calldef_t ): 431 continue 432 else: 433 members.append( member ) 434 435 vfunction_selector = lambda member: isinstance( member, declarations.member_function_t ) \ 436 and member.virtuality == declarations.VIRTUALITY_TYPES.PURE_VIRTUAL 437 members.extend( filter( vfunction_selector, self.private_members ) ) 438 439 def is_exportable( decl ): 440 #filter out non-public member operators - Py++ does not support them right now 441 if isinstance( decl, declarations.member_operator_t ) \ 442 and decl.access_type != declarations.ACCESS_TYPES.PUBLIC: 443 return False 444 #remove artificial constructors 445 if isinstance( decl, declarations.constructor_t ) and decl.is_artificial: 446 return False 447 if decl.ignore == True or decl.exportable == False: 448 return False 449 return True
450 #-#if declarations.has_destructor( self ) \ 451 #-# and not declarations.has_public_destructor( self ): 452 members = filter( is_exportable, members ) 453 sorted_members = members 454 if sort: 455 sorted_members = sort( members ) 456 return sorted_members
457 458 @property
459 - def properties( self ):
460 """list of properties""" 461 return self._properties
462
463 - def add_property( self, name, fget, fset=None, doc='' ):
464 """adds new property to the class 465 466 @param name: name of the property 467 @type name: str 468 469 @param fget: reference to the class member function 470 @param fset: reference to the class member function, could be None 471 @param doc: documentation string 472 """ 473 self._properties.append( properties.property_t( name, fget, fset, doc ) )
474
475 - def add_properties( self, recognizer=None, exclude_accessors=False ):
476 props = properties.find_properties( self, recognizer, exclude_accessors ) 477 self.properties.extend( props )
478
479 - def add_static_property( self, name, fget, fset=None, doc='' ):
480 """adds new static property to the class""" 481 self._properties.append( properties.property_t( name, fget, fset, doc, True ) )
482
483 - def redefined_funcs( self ):
484 """returns list of member functions that should be defined in class wrapper 485 486 It comes useful in 3 tier hierarchy: 487 struct base{ 488 virtual void do_nothing() = 0; 489 }; 490 491 struct derived{ 492 virtual void do_something() = 0; 493 }; 494 495 struct concrete{ 496 virtual void do_nothing(){} 497 virtual void do_something(){} 498 }; 499 500 derived_wrapper should define do_nothing function, otherwise the generated 501 code will not compile 502 """ 503 504 if isinstance( self._redefined_funcs, list ): 505 return self._redefined_funcs 506 507 all_included = declarations.custom_matcher_t( lambda decl: decl.ignore == False and decl.exportable ) 508 all_protected = declarations.access_type_matcher_t( 'protected' ) & all_included 509 all_pure_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.PURE_VIRTUAL ) 510 all_virtual = declarations.virtuality_type_matcher_t( VIRTUALITY_TYPES.VIRTUAL ) \ 511 & ( declarations.access_type_matcher_t( 'public' ) \ 512 | declarations.access_type_matcher_t( 'protected' )) 513 all_not_pure_virtual = ~all_pure_virtual 514 515 query = all_protected | all_pure_virtual 516 mf_query = query | all_virtual 517 relevant_opers = declarations.custom_matcher_t( lambda decl: decl.symbol in ('()', '[]') ) 518 funcs = [] 519 defined_funcs = [] 520 521 for base in self.recursive_bases: 522 if base.access == ACCESS_TYPES.PRIVATE: 523 continue 524 base_cls = base.related_class 525 526 funcs.extend( base_cls.member_functions( mf_query, recursive=False, allow_empty=True ) ) 527 funcs.extend( base_cls.member_operators( relevant_opers & query, recursive=False, allow_empty=True ) ) 528 529 defined_funcs.extend( base_cls.member_functions( all_not_pure_virtual, recursive=False, allow_empty=True ) ) 530 defined_funcs.extend( base_cls.member_operators( all_not_pure_virtual & relevant_opers, recursive=False, allow_empty=True ) ) 531 532 not_reimplemented_funcs = set() 533 is_same_function = declarations.is_same_function 534 for f in funcs: 535 cls_fs = self.calldefs( name=f.name, recursive=False, allow_empty=True ) 536 for cls_f in cls_fs: 537 if is_same_function( f, cls_f ): 538 break 539 else: 540 #should test whether this function has been added or not 541 for f_impl in not_reimplemented_funcs: 542 if is_same_function( f, f_impl ): 543 if declarations.is_base_and_derived( f_impl.parent, f.parent ): 544 #add function from the most derived class 545 not_reimplemented_funcs.remove( f_impl ) 546 not_reimplemented_funcs.add( f ) 547 break 548 else: 549 #should test whether this function is implemented in base class 550 if f.virtuality != VIRTUALITY_TYPES.PURE_VIRTUAL: 551 not_reimplemented_funcs.add( f ) 552 else: 553 for f_defined in defined_funcs: 554 if is_same_function( f, f_defined ): 555 break 556 else: 557 not_reimplemented_funcs.add( f ) 558 functions = filter( lambda f: ( False == f.ignore and True == f.exportable ) 559 or all_pure_virtual( f ) 560 , list( not_reimplemented_funcs ) ) 561 562 563 #Boost.Python is not able to call for non-virtual function, from the base 564 #class if there is a virtual function with the same within base class 565 #See override_bug tester for more information 566 567 def buggy_bpl_filter( f ): 568 if f.parent is self: 569 return False 570 if f.access_type != ACCESS_TYPES.PUBLIC: 571 return False 572 if f.virtuality != VIRTUALITY_TYPES.NOT_VIRTUAL: 573 return False 574 #we need to check that we don't have "same" function in this class 575 this_funs = self.decls( name=f.name 576 , decl_type=declarations.calldef_t 577 , recursive=False 578 , allow_empty=True ) 579 for this_f in this_funs: 580 if is_same_function( this_f, f ): 581 #there is already the function in the class, so no need to redefined it 582 return False 583 else: 584 return True
585 586 tmp = {} # id : f 587 for redefined_f in functions: 588 #redefined is virtual, I am not interested in virtual functions 589 for rfo in redefined_f.overloads: 590 if id(rfo) in tmp: 591 continue 592 if buggy_bpl_filter( rfo ): 593 tmp[ id(rfo) ] = rfo 594 functions.extend( tmp.values() ) 595 596 functions.sort( cmp=lambda f1, f2: cmp( ( f1.name, f1.location.as_tuple() ) 597 , ( f2.name, f2.location.as_tuple() ) ) ) 598 599 self._redefined_funcs = functions 600 return self._redefined_funcs 601
602 - def is_wrapper_needed(self):
603 """returns an explanation( list of str ) why wrapper is needed. 604 605 If wrapper is not needed than [] will be returned. 606 """ 607 explanation = [] 608 if self.wrapper_code: 609 explanation.append( messages.W1020 ) 610 611 if self.null_constructor_body: 612 explanation.append( messages.W1021 ) 613 614 if self.copy_constructor_body: 615 explanation.append( messages.W1022 ) 616 617 if self.destructor_code: 618 explanation.append( messages.W1055 ) 619 620 redefined_funcs = self.redefined_funcs() 621 if redefined_funcs: 622 funcs = map( lambda f: f.name, redefined_funcs ) 623 explanation.append( messages.W1023 % ', '.join(funcs) ) 624 625 for member in self.get_exportable_members(): 626 if isinstance( member, declarations.destructor_t ): 627 continue 628 if isinstance( member, declarations.variable_t ): 629 explanation.extend( member.is_wrapper_needed() ) 630 if isinstance( member, declarations.class_t ) and member.is_wrapper_needed(): 631 explanation.append( messages.W1028 % member.name) 632 if isinstance( member, declarations.calldef_t ): 633 if isinstance( member, declarations.constructor_t ) and member.body: 634 explanation.append( messages.W1029 ) 635 if member.virtuality != VIRTUALITY_TYPES.NOT_VIRTUAL: 636 explanation.append( messages.W1030 % member.name ) 637 if member.access_type in ( ACCESS_TYPES.PROTECTED, ACCESS_TYPES.PRIVATE ): 638 explanation.append( messages.W1031 % member.name) 639 return explanation
640
641 - def _readme_impl( self ):
642 explanation = self.is_wrapper_needed() 643 for fc in self.fake_constructors: 644 if fc.ignore: 645 explanation.append( messages.W1062 % ( str( self ), str( fc ) ) ) 646 if not fc.exportable: 647 explanation.append( messages.W1063 % ( str( self ), str( fc ) ) ) 648 if not isinstance( fc, self.FAKE_CONSTRUCTOR_TYPES ): 649 explanation.append( messages.W1064 650 % ( str( fc ), str( self ), self.FAKE_CONSTRUCTOR_TYPE_NAMES ) ) 651 return explanation
652
653 - def guess_always_expose_using_scope_value( self ):
654 def is_assign( oper ): 655 if oper.symbol != '=': 656 return False 657 if oper.is_artificial: 658 return False 659 if oper.access_type != ACCESS_TYPES.PUBLIC: 660 return False 661 return True
662 #MSVC 7.1 has problem with taking reference to operator= 663 if self.member_operators( is_assign, allow_empty=True, recursive=False ): 664 return impl_details.GUESS_VALUES.ALWAYS_TRUE 665 return super(class_t, self).guess_always_expose_using_scope_value() 666
667 - def _get_require_self_reference(self):
668 return self._require_self_reference
669 - def _set_require_self_reference(self, require_self_reference):
670 self._require_self_reference = require_self_reference
671 require_self_reference = property( _get_require_self_reference, _set_require_self_reference 672 , doc="boolean, if True the first argument to the constructor will be reference to self object" ) 673
674 - def _get_expose_this( self ):
675 return self._expose_this
676 - def _set_expose_this( self, new_value ):
677 self._expose_this = new_value
678 expose_this = property( _get_expose_this, _set_expose_this 679 , doc="boolean, if True an object address( this pointer ) will be exposed to Python as integer.") 680
681 - def _get_expose_sizeof( self ):
682 return self._expose_sizeof
683 - def _set_expose_sizeof( self, new_value ):
684 self._expose_sizeof = new_value
685 expose_sizeof = property( _get_expose_sizeof, _set_expose_sizeof 686 , doc="boolean, if True the sizeof(obj) will be exposed to Python as integer.") 687 688 @property
689 - def introduces_new_scope(self):
690 """returns True, if during exposing this class, new scope will be created 691 692 For example, anonymous structs will be exposed in a parent scope. 693 """ 694 if not self.name: 695 return False 696 elif self.class_type == declarations.CLASS_TYPES.UNION: 697 return False 698 else: 699 return True
700
701 - def _get_no_init( self ):
702 if None is self._no_init and False == bool( self.indexing_suite ): 703 #select all public constructors and exclude copy constructor 704 cs = self.constructors( lambda c: not c.is_copy_constructor and c.access_type == 'public' 705 , recursive=False, allow_empty=True ) 706 707 has_suitable_constructor = bool( cs ) 708 if cs and len(cs) == 1 and cs[0].is_trivial_constructor and self.find_noncopyable_vars(): 709 has_suitable_constructor = False 710 711 has_nonpublic_destructor = declarations.has_destructor( self ) \ 712 and not declarations.has_public_destructor( self ) 713 714 trivial_constructor = self.find_trivial_constructor() 715 716 if has_nonpublic_destructor \ 717 or ( self.is_abstract and not self.is_wrapper_needed() ) \ 718 or not has_suitable_constructor: 719 self._no_init = True 720 elif not trivial_constructor or trivial_constructor.access_type != 'public': 721 exportable_cs = filter( lambda c: c.exportable and c.ignore == False 722 , cs ) 723 if not exportable_cs: 724 self._no_init = True 725 else: 726 pass 727 if None is self._no_init: 728 self._no_init = False 729 return self._no_init
730 - def _set_no_init( self, value ):
731 self._no_init = value
732 733 no_init = property( _get_no_init, _set_no_init 734 , doc="If True, class will be registered with 'boost::python::no_init'" ) 735