Package pyplusplus :: Package decl_wrappers :: Module call_policies

Source Code for Module pyplusplus.decl_wrappers.call_policies

  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  """Contains definition of call policies classes""" 
  7   
  8  import algorithm 
  9  import python_traits 
 10  from pygccxml import declarations 
11 12 #keeps file name, where Py++ defined call policies will be defined 13 PYPP_CALL_POLICIES_HEADER_FILE = "__call_policies.pypp.hpp" 14 15 -class CREATION_POLICY:
16 """Implementation details""" 17 AS_INSTANCE = 'as instance' 18 AS_TEMPLATE_ARGUMENT = 'as template argument'
19
20 -class call_policy_t(object):
21 """base class for all classes, which generate "call policies" code"""
22 - def __init__(self):
23 object.__init__(self)
24
25 - def create(self, function_creator, creation_policy=CREATION_POLICY.AS_INSTANCE):
26 """Creates code from the call policies class instance. 27 @param function_creator: parent code creator 28 @type function_creator: L{code_creators.function_t} or L{code_creators.constructor_t} 29 30 @param creation_policy: indicates whether we this call policy used as template 31 argument or as an instance 32 @type creation_policy: L{CREATION_POLICY} 33 """ 34 code = self._create_impl( function_creator ) 35 if code and creation_policy == CREATION_POLICY.AS_INSTANCE: 36 code = code + '()' 37 return code
38
39 - def create_type(self):
40 """return call policies class declaration as string""" 41 return self.create( None, CREATION_POLICY.AS_TEMPLATE_ARGUMENT )
42
43 - def create_template_arg( self, function_creator ):
44 """return call policies class declaration as string""" 45 return self.create( function_creator, CREATION_POLICY.AS_TEMPLATE_ARGUMENT )
46
47 - def is_default( self ):
48 """return True is self is instance of L{default_call_policies_t} class""" 49 return False
50
51 - def is_predefined( self ):
52 """return True if call policy is defined in Boost.Python library, False otherwise""" 53 return True
54
55 - def _create_impl( self, function_creator ):
56 raise NotImplementedError()
57 58 @property
59 - def header_file(self):
60 """return a name of the header file the call policy is defined in""" 61 return "boost/python.hpp"
62
63 -class default_call_policies_t(call_policy_t):
64 """implements code generation for boost::python::default_call_policies"""
65 - def __init__( self ):
66 call_policy_t.__init__( self )
67
68 - def _create_impl(self, function_creator ):
69 return algorithm.create_identifier( function_creator, '::boost::python::default_call_policies' )
70
71 - def is_default( self ):
72 return True
73
74 - def __str__(self):
75 return 'default_call_policies'
76
77 -def default_call_policies():
78 """create ::boost::python::default_call_policies call policies code generator""" 79 return default_call_policies_t()
80
81 -class compound_policy_t( call_policy_t ):
82 """base class for all call policies, except the default one"""
83 - def __init__( self, base=None ):
84 call_policy_t.__init__( self ) 85 self._base = base 86 if not base: 87 self._base = default_call_policies_t()
88
89 - def _get_base_policy( self ):
90 return self._base
91 - def _set_base_policy( self, new_policy ):
92 self._base = new_policy
93 base_policy = property( _get_base_policy, _set_base_policy 94 , doc="base call policy, by default is reference to L{default_call_policies_t} call policy") 95
96 - def _get_args(self, function_creator):
97 return []
98
99 - def _get_name(self, function_creator):
100 raise NotImplementedError()
101
102 - def _create_impl( self, function_creator ):
103 args = self._get_args(function_creator) 104 if not self._base.is_default(): 105 args.append( self._base.create( function_creator, CREATION_POLICY.AS_TEMPLATE_ARGUMENT ) ) 106 name = algorithm.create_identifier( function_creator, self._get_name(function_creator) ) 107 return declarations.templates.join( name, args )
108
109 - def __str__(self):
110 name = self._get_name(None).replace('::boost::python::', '' ) 111 args = map( lambda text: text.replace( '::boost::python::', '' ) 112 , self._get_args( None ) ) 113 return declarations.templates.join( name, args )
114
115 -class return_argument_t( compound_policy_t ):
116 """implements code generation for boost::python::return_argument call policies"""
117 - def __init__( self, position=1, base=None):
118 compound_policy_t.__init__( self, base ) 119 self._position = position
120
121 - def _get_position( self ):
122 return self._position
123 - def _set_position( self, new_position):
124 self._position = new_position
125 position = property( _get_position, _set_position ) 126
127 - def _get_name(self, function_creator):
128 if self.position == 1: 129 return '::boost::python::return_self' 130 else: 131 return '::boost::python::return_arg'
132
133 - def _get_args(self, function_creator):
134 if self.position == 1: 135 return [] 136 else: 137 return [ str( self.position ) ]
138
139 -def return_arg( arg_pos, base=None ):
140 """create boost::python::return_arg call policies code generator""" 141 return return_argument_t( arg_pos, base )
142
143 -def return_self(base=None):
144 """create boost::python::return_self call policies code generator""" 145 return return_argument_t( 1, base )
146
147 -class return_internal_reference_t( compound_policy_t ):
148 """implements code generation for boost::python::return_internal_reference call policies"""
149 - def __init__( self, position=1, base=None):
150 compound_policy_t.__init__( self, base ) 151 self._position = position
152
153 - def _get_position( self ):
154 return self._position
155 - def _set_position( self, new_position):
156 self._position = new_position
157 position = property( _get_position, _set_position ) 158
159 - def _get_name(self, function_creator):
160 return '::boost::python::return_internal_reference'
161
162 - def _get_args(self, function_creator):
163 if self.position == 1: 164 return [] #don't generate default template arguments 165 else: 166 return [ str( self.position ) ]
167
168 -def return_internal_reference( arg_pos=1, base=None):
169 """create boost::python::return_internal_reference call policies code generator""" 170 return return_internal_reference_t( arg_pos, base )
171
172 -class with_custodian_and_ward_t( compound_policy_t ):
173 """implements code generation for boost::python::with_custodian_and_ward call policies"""
174 - def __init__( self, custodian, ward, base=None):
175 compound_policy_t.__init__( self, base ) 176 self._custodian = custodian 177 self._ward = ward
178
179 - def _get_custodian( self ):
180 return self._custodian
181 - def _set_custodian( self, new_custodian):
182 self._custodian = new_custodian
183 custodian = property( _get_custodian, _set_custodian ) 184
185 - def _get_ward( self ):
186 return self._ward
187 - def _set_ward( self, new_ward):
188 self._ward = new_ward
189 ward = property( _get_ward, _set_ward ) 190
191 - def _get_name(self, function_creator):
192 return '::boost::python::with_custodian_and_ward'
193
194 - def _get_args(self, function_creator):
195 return [ str( self.custodian ), str( self.ward ) ]
196
197 -def with_custodian_and_ward( custodian, ward, base=None):
198 """create boost::python::with_custodian_and_ward call policies code generator""" 199 return with_custodian_and_ward_t( custodian, ward, base )
200
201 -class with_custodian_and_ward_postcall_t( with_custodian_and_ward_t ):
202 """implements code generation for boost::python::with_custodian_and_ward_postcall call policies"""
203 - def __init__( self, custodian, ward, base=None):
205
206 - def _get_name(self, function_creator):
207 return '::boost::python::with_custodian_and_ward_postcall'
208
209 -def with_custodian_and_ward_postcall( custodian, ward, base=None):
210 """create boost::python::with_custodian_and_ward_postcall call policies code generator""" 211 return with_custodian_and_ward_postcall_t( custodian, ward, base )
212
213 -class return_value_policy_t( compound_policy_t ):
214 """implements code generation for boost::python::return_value_policy call policies"""
215 - def __init__( self, result_converter_generator, base=None):
216 compound_policy_t.__init__( self, base ) 217 self._result_converter_generator = result_converter_generator
218
220 return self._result_converter_generator
221 - def _set_result_converter_generator( self, new_result_converter_generator):
222 self._result_converter_generator = new_result_converter_generator
223 result_converter_generator = property( _get_result_converter_generator 224 , _set_result_converter_generator ) 225
226 - def _get_name(self, function_creator):
227 return '::boost::python::return_value_policy'
228
229 - def _get_args(self, function_creator):
230 if function_creator: 231 rcg = algorithm.create_identifier( function_creator, self.result_converter_generator ) 232 return [ rcg ] 233 else: 234 return [self.result_converter_generator]
235
236 - def is_predefined( self ):
237 """Returns True if call policy is defined in Boost.Python library, False otherwise""" 238 global return_addressof 239 global return_pointee_value 240 if self.result_converter_generator in (return_pointee_value, return_addressof ): 241 return False 242 else: 243 return True
244 245 @property
246 - def header_file(self):
247 """Return name of the header file to be included""" 248 if self.is_predefined(): 249 return super( return_value_policy_t, self ).header_file 250 else: 251 return PYPP_CALL_POLICIES_HEADER_FILE
252 253 254 copy_const_reference = '::boost::python::copy_const_reference' 255 copy_non_const_reference = '::boost::python::copy_non_const_reference' 256 manage_new_object = '::boost::python::manage_new_object' 257 reference_existing_object = '::boost::python::reference_existing_object' 258 return_by_value = '::boost::python::return_by_value' 259 return_opaque_pointer = '::boost::python::return_opaque_pointer' 260 return_pointee_value = '::pyplusplus::call_policies::return_pointee_value' 261 return_addressof = '::pyplusplus::call_policies::return_addressof'
262 263 -def return_value_policy( result_converter_generator, base=None):
264 """create boost::python::return_value_policy call policies code generator""" 265 return return_value_policy_t( result_converter_generator, base )
266
267 -def is_return_opaque_pointer_policy( policy ):
268 """returns True is policy represents return_value_policy<return_opaque_pointer>, False otherwise""" 269 return isinstance( policy, return_value_policy_t ) \ 270 and policy.result_converter_generator == return_opaque_pointer
271
272 -class custom_call_policies_t(call_policy_t):
273 """implements code generation for user defined call policies"""
274 - def __init__( self, call_policies, header_file=None ):
275 call_policy_t.__init__( self ) 276 self.__call_policies = call_policies 277 self.__header_file = header_file
278
279 - def _create_impl(self, function_creator ):
280 return str( self.__call_policies )
281
282 - def __str__(self):
283 return 'custom call policies'
284
285 - def get_header_file( self ):
286 return self.__header_file
287 - def set_header_file( self, header_file_name ):
288 self.__header_file = header_file_name
289 header_file = property( get_header_file, set_header_file 290 , doc="""Return name of the header file to be included""" )
291
292 -def custom_call_policies(call_policies, header_file=None):
293 """create custom\\user defined call policies code generator""" 294 return custom_call_policies_t(call_policies, header_file)
295
296 -class memory_managers:
297 """implements code generation for Py++ defined memory managers 298 299 For complete documentation and usage example see http://language-binding.net/pyplusplus/documentation/functions/call_policies.html 300 """ 301 none = 'none' 302 delete_ = 'delete_' 303 all = [ none, delete_ ] 304 305 @staticmethod
306 - def create( manager, function_creator=None):
307 mem_manager = 'pyplusplus::call_policies::memory_managers::' + manager 308 if function_creator: 309 mem_manager = algorithm.create_identifier( function_creator, mem_manager ) 310 return mem_manager
311
312 -class convert_array_to_tuple_t( compound_policy_t ):
313 """implements code generation for Py++ defined "as_tuple" value policy 314 315 For complete documentation and usage example see http://language-binding.net/pyplusplus/documentation/functions/call_policies.html 316 """
317 - def __init__( self, array_size, memory_manager, make_object_call_policies=None, base=None):
318 compound_policy_t.__init__( self, base ) 319 self._array_size = array_size 320 self._memory_manager = memory_manager 321 self._make_objec_call_policies = make_object_call_policies
322
323 - def is_predefined( self ):
324 """Returns True if call policy is defined in Boost.Python library, False otherwise""" 325 return False
326 327 @property
328 - def header_file(self):
329 """Return name of the header file to be included""" 330 return PYPP_CALL_POLICIES_HEADER_FILE
331
332 - def _get_array_size( self ):
333 return self._array_size
334 - def _set_array_size( self, new_array_size):
335 self._array_size = new_array_size
336 array_size = property( _get_array_size, _set_array_size ) 337
338 - def _get_memory_manager( self ):
339 return self._memory_manager
340 - def _set_memory_manager( self, new_memory_manager):
341 self._memory_manager = new_memory_manager
342 memory_manager = property( _get_memory_manager, _set_memory_manager ) 343
345 if None is self._make_objec_call_policies: 346 self._make_objec_call_policies = default_call_policies() 347 return self._make_objec_call_policies
348 - def _set_make_objec_call_policies( self, new_make_objec_call_policies):
349 self._make_objec_call_policies = new_make_objec_call_policies
350 make_objec_call_policies = property( _get_make_objec_call_policies, _set_make_objec_call_policies ) 351
352 - def _get_name(self, function_creator):
353 return '::boost::python::return_value_policy'
354
355 - def _get_args(self, function_creator):
356 as_tuple_args = [ str( self.array_size ) ] 357 as_tuple_args.append( memory_managers.create( self.memory_manager, function_creator ) ) 358 if not self.make_objec_call_policies.is_default(): 359 as_tuple_args.append( self.make_objec_call_policies.create_template_arg( function_creator ) ) 360 as_tuple = '::pyplusplus::call_policies::arrays::as_tuple' 361 if function_creator: 362 as_tuple = algorithm.create_identifier( function_creator, as_tuple ) 363 return [ declarations.templates.join( as_tuple, as_tuple_args ) ]
364
365 -def convert_array_to_tuple( array_size, memory_manager, make_object_call_policies=None, base=None ):
366 """create boost::python::return_value_policy< py++::as_tuple > call policies code generator""" 367 return convert_array_to_tuple_t( array_size, memory_manager, make_object_call_policies, base )
368
369 -class return_range_t( call_policy_t ):
370 """implements code generation for Py++ defined "return_range" call policies 371 372 For complete documentation and usage example see http://language-binding.net/pyplusplus/documentation/functions/call_policies.html 373 """ 374 HEADER_FILE = "__return_range.pypp.hpp"
375 - def __init__( self, get_size_class, value_type, value_policies):
376 call_policy_t.__init__( self ) 377 self._value_type = value_type 378 self._get_size_class = get_size_class 379 self._value_policies = value_policies
380
381 - def is_predefined( self ):
382 """Returns True if call policy is defined in Boost.Python library, False otherwise""" 383 return False
384 385 @property
386 - def header_file(self):
387 """Return name of the header file to be included""" 388 return self.HEADER_FILE
389
390 - def _get_get_size_class( self ):
391 return self._get_size_class
392 - def _set_get_size_class( self, new_get_size_class):
393 self._get_size_class = new_get_size_class
394 get_size_class = property( _get_get_size_class, _set_get_size_class ) 395
396 - def _get_value_type( self ):
397 return self._value_type
398 - def _set_value_type( self, new_value_type):
399 self._value_type = new_value_type
400 value_type = property( _get_value_type, _set_value_type ) 401
402 - def _get_value_policies( self ):
403 return self._value_policies
404 - def _set_value_policies( self, new_value_policies):
405 self._value_policies = new_value_policies
406 value_policies = property( _get_value_policies, _set_value_policies ) 407
408 - def _create_impl(self, function_creator ):
409 name = algorithm.create_identifier( function_creator, '::pyplusplus::call_policies::return_range' ) 410 args = [ self.get_size_class, self.value_type.decl_string ] 411 if not self.value_policies.is_default(): 412 args.append( self.value_policies.create_type() ) 413 return declarations.templates.join( name, args )
414
415 -def return_range( function, get_size_class, value_policies=None ):
416 """create Py++ defined return_range call policies code generator""" 417 r_type = function.return_type 418 if not declarations.is_pointer( r_type ): 419 raise TypeError( 'Function "%s" return type should be pointer, got "%s"' 420 % r_type.decl_string ) 421 422 value_type = declarations.remove_pointer( r_type ) 423 if None is value_policies: 424 if python_traits.is_immutable( value_type ): 425 value_policies = default_call_policies() 426 else: 427 raise RuntimeError( "return_range call policies requieres specification of value_policies" ) 428 return return_range_t( get_size_class, value_type, value_policies )
429