def is_related(t1, t2): """Check whether two types\\classes t1 and t2 could introduce the problem""" if declarations.is_pointer(t1) and declarations.is_pointer(t2): return registration_order.is_related( declarations.remove_pointer(t1), declarations.remove_pointer(t2)) elif declarations.is_pointer(t1) and not declarations.is_pointer(t2): t1 = declarations.remove_cv(declarations.remove_pointer(t1)) t2 = declarations.remove_cv(t2) if declarations.is_same(t1, t2): return 1 elif not declarations.is_pointer(t1) and declarations.is_pointer(t2): t1 = declarations.remove_cv(t1) t2 = declarations.remove_cv(declarations.remove_pointer(t2)) if declarations.is_same(t1, t2): return -1 else: #not is_pointer( t1 ) and not is_pointer( t2 ): if declarations.is_integral( t1 ) and not declarations.is_bool( t1 ) \ and declarations.is_bool( t2 ): return -1 elif declarations.is_bool( t1 ) \ and declarations.is_integral( t2 ) and not declarations.is_bool( t2 ): return 1 else: pass return None
def is_related( t1, t2 ): """Check whether two types\\classes t1 and t2 could introduce the problem""" if declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): return registration_order.is_related( declarations.remove_pointer( t1 ) , declarations.remove_pointer( t2 ) ) elif declarations.is_pointer( t1 ) and not declarations.is_pointer( t2 ): t1 = declarations.remove_cv( declarations.remove_pointer( t1 ) ) t2 = declarations.remove_cv( t2 ) if declarations.is_same( t1, t2 ): return 1 elif not declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): t1 = declarations.remove_cv( t1 ) t2 = declarations.remove_cv( declarations.remove_pointer( t2 ) ) if declarations.is_same( t1, t2 ): return -1 else: #not is_pointer( t1 ) and not is_pointer( t2 ): if declarations.is_integral( t1 ) and not declarations.is_bool( t1 ) \ and declarations.is_bool( t2 ): return -1 elif declarations.is_bool( t1 ) \ and declarations.is_integral( t2 ) and not declarations.is_bool( t2 ): return 1 else: pass return None
def test_is_same(self): self.assertTrue( declarations.is_same( declarations.int_t, declarations.int_t)) self.assertFalse( declarations.is_same( declarations.int_t, declarations.float_t))
def test_is_same(self): self.assertTrue( declarations.is_same( declarations.int_t, declarations.int_t)) self.failIf( declarations.is_same( declarations.int_t, declarations.float_t))
def test_is_same(self): self.failUnless( declarations.is_same( declarations.int_t, declarations.int_t)) self.failIf( declarations.is_same( declarations.int_t, declarations.float_t))
def visit_reference( self ): no_ref = declarations.remove_const( declarations.remove_reference( self.user_type ) ) if declarations.is_same( declarations.char_t(), no_ref ): return "ctypes.c_char_p" elif declarations.is_same( declarations.wchar_t(), no_ref ): return "ctypes.c_wchar_p" elif declarations.is_same( declarations.void_t(), no_ref ): return "ctypes.c_void_p" else: base_visitor = self.create_converter( self.user_type.base ) internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type ) return "ctypes.POINTER( %s )" % internal_type_str
def __call__( self, calldef, hint=None ): if not isinstance( calldef, declarations.calldef_t ): return None if isinstance( calldef, declarations.constructor_t ): return None return_type = declarations.remove_alias( calldef.return_type ) void_ptr = declarations.pointer_t( declarations.void_t() ) const_void_ptr = declarations.pointer_t( declarations.const_t( declarations.void_t() ) ) if declarations.is_same( return_type, void_ptr ) \ or declarations.is_same( return_type, const_void_ptr ): return decl_wrappers.return_value_policy( decl_wrappers.return_opaque_pointer ) return None
def visit_reference(self): no_ref = declarations.remove_const( declarations.remove_reference(self.user_type)) if declarations.is_same(declarations.char_t(), no_ref): return "ctypes.c_char_p" elif declarations.is_same(declarations.wchar_t(), no_ref): return "ctypes.c_wchar_p" elif declarations.is_same(declarations.void_t(), no_ref): return "ctypes.c_void_p" else: base_visitor = self.create_converter(self.user_type.base) internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type) return "ctypes.POINTER( %s )" % internal_type_str
def visit_pointer( self ): no_ptr = declarations.remove_const( declarations.remove_pointer( self.user_type ) ) if declarations.is_same( declarations.char_t(), no_ptr ) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_char_p" elif declarations.is_same( declarations.wchar_t(), no_ptr ) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_wchar_p" elif declarations.is_same( declarations.void_t(), no_ptr ): return "ctypes.c_void_p" else: base_visitor = self.create_converter( self.user_type.base ) internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type ) if declarations.is_calldef_pointer( self.user_type ): return internal_type_str else: return "ctypes.POINTER( %s )" % internal_type_str
def __test_type_transformation(self, ns_name, transformer): ns_control = declarations.find_declaration( self.declarations, decl_type=declarations.namespace_t, name=ns_name) self.assertTrue(ns_control, "unable to find '%s' namespace" % ns_name) ns_before = declarations.find_declaration( ns_control, decl_type=declarations.namespace_t, name='before') self.assertTrue(ns_before, "unable to find 'before' namespace") ns_after = declarations.find_declaration( ns_control, decl_type=declarations.namespace_t, name='after') self.assertTrue(ns_after, "unable to find 'after' namespace") for tbefore in ns_before.declarations: tafter = declarations.find_declaration( ns_after, name=tbefore.name) self.assertTrue( tafter, "unable to find transformed type definition for type '%s'" % tbefore.decl_string) transformed = transformer(tbefore) self.assertTrue( declarations.is_same( transformed, tafter), ("there is a difference between expected type '{0}' " + "and result '{1}'. typedef name: {2}").format( declarations.remove_declarated(tafter).decl_string, declarations.remove_declarated(transformed).decl_string, tbefore.decl_string))
def is_supported( oper ): """returns True if Boost.Python support the operator""" if oper.symbol == '*' and len( oper.arguments ) == 0: #dereference does not make sense return False if oper.symbol != '<<': return oper.symbol in operators_helper.all args_len = len( oper.arguments ) if isinstance( oper, declarations.member_operator_t ):# and args_len != 1: return False #Boost.Python does not support member operator<< :-( if isinstance( oper, declarations.free_operator_t ) and args_len != 2: return False if not declarations.is_same( oper.return_type, oper.arguments[0].type ): return False type_ = oper.return_type if not declarations.is_reference( type_ ): return False type_ = declarations.remove_reference( type_ ) if declarations.is_const( type_ ): return False if args_len == 2: #second argument should has "T const &" type, otherwise the code will not compile tmp = oper.arguments[1].type if not declarations.is_reference( tmp ): return False tmp = declarations.remove_reference( tmp ) if not declarations.is_const( tmp ): return False return declarations.is_std_ostream( type_ ) or declarations.is_std_wostream( type_ )
def __test_type_transformation(self, ns_name, transformer): ns_control = declarations.find_declaration( self.declarations, decl_type=declarations.namespace_t, name=ns_name) self.assertTrue(ns_control, "unable to find '%s' namespace" % ns_name) ns_before = declarations.find_declaration( ns_control, decl_type=declarations.namespace_t, name='before') self.assertTrue(ns_before, "unable to find 'before' namespace") ns_after = declarations.find_declaration( ns_control, decl_type=declarations.namespace_t, name='after') self.assertTrue(ns_after, "unable to find 'after' namespace") for tbefore in ns_before.declarations: tafter = declarations.find_declaration(ns_after, name=tbefore.name) self.assertTrue( tafter, "unable to find transformed type definition for type '%s'" % tbefore.decl_string) transformed = transformer(tbefore) self.assertTrue( declarations.is_same(transformed, tafter), ("there is a difference between expected type '{0}' " + "and result '{1}'. typedef name: {2}").format( declarations.remove_declarated(tafter).decl_string, declarations.remove_declarated(transformed).decl_string, tbefore.decl_string))
def is_supported(oper): """returns True if Boost.Python support the operator""" if oper.symbol == "*" and len(oper.arguments) == 0: # dereference does not make sense return False if oper.symbol != "<<": return oper.symbol in operators_helper.all args_len = len(oper.arguments) if isinstance(oper, declarations.member_operator_t): # and args_len != 1: return False # Boost.Python does not support member operator<< :-( if isinstance(oper, declarations.free_operator_t) and args_len != 2: return False if not declarations.is_same(oper.return_type, oper.arguments[0].type): return False type_ = oper.return_type if not declarations.is_reference(type_): return False type_ = declarations.remove_reference(type_) if declarations.is_const(type_): return False if args_len == 2: # second argument should has "T const &" type, otherwise the code will not compile tmp = oper.arguments[1].type if not declarations.is_reference(tmp): return False tmp = declarations.remove_reference(tmp) if not declarations.is_const(tmp): return False return declarations.is_std_ostream(type_) or declarations.is_std_wostream(type_)
def __test_type_transformation(self, ns_name, transformer): ns_control = declarations.find_declaration( self.declarations, type=declarations.namespace_t, name=ns_name) self.failUnless(ns_control, "unable to find '%s' namespace" % ns_name) ns_before = declarations.find_declaration( ns_control, type=declarations.namespace_t, name='before') self.failUnless(ns_before, "unable to find 'before' namespace") ns_after = declarations.find_declaration( ns_control, type=declarations.namespace_t, name='after') self.failUnless(ns_after, "unable to find 'after' namespace") for tbefore in ns_before.declarations: tafter = declarations.find_declaration( ns_after, name=tbefore.name) self.failUnless( tafter, "unable to find transformed type definition for type '%s'" % tbefore.decl_string) transformed = transformer(tbefore) self.failUnless( declarations.is_same( transformed, tafter), ("there is a difference between expected type and result. " + "typedef name: %s") % tbefore.decl_string)
def validate_yes(self, value_type, container): traits = declarations.vector_traits self.assertTrue(traits.is_my_case(container)) self.assertTrue( declarations.is_same( value_type, traits.element_type(container))) self.assertTrue(traits.is_sequence(container))
def validate_yes(self, value_type, container): traits = declarations.vector_traits self.failUnless(traits.is_my_case(container)) self.failUnless( declarations.is_same( value_type, traits.element_type(container))) self.failUnless(traits.is_sequence(container))
def check_type_compatibility( self, fget, fset ): #algorithms allows "const" differences between types t1 = fget.return_type t2 = fset.arguments[0].type if declarations.is_same( t1, t2 ): return True elif declarations.is_pointer( t1 ) and declarations.is_pointer( t2 ): t1 = declarations.remove_cv( declarations.remove_pointer( t1 ) ) t2 = declarations.remove_cv( declarations.remove_pointer( t2 ) ) return declarations.is_same( t1, t2 ) elif declarations.is_reference( t1 ) and declarations.is_reference( t2 ): t1 = declarations.remove_cv( declarations.remove_reference( t1 ) ) t2 = declarations.remove_cv( declarations.remove_reference( t2 ) ) return declarations.is_same( t1, t2 ) else: return False
def check_type_compatibility(self, fget, fset): #algorithms allows "const" differences between types t1 = fget.return_type t2 = fset.arguments[0].decl_type if declarations.is_same(t1, t2): return True elif declarations.is_pointer(t1) and declarations.is_pointer(t2): t1 = declarations.remove_cv(declarations.remove_pointer(t1)) t2 = declarations.remove_cv(declarations.remove_pointer(t2)) return declarations.is_same(t1, t2) elif declarations.is_reference(t1) and declarations.is_reference(t2): t1 = declarations.remove_cv(declarations.remove_reference(t1)) t2 = declarations.remove_cv(declarations.remove_reference(t2)) return declarations.is_same(t1, t2) else: return False
def _resolve_by_type( self, some_type ): temp_type = declarations.remove_alias( some_type ) temp_type = declarations.remove_cv( temp_type ) if isinstance( temp_type, declarations.fundamental_t ) \ or isinstance( temp_type, declarations.declarated_t ): return decl_wrappers.default_call_policies() if declarations.is_same( some_type, self.__const_char_pointer ): return decl_wrappers.default_call_policies() return None
def _resolve_by_type(self, some_type): temp_type = declarations.remove_alias(some_type) temp_type = declarations.remove_cv(temp_type) if isinstance( temp_type, declarations.fundamental_t ) \ or isinstance( temp_type, declarations.declarated_t ): return decl_wrappers.default_call_policies() if declarations.is_same(some_type, self.__const_char_pointer): return decl_wrappers.default_call_policies() return None
def visit_pointer(self): no_ptr = declarations.remove_const( declarations.remove_pointer(self.user_type)) if declarations.is_same( declarations.char_t(), no_ptr) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_char_p" elif declarations.is_same( declarations.wchar_t(), no_ptr) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_wchar_p" elif declarations.is_same(declarations.void_t(), no_ptr): return "ctypes.c_void_p" else: base_visitor = self.create_converter(self.user_type.base) internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type) if declarations.is_calldef_pointer(self.user_type): return internal_type_str else: return "ctypes.POINTER( %s )" % internal_type_str
def check_type_compatibility(self, fget, fset): if decl_wrappers.name_based_recognizer_t.check_type_compatibility(self, fget, fset): return True # N.B.: la base non contempla il caso il cui la get restituisca "type" e la set abbia come parametro "const type &" (capita ad esempio in circostanze dove il valore di ritorno della get viene ottenuto tramite conversione da stringa) t1 = fget.return_type t2 = fset.arguments[0].type if declarations.is_reference(t2): t2 = declarations.remove_cv( declarations.remove_reference( t2 ) ) if declarations.is_same( t1, t2 ): return True return False
def _get_alias(self): if not self._alias or self.name == super(casting_operator_t, self)._get_alias(): return_type = declarations.remove_alias(self.return_type) decl_string = return_type.decl_string for type_, alias in self.SPECIAL_CASES.items(): if isinstance(type_, declarations.type_t): if declarations.is_same(return_type, type_): self._alias = alias break else: if decl_string == type_: self._alias = alias break else: self._alias = "as_" + self._generate_valid_name(self.return_type.decl_string) return self._alias
def _get_alias( self): if not self._alias or self.name == super( casting_operator_t, self )._get_alias(): return_type = declarations.remove_alias( self.return_type ) decl_string = return_type.decl_string for type_, alias in self.SPECIAL_CASES.items(): if isinstance( type_, declarations.type_t ): if declarations.is_same( return_type, type_ ): self._alias = alias break else: if decl_string == type_: self._alias = alias break else: self._alias = 'as_' + self._generate_valid_name(self.return_type.decl_string) return self._alias
def wrap_one_call_policy(fn): rt = fn.return_type if fn.return_type.decl_string == "char const *": return # use default for strings if fn.return_type.decl_string == "char *": return # use default for strings elif fn.return_type.decl_string == "void *": return # use default for void pointers elif fn.return_type.decl_string == "::GLvoid const *": return # use default for void pointers parent_ref = declarations.reference_t(declarations.declarated_t(fn.parent)) if declarations.is_reference(rt): # Need type without reference for next type checks nonref_rt = rt.base if declarations.is_arithmetic(nonref_rt) or declarations.is_enum( nonref_rt): # returning const& double can cause compile trouble if return_internal_reference is used if declarations.is_const(nonref_rt): fn.call_policies = return_value_policy(copy_const_reference) return # int& might need to be copy_non_const_reference... else: fn.call_policies = return_value_policy( copy_non_const_reference) return # Const string references should be copied to python strings if declarations.is_std_string(nonref_rt) and declarations.is_const( nonref_rt): fn.call_policies = return_value_policy(copy_const_reference) return # Returning reference to this same class looks like return_self() [does this always work?] if declarations.is_same(parent_ref, rt): fn.call_policies = return_self() return elif declarations.is_pointer(rt): # Clone methods if re.search(r'^clone', fn.name): fn.call_policies = return_value_policy(reference_existing_object) return else: return # Everything else probably returns an internal reference fn.call_policies = return_internal_reference() return
def __call__(self, calldef, hint=None): if not isinstance( calldef, declarations.calldef_t ): return None if isinstance( calldef, declarations.constructor_t ): return None return_type = declarations.remove_alias( calldef.return_type ) if isinstance( return_type, declarations.reference_t ) \ and isinstance( return_type.base, declarations.const_t ): return decl_wrappers.return_value_policy( decl_wrappers.copy_const_reference ) if declarations.is_same( return_type, self.__const_wchar_pointer ): return decl_wrappers.return_value_policy( decl_wrappers.return_by_value ) if opaque_types_manager.find_out_opaque_decl( return_type, ensure_opaque_decl=True ): return decl_wrappers.return_value_policy( decl_wrappers.return_opaque_pointer ) return None
def wrap_one_call_policy(fn): rt = fn.return_type if fn.return_type.decl_string == "char const *": return # use default for strings if fn.return_type.decl_string == "char *": return # use default for strings elif fn.return_type.decl_string == "void *": return # use default for void pointers elif fn.return_type.decl_string == "::GLvoid const *": return # use default for void pointers parent_ref = declarations.reference_t(declarations.declarated_t(fn.parent)) if declarations.is_reference(rt): # Need type without reference for next type checks nonref_rt = rt.base if declarations.is_arithmetic(nonref_rt) or declarations.is_enum(nonref_rt): # returning const& double can cause compile trouble if return_internal_reference is used if declarations.is_const(nonref_rt): fn.call_policies = return_value_policy(copy_const_reference) return # int& might need to be copy_non_const_reference... else: fn.call_policies = return_value_policy(copy_non_const_reference) return # Const string references should be copied to python strings if declarations.is_std_string(nonref_rt) and declarations.is_const(nonref_rt): fn.call_policies = return_value_policy(copy_const_reference) return # Returning reference to this same class looks like return_self() [does this always work?] if declarations.is_same(parent_ref, rt): fn.call_policies = return_self() return elif declarations.is_pointer(rt): # Clone methods if re.search(r'^clone', fn.name): fn.call_policies = return_value_policy(reference_existing_object) return else: return # Everything else probably returns an internal reference fn.call_policies = return_internal_reference() return
def __test_type_transformation(self, ns_name, transformer): ns_control = declarations.find_declaration( self.declarations, type=declarations.namespace_t, name=ns_name) self.failUnless(ns_control, "unable to find '%s' namespace" % ns_name) ns_before = declarations.find_declaration( ns_control, type=declarations.namespace_t, name='before') self.failUnless(ns_before, "unable to find 'before' namespace") ns_after = declarations.find_declaration(ns_control, type=declarations.namespace_t, name='after') self.failUnless(ns_after, "unable to find 'after' namespace") for tbefore in ns_before.declarations: tafter = declarations.find_declaration(ns_after, name=tbefore.name) self.failUnless( tafter, "unable to find transformed type definition for type '%s'" % tbefore.decl_string) transformed = transformer(tbefore) self.failUnless( declarations.is_same(transformed, tafter), "there is a difference between expected type and result. typedef name: %s" % tbefore.decl_string)
def prepare_special_cases(): """ Creates a map of special cases ( aliases ) for casting operator. """ special_cases = {} const_t = declarations.const_t pointer_t = declarations.pointer_t for type_ in declarations.FUNDAMENTAL_TYPES.values(): alias = None if declarations.is_same( type_, declarations.bool_t() ): alias = '__int__' elif declarations.is_integral( type_ ): if 'long' in type_.decl_string: alias = '__long__' else: alias = '__int__' elif declarations.is_floating_point( type_ ): alias = '__float__' else: continue #void if alias: special_cases[ type_ ] = alias special_cases[ const_t( type_ ) ] = alias special_cases[ pointer_t( const_t( declarations.char_t() ) ) ] = '__str__' std_string = '::std::basic_string<char,std::char_traits<char>,std::allocator<char> >' std_wstring1 = '::std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >' std_wstring2 = '::std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >' special_cases[ std_string ] = '__str__' special_cases[ std_wstring1 ] = '__str__' special_cases[ std_wstring2 ] = '__str__' special_cases[ '::std::string' ] = '__str__' special_cases[ '::std::wstring' ] = '__str__' #TODO: add # std::complex<SomeType> some type should be converted to double return special_cases
def prepare_special_cases(): """ Creates a map of special cases ( aliases ) for casting operator. """ special_cases = {} const_t = declarations.const_t pointer_t = declarations.pointer_t for type_ in declarations.FUNDAMENTAL_TYPES.values(): alias = None if declarations.is_same(type_, declarations.bool_t()): alias = "__int__" elif declarations.is_integral(type_): if "long" in type_.decl_string: alias = "__long__" else: alias = "__int__" elif declarations.is_floating_point(type_): alias = "__float__" else: continue # void if alias: special_cases[type_] = alias special_cases[const_t(type_)] = alias special_cases[pointer_t(const_t(declarations.char_t()))] = "__str__" std_string = "::std::basic_string<char,std::char_traits<char>,std::allocator<char> >" std_wstring1 = "::std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >" std_wstring2 = "::std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >" special_cases[std_string] = "__str__" special_cases[std_wstring1] = "__str__" special_cases[std_wstring2] = "__str__" special_cases["::std::string"] = "__str__" special_cases["::std::wstring"] = "__str__" # TODO: add # std::complex<SomeType> some type should be converted to double return special_cases
def test_is_same(self): self.failUnless( declarations.is_same(declarations.int_t, declarations.int_t)) self.failIf( declarations.is_same(declarations.int_t, declarations.float_t))