Trees | Indices | Help |
|
---|
|
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 global and member variable exposing""" 7 8 import decl_wrapper 9 import python_traits 10 import call_policies 11 import python_traits 12 from pyplusplus import messages 13 from pygccxml import declarations 1416 """defines a set of properties, that will instruct Py++ how to expose the variable"""23718 declarations.variable_t.__init__(self, *arguments, **keywords ) 19 decl_wrapper.decl_wrapper_t.__init__( self ) 20 self._getter_call_policies = None 21 self._setter_call_policies = None 22 self._apply_smart_ptr_wa = False 23 self._is_read_only = None 24 self._use_make_functions = None 25 self._expose_address = None 26 self._expose_value = None27 28 __call_policies_doc__ = \ 29 """There are usecase, when exporting member variable forces Py++ to 30 create accessors functions. Sometime, those functions requires call policies. 31 To be more specific: when you export member variable that has reference or 32 pointer type, you need to tell Boost.Python library how to manage object 33 life-time. In all cases, Py++ will give reasonable default value. I am 34 sure, that there are use cases, when you will have to change it. You should 35 use this property to change it. 36 """ 3739 if None is self._getter_call_policies: 40 if self.apply_smart_ptr_wa: 41 value_policy = '' 42 if self.is_read_only: 43 value_policy = call_policies.copy_const_reference 44 else: 45 value_policy = call_policies.copy_non_const_reference 46 self._getter_call_policies = call_policies.return_value_policy( value_policy ) 47 elif self.use_make_functions: 48 self._getter_call_policies = call_policies.return_internal_reference() 49 else: 50 pass 51 return self._getter_call_policies53 self._getter_call_policies = call_policies54 getter_call_policies = property( get_getter_call_policies, set_getter_call_policies 55 , doc=__call_policies_doc__ ) 5658 if None is self._getter_call_policies: 59 if self.apply_smart_ptr_wa or self.use_make_functions: 60 self._setter_call_policies = call_policies.default_call_policies() 61 return self._setter_call_policies63 self._setter_call_policies = call_policies64 setter_call_policies = property( get_setter_call_policies, set_setter_call_policies 65 , doc=__call_policies_doc__ ) 66 67 __use_make_functions_doc__ = \ 68 """Generate code using make_getter and make_setter functions 69 70 Basically you don't need to use this, untill you have one of the next use-cases: 71 * member variable is smart pointer - in this case Boost.Python has small problem 72 to expose it right. Using the functions is a work around to the problem. 73 * member variable defined custom r-value converter - may be you don't know 74 but the conversion is applied only on functions arguments. So you need to 75 use make_getter/make_setter in order to allow user to enjoy from the 76 conversion. 77 78 Setting "apply_smart_ptr_wa" and/or "use_make_functions" to "True" will tell 79 Py++ to generate such code. 80 """ 8185 self._apply_smart_ptr_wa = value86 apply_smart_ptr_wa = property( get_apply_smart_ptr_wa, set_apply_smart_ptr_wa 87 , doc=__use_make_functions_doc__ ) 8892 self._use_make_functions = value93 use_make_functions = property( get_use_make_functions, set_use_make_functions 94 , doc=__use_make_functions_doc__) 9597 type_ = declarations.remove_alias( self.type ) 98 type_ = declarations.remove_const( type_ ) 99 type_ = declarations.remove_pointer( type_ ) 100 if not declarations.class_traits.is_my_case( type_ ): 101 return False 102 cls = declarations.class_traits.get_declaration( type_ ) 103 if cls.class_type == declarations.CLASS_TYPES.UNION: 104 return True 105 elif not cls.name: 106 return True 107 else: 108 return False109 110 __expose_address_doc__ = \ 111 """There are some cases when Boost.Python doesn't provide a convenient way 112 to expose the variable to Python. For example: 113 114 double* x[10]; 115 //or 116 char* buffer; //in case you want to modify the buffer in place 117 118 In this cases Py++ doesn't help too. In these cases it is possible to expose 119 the actual address of the variable. After that, you can use built-in "ctypes" 120 package to edit the content of the variable. 121 """123 if None is self._expose_address: 124 self._expose_address = self.__should_be_exposed_by_address_only() 125 return self._expose_address127 self._expose_address = value128 expose_address = property( get_expose_address, set_expose_address 129 , doc= __expose_address_doc__ ) 130 131 __expose_value_doc__ = \ 132 """Boost.Python is not able to expose unions. Using ctypes module 133 it is possible to get access to the data stored in a variable, which 134 has some union type. 135 136 This property controls whether Py++ should expose the variable value 137 or not. In case, this variable has type union, this property will be False. 138 """140 if None is self._expose_value: 141 self._expose_value = not self.__should_be_exposed_by_address_only() 142 return self._expose_value144 self._expose_value = value145 expose_value = property( get_expose_value, set_expose_value 146 , doc= __expose_value_doc__ ) 147149 type_ = declarations.remove_alias( self.type ) 150 151 if isinstance( type_, declarations.const_t ): 152 return True 153 154 if declarations.is_pointer( type_ ): 155 type_ = declarations.remove_pointer( type_ ) 156 157 if declarations.is_reference( type_ ): 158 type_ = declarations.remove_reference( type_ ) 159 160 if isinstance( type_, declarations.const_t ): 161 return True 162 163 if self.apply_smart_ptr_wa: 164 return False #all smart pointers has assign operator 165 166 if isinstance( type_, declarations.declarated_t ) \ 167 and isinstance( type_.declaration, declarations.class_t ) \ 168 and not declarations.has_public_assign( type_.declaration ): 169 return True 170 return False171173 if None is self._is_read_only: 174 self._is_read_only = self.__find_out_is_read_only() 175 return self._is_read_only178 is_read_only = property( get_is_read_only, set_is_read_only ) 179181 if not self.parent.name and self.is_wrapper_needed(): 182 #return messages.W1057 % str( self ) 183 return messages.W1058 % str( self ) 184 if not self.name: 185 return messages.W1033 186 if self.bits == 0 and self.name == "": 187 return messages.W1034 188 if not self.expose_address: 189 if declarations.is_array( self.type ) and declarations.array_size( self.type ) < 1: 190 return messages.W1045 191 type_ = declarations.remove_alias( self.type ) 192 type_ = declarations.remove_const( type_ ) 193 if declarations.is_pointer( type_ ): 194 if not self.expose_address and self.type_qualifiers.has_static: 195 return messages.W1035 196 if not self.expose_address and python_traits.is_immutable( type_.base ): 197 return messages.W1036 198 199 units = declarations.decompose_type( type_ ) 200 ptr2functions = filter( lambda unit: isinstance( unit, declarations.calldef_type_t ) 201 , units ) 202 if ptr2functions: 203 return messages.W1037 204 type_ = declarations.remove_pointer( type_ ) 205 if declarations.class_traits.is_my_case( type_ ): 206 cls = declarations.class_traits.get_declaration( type_ ) 207 if not cls.name: 208 return messages.W1038 209 #if cls.class_type == declarations.CLASS_TYPES.UNION: 210 # return messages.W1061 % ( str( self ), str( cls ) ) 211 if isinstance( self.parent, declarations.class_t ): 212 if self.access_type != declarations.ACCESS_TYPES.PUBLIC: 213 return messages.W1039 214 if declarations.is_array( type_ ): 215 item_type = declarations.array_item_type( type_ ) 216 if declarations.is_pointer( item_type ): 217 item_type_no_ptr = declarations.remove_pointer( item_type ) 218 if python_traits.is_immutable( item_type_no_ptr ): 219 return messages.W1056 220 return ''221223 """returns an explanation( list of str ) why wrapper is needed. 224 225 If wrapper is not needed than [] will be returned. 226 """ 227 explanation = [] 228 if self.bits: 229 explanation.append( messages.W1024 % self.name ) 230 if declarations.is_pointer( self.type ): 231 explanation.append( messages.W1025 % self.name ) 232 if declarations.is_reference( self.type ): 233 explanation.append( messages.W1026 % self.name ) 234 if declarations.is_array( self.type ): 235 explanation.append( messages.W1027 % self.name) 236 return explanation
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Mon Oct 20 08:51:39 2008 | http://epydoc.sourceforge.net |