def del_contained_elements_type(proxy_obj, value): """ Deletes the contained element types that correspond to a certain key type (for dictionaries) :param proxy_obj: :param value: :return: """ if can_store_elements(proxy_obj) or can_store_keypairs(proxy_obj): try: if type(proxy_obj) is TypeWrapper: delitem = proxy_obj.get_type_of_member('__delitem__') if isinstance(delitem, StypyTypeError): return delitem else: return stypy.type_inference_programs.stypy_interface.invoke( Localization.get_current(), delitem, value) else: if not hasattr(proxy_obj, '__delitem__'): return StypyTypeError( Localization.get_current(), "Trying to remove elements on a non-container type") except: return StypyTypeError( Localization.get_current(), "Trying to remove elements on a non-container type") else: return StypyTypeError( Localization.get_current(), "Trying to remove elements on a non-container type")
def will_iterate_loop(localization, condition_type): """ A loop must iterate an iterable object or data structure or an string. This function checks if the iterable object is empty (its contents are of the type UndefinedType). In that case, it does not iterate :param localization: Caller information :param condition_type: Type of the condition :return: """ if is_error_type(condition_type): return False if type(condition_type) is file: return True if condition_type is undefined_type.UndefinedType: return False if (can_store_elements(condition_type) or ( can_represent_type(IterableObject, condition_type)) or call_utilities.is_iterable(condition_type)): try: Localization.set_current(localization) t = get_contained_elements_type(condition_type) if type(t) is undefined_type.UndefinedType or t is undefined_type.UndefinedType: return False except: pass return True return True
def set_contained_elements_type_for_key(proxy_obj, key, new_type): """ Set the contained element types that correspond to a certain key type (for dictionaries) :param proxy_obj: :param key: :param new_type: :return: """ if isinstance(proxy_obj, union_type.UnionType): return proxy_obj.set_contained_type_for_key(key, new_type) if hasattr(proxy_obj, '__setitem__'): existing_type = get_contained_elements_type_for_key(proxy_obj, key) if existing_type is undefined_type.UndefinedType: if proxy_obj is os.environ and key == '': return proxy_obj.__setitem__(' ', new_type) if is_type_inference_file_object(proxy_obj): return proxy_obj.__setitem__(Localization.get_current(), key, new_type) return proxy_obj.__setitem__(key, new_type) else: existing_type = union_type.UnionType.add(existing_type, new_type) if is_type_inference_file_object(proxy_obj): return proxy_obj.__setitem__(Localization.get_current(), key, existing_type) return proxy_obj.__setitem__(key, existing_type) else: return None
def __join_ssa_branches_types_of_members_for_object(obj, previous_context, branch1, branch2): """ Implementation of the SSA joining algorithm for two SSA branches, handling types of members :param previous_context: :param branch1: dict(obj, dict(name, type)) :param branch2: :return: """ type_dict = dict() # NOTE: Explanations in comments are done with an if/else control structure. Other structures are the same. # Proceed with the first branch (if) # For any variable stored in the first branch (note that we only deal with variables that change its type in the # active branch, not all the possible variables accessible within the SSA context. This is also a major speedup # over our previous version. for var_name in branch1: if var_name in branch2: # Variable defined in if and else body: Joins both types type_dict[var_name] = UnionType.add(branch1[var_name], branch2[var_name]) else: # Variable defined in if and in the previous context: Joins the previous type and the if one previous_type = previous_context.get_type_of_member( Localization.get_current(), obj, var_name) if not isinstance(previous_type, StypyTypeError): type_dict[var_name] = UnionType.add(previous_type, branch1[var_name]) else: # Variable defined in if body, but did not exist in the previous context: Joins the if type with an # undefined type, as the if could not be executed type_dict[var_name] = UnionType.add(branch1[var_name], UndefinedType) StypyTypeError.remove_error_msg(previous_type) # Now proceed with the second branch (else). If no else is present and empty dict is passed, and therefore no # processing is done. for var_name in branch2: if var_name in branch1: continue # Already processed (above) else: # Variable defined only in the else body and in the previous context: Treat equally to the if branch # counterpart previous_type = previous_context.get_type_of_member( Localization.get_current(), obj, var_name) if not isinstance(previous_type, StypyTypeError): type_dict[var_name] = UnionType.add(previous_type, branch2[var_name]) else: # Variable defined in else body, but did not existed in the previous context: Same treatment as their # if branch counterpart type_dict[var_name] = UnionType.add(branch2[var_name], UndefinedType) StypyTypeError.remove_error_msg(previous_type) # type_store_previous does not need to be iterated because it is included in the if and else stores return type_dict
def del_member(self, name): """ Deletes the member name from all the types in the union that declare it :param name: :return: """ errors = [] for type_ in self.types: type_ = stypy_types.type_intercession.del_member( Localization.get_current(), type_, name) if isinstance(type_, StypyTypeError): errors.append(type_) # If all types contained in the union do not have this member, the whole access is an error. if len(errors) == len(self.types): for error in errors: StypyTypeError.remove_error_msg(error) return StypyTypeError.no_type_can_delete_member_error( Localization.get_current(), self.types, name) else: # If not all the types return an error when accessing the members, the policy is different: # - Notified errors are turned to warnings in the general error log # - ErrorTypes are eliminated. for error in errors: error.turn_to_warning() return None
def has_member(self, localization, obj, name): """ Gets the type of the specified member name for the object obj, looking on its parent context if not found on its own type store :param localization: :param obj: :param name: :return: """ try: # Lookup inside our types self.__get_hash(obj) if obj in self.types_of_members: obj = self.types_of_members[self.__get_hash(obj)][name] return True except KeyError: # If not found, lookup our parent context (if any) recursively if self.parent_context is not None: return self.parent_context.has_member( Localization.get_current(), obj, name) except Exception as exc: try: # Lookup inside our types if id(obj) in self.types_of_members: obj = self.types_of_members[id(obj)][name] return True except KeyError: # If not found, lookup our parent context (if any) recursively if self.parent_context is not None: return self.parent_context.has_member( Localization.get_current(), obj, name) return super(SSAContext, self).has_member(localization, obj, name)
def get_contained_elements_type(proxy_obj, multi_assign_arity=-1, multi_assign_index=-1): """ Get the type of the contained elements of the passed type :param proxy_obj: :return: """ if type(proxy_obj) is file: return str() if type(proxy_obj) is type_groups.type_groups.DynamicType: return proxy_obj # Direct containers if type(proxy_obj) in types_that_store_contents_directly: try: return proxy_obj[0] except: return undefined_type.UndefinedType # Wrappers if isinstance(proxy_obj, TypeWrapper): if proxy_obj.can_store_elements(): if proxy_obj.can_store_keypairs() and type( proxy_obj.wrapped_type) is dict: return union_type.UnionType.create_from_type_list( proxy_obj.wrapped_type.keys()) if type(proxy_obj.wrapped_type ) in types_that_store_contents_directly: try: return proxy_obj.wrapped_type[0] except: return undefined_type.UndefinedType return proxy_obj.get_contained_type(multi_assign_arity, multi_assign_index) else: if type(proxy_obj) is str: return str() else: # Other classes that define __setitem__ m_get = get_getitem_method(proxy_obj) if m_get is not None: try: return m_get(Localization.get_current(), *[int()]) except TypeError: return m_get(*[int()]) # Error: Containers must be wrapped if proxy_obj is not None: return StypyTypeError( Localization.get_current(), "Elements of type '{0}' cannot contain types".format( format_type(proxy_obj))) else: return StypyTypeError(Localization.get_current(), "The provided type cannot contain elements")
def set_member_to_object(localization, obj, name, value): """ Sets the member name from the object obj to value :param localization: :param obj: :param name: :param value: :return: """ if is_error(obj): return obj try: Localization.set_current(localization) if isinstance(obj, contexts.context.Context): return obj.set_type_of(localization, name, value) if isinstance(obj, TypeWrapper) and obj.is_declared_member(name): return obj.set_type_of_member(name, value) if name in reserved_members: try: set_attr(obj, name, value) return except: set_attr(obj, '__stypy'+ name, value) return set_attr(obj, name, value) except Exception as exc: return StypyTypeError.member_cannot_be_set_error(localization, obj, name, value, str(exc))
def generic_0parameter_test(type_store, var_name, method_name, correct_return_type): obj = type_store.get_type_of(Localization(__file__), var_name) method = type_store.get_type_of_member(Localization(__file__), obj, method_name) result = invoke(Localization(__file__), method) compare_types(result, correct_return_type)
def test_use_global_in_global_context_after_usage(self): self.type_store.set_type_of(self.loc, "global_var", int) self.type_store.set_type_of(self.loc, "global_func", types.FunctionType) self.type_store.declare_global(Localization(__file__, 1, 1), "global_var") self.type_store.declare_global(Localization(__file__, 2, 2), "global_func") compare_types(self.type_store.get_type_of(Localization(__file__, 3, 3), "global_var"), types.IntType) compare_types(self.type_store.get_type_of(Localization(__file__, 4, 4), "global_func"), types.FunctionType) assert len(Advice.get_advice_msgs()) == 2
def get_type_of_for_loop_variable(localization, condition_type): """ A loop must iterate an iterable object or data structure or an string. This function returns the contents of whatever the loop is iterating :param localization: Caller information :param condition_type: Type of the condition :return: """ if type(condition_type) is RecursionType: return condition_type if type(condition_type) is StypyTypeError: return condition_type if type(condition_type) is types.FileType: return str() if condition_type is undefined_type.UndefinedType: return condition_type if can_store_keypairs(condition_type): return wrap_contained_type(get_key_types(condition_type)) # If the type of the condition can store elements, return the type of stored elements if can_store_elements(condition_type): Localization.set_current(localization) return wrap_contained_type(get_contained_elements_type(condition_type)) # If the type of the condition is some kind of string, return the type of string if can_represent_type(Str, condition_type): return wrap_contained_type(condition_type) # If the type of the condition is something iterable, return the result of calling its __iter__ method if can_represent_type(IterableObject, condition_type): iter_method = condition_type.get_type_of_member(localization, "__iter__") return wrap_contained_type(stypy_interface.invoke(localization, iter_method)) if call_utilities.is_numpy_array(condition_type): return condition_type.get_contained_type() if call_utilities.is_ndenumerate(condition_type): contained = None for typ in condition_type.iter.coords: contained = union_type.UnionType.add(contained, typ) t = wrap_contained_type((contained,)) t.set_contained_type(contained) return union_type.UnionType.add(t, numpy.int32) if call_utilities.is_ndindex(condition_type): t = wrap_contained_type((numpy.int32(),)) t.set_contained_type(numpy.int32()) return t return StypyTypeError(localization, "Invalid iterable type for a loop target ({0})".format(str(condition_type)))
def test_local_variable_turned_global_before(self): self.type_store.declare_global(Localization(__file__, 1, 1), "global_var") self.type_store.set_type_of(Localization(__file__, 2, 2), "global_var", int) self.type_store = self.type_store.open_function_context("nested_func") num_warnings_before = len(TypeWarning.get_warning_msgs()) compare_types(self.type_store.get_type_of(Localization(__file__, 3, 3), "global_var"), types.IntType) num_warnings_after = len(TypeWarning.get_warning_msgs()) assert num_warnings_after == num_warnings_before + 1 self.type_store.declare_global(Localization(__file__, 4, 4), "global_var") assert len(Advice.get_advice_msgs()) == 2 self.type_store.declare_global(self.loc, "non_existing") assert_if_not_error(self.type_store.get_type_of(Localization(__file__, 5, 5), "non_existing")) self.type_store.declare_global(Localization(__file__, 6, 6), "foo") self.type_store.set_type_of(Localization(__file__, 7, 7), "foo", int) assert len(Advice.get_advice_msgs()) == 4 self.type_store.declare_global(Localization(__file__, 8, 8), "foo_func") self.type_store.set_type_of(Localization(__file__, 9, 9), "foo_func", types.FunctionType) assert len(Advice.get_advice_msgs()) == 5 compare_types(self.type_store.get_type_of(self.loc, "foo"), types.IntType) compare_types(self.type_store.get_type_of(self.loc, "foo_func"), types.FunctionType) self.type_store = self.type_store.close_function_context() compare_types(self.type_store.get_type_of(self.loc, "foo"), types.IntType) compare_types(self.type_store.get_type_of(self.loc, "foo_func"), types.FunctionType)
def __eq__(self, type_): for member in self.members: if is_special_name_method(member): converted_name = convert_special_name_method(member) if has_member(Localization.get_current(), type_, converted_name): return False if has_member(Localization.get_current(), type_, member): return False return True
def analyze(self): """ Main stypy function. Performs all the steps to analyze the source file types in order """ if self.verbose: info("Parsing file '" + self.source_file_path + "'\n") try: existing_ts = contexts.context.Context.get_current_active_context_for_module(self.source_file_path) if existing_ts is not None: self.analyzed_program_type_store = existing_ts return existing_ts except: pass # Obtain the AST of the source file # self.get_original_source_file_ast() # If a type data file have to be generated and the source file is suitable to do so, do it # if self.generate_type_data_file: # if Stypy.__is_file_suitable_for_autocalculate_types(self.source_file_path): # self.create_automatic_type_data_autogenerator_program() # Create the type inference program self.create_type_inference_program() try: return self.run_type_inference() except Exception as exc: return type_error.StypyTypeError(Localization.get_current(), exc.message)
def get_contained_elements_type_for_key(proxy_obj, key): """ Get the contained element types that correspond to a certain key type (for dictionaries) :param proxy_obj: :param key: :return: """ if isinstance(proxy_obj, union_type.UnionType): return proxy_obj.get_contained_type_for_key(key) if hasattr(proxy_obj, '__getitem__'): try: if is_type_inference_file_object(proxy_obj): return proxy_obj.__getitem__(Localization.get_current(), key) try: return proxy_obj.__getitem__(key) except KeyError: ks = proxy_obj.items() for k in ks: if type(k[0]) is type(key): return k[1] return undefined_type.UndefinedType except Exception as exc: return undefined_type.UndefinedType else: return None
def __init__(self, localization, msg, prints_msg=True, snap=None): """ Creates a warning with the provided message. :param localization: Caller information :param msg: Warning message :param prints_msg: As TypeErrors, TypeWarnings can also be silent if reporting them is not activated :return: """ self.packed = False self.display_message = "" self.message = msg self.other_stack_traces = [] if localization is None: localization = Localization(__file__, 1, 0) self.localization = localization if snap is None: self.stack_trace_snapshot = localization.stack_trace.get_snapshot() else: self.stack_trace_snapshot = snap # Create the message here to capture the execution point, as stack traces are dynamic. self.warn_msg = self.__msg() if (stypy_parameters.MAX_TYPE_WARNINGS > 0) and len( TypeWarning.warnings) > stypy_parameters.MAX_TYPE_WARNINGS: TypeWarning.type_warning_limit_hit = True return if prints_msg and self not in TypeWarning.warnings: TypeWarning.warnings.append(self)
def del_member(self, localization, obj, name): """ Deletes the type of the specified member name for the object obj, looking on its parent context if not found on its own type store :param localization: :param obj: :param name: :return: """ try: if self.on_ssa: # Lookup inside our types if self.__get_hash(obj) not in self.types_of_members: self.types_of_members[self.__get_hash(obj)] = dict() self.types_of_members[self.__get_hash( obj)][name] = UndefinedType return None else: # Lookup inside our types del self.types_of_members[self.__get_hash(obj)][name] return None except KeyError: # If not found, lookup our parent context (if any) recursively if self.parent_context is not None: return self.parent_context.del_member( Localization.get_current(), obj, name) return super(SSAContext, self).del_member(localization, obj, name)
def get_type_of_member(self, name): """ Get the type of the member name of the types of the union (if different types has the same member name with different types, a union type with all the possible types is returned). :param name: :return: """ types_to_return = [] errors = [] # Add all the results of get_type_of_member for all stored types in a list for type_ in self.types: type_ = stypy_types.type_intercession.get_member( Localization.get_current(), type_, name) if isinstance(type_, StypyTypeError): errors.append(type_) else: types_to_return.append(type_) all_errors = len(errors) == len(self.types) if all_errors: return StypyTypeError.no_type_has_member_error( Localization.get_current(), self.types, name) else: # If there is an error, it means that the obtained member could be undefined in one of the contained # objects # if len(errors) > 0: # types_to_return.append(UndefinedType) # If not all the types return an error when accessing the members, the policy is different: # - Notified errors are turned to warnings in the general error log, as there are combinations of types # that are valid # - ErrorTypes are eliminated from the error collection. for error in errors: error.turn_to_warning() # Calculate return type: If there is only one type, return it. If there are several types, return a # UnionType with all of them contained if len(types_to_return) == 1: return types_to_return[0] else: ret_union = None for type_ in types_to_return: ret_union = UnionType.add(ret_union, type_) return ret_union
def __eq__(self, type_): if is_special_name_method(self.member): converted_name = convert_special_name_method(self.member) if has_member(Localization.get_current(), type_, converted_name): self.member_obj = get_member(Localization.get_current(), type_, converted_name) return True else: self.member_obj = None if has_member(Localization.get_current(), type_, self.member): self.member_obj = get_member(Localization.get_current(), type_, self.member) return True else: self.member_obj = None return False
def __init__(self, localization=None, msg="", prints_msg=True): """ Creates a particular instance of a type error amd adds it to the error list :param localization: Caller information :param msg: Error to report to the user :param prints_msg: Determines if this error is silent (report its message) or not. Some error are silent because they are generated to generate a more accurate TypeError later once the program determines that TypeErrors exist on certain places of the analyzed program. This is used in certain situations to avoid reporting the same error multiple times :return: """ # This happens when a declared class has its parent inferred as an error type. If that happens, the class is # built using this constructor as a base class initializer. We throw an error indicating the issue and do not # build a standard error in this case. if type(localization) is str: StypyTypeError( Localization.get_current(), "The parent class of class '" + localization + "' is an error") return self.message = msg if localization is None: localization = Localization(__file__, 1, 0) self.localization = localization self.stack_trace_snapshot = localization.stack_trace.get_snapshot() # The error_msg is the full error to report to the user, composed by the passed msg and the stack trace. # We calculate it here to "capture" the precise execution point when the error is produced as stack trace is # dynamic and changes during the execution self.error_msg = self.__msg() if (stypy_parameters.MAX_TYPE_ERRORS > 0) and len( StypyTypeError.errors) > stypy_parameters.MAX_TYPE_ERRORS: StypyTypeError.type_error_limit_hit = True return # Add this error to the general error list if not already present if prints_msg and self not in StypyTypeError.errors: StypyTypeError.errors.append(self)
def get_member_from_object(localization, obj, name): """ Get the member name from the object obj :param localization: :param obj: :param name: :return: """ if is_error(obj): return obj Localization.set_current(localization) if isinstance(obj, contexts.context.Context): return obj.get_type_of(localization, name) if isinstance(obj, TypeWrapper) and (obj.is_declared_member(name) or name == '__getitem__'): try: return obj.get_type_of_member(name) except Exception as ex: return StypyTypeError.member_not_defined_error(localization, obj, name) if has_attr(obj, name): ret_type = type_inference_programs.stypy_interface.wrap_type(get_attr(obj, name)) if name == '__bases__': base_type = None bases = obj.__bases__ if not isinstance(bases, tuple): bases = (bases,) for type_ in bases: base_type = types.union_type.UnionType.add(base_type, type_) type_containers.set_contained_elements_type(ret_type, base_type) return ret_type if isinstance(obj, invokation.type_rules.type_groups.type_groups.DynamicType) or \ (type(obj) is invokation.type_rules.type_groups.type_groups.DynamicType): return invokation.type_rules.type_groups.type_groups.DynamicType() # Variable not found return StypyTypeError.member_not_defined_error(localization, obj, name)
def has_member(self, name): """ Determines if any of the types in the union has the passed member name :param name: :return: """ for type_ in self.types: type_ = stypy_types.type_intercession.get_member( Localization.get_current(), type_, name) if not isinstance(type_, StypyTypeError): return True return False
def test_wrong_global_keyword_in_func(self): self.type_store.declare_global(Localization(__file__, 1, 1), "global_var") self.type_store.declare_global(Localization(__file__, 2, 2), "global_func") self.type_store.set_type_of(self.loc, "global_var", int) self.type_store.set_type_of(self.loc, "global_func", types.FunctionType) self.type_store = self.type_store.open_function_context("nested_func") num_warnings_before = len(TypeWarning.get_warning_msgs()) compare_types(self.type_store.get_type_of(self.loc, "global_var"), types.IntType) compare_types(self.type_store.get_type_of(self.loc, "global_func"), types.FunctionType) num_warnings_after = len(TypeWarning.get_warning_msgs()) # TypeWarning.print_warning_msgs() assert num_warnings_after == num_warnings_before + 2 self.type_store.declare_global(Localization(__file__, 3, 3), "global_var") assert len(Advice.get_advice_msgs()) == 3 self.type_store.declare_global(Localization(__file__, 4, 4), "global_func") assert len(Advice.get_advice_msgs()) == 4 self.type_store = self.type_store.close_function_context()
def del_member_from_object(localization, obj, name): """ Removes the member name from the object obj :param localization: :param obj: :param name: :return: """ if is_error(obj): return obj try: Localization.set_current(localization) if isinstance(obj, TypeWrapper): if has_attr(obj, '__delitem__'): return type_inference_programs.stypy_interface.invoke(localization, obj.__delitem__, [name]) if obj.is_declared_member(name): return obj.del_member(name) member_type = get_member(localization, obj, name) if isinstance(member_type, types.union_type.UnionType): if types.undefined_type.UndefinedType in member_type: TypeWarning(localization, "Attempt to delete the potentially unexisting member '{0}' from an object".format(name)) if isinstance(member_type, StypyTypeError): return member_type if isinstance(obj, contexts.context.Context): obj.del_type_of(localization, name) return del_attr(obj, name) except Exception as exc: if isinstance(obj, invokation.type_rules.type_groups.type_groups.DynamicType): return invokation.type_rules.type_groups.type_groups.DynamicType() return StypyTypeError.member_cannot_be_deleted_error(localization, obj, name, str(exc))
def setUp(self): try: delattr(ClassA, "class_attribute") except: pass try: delattr(ClassA, "class_attribute2") except: pass try: delattr(ClassA, "class_attribute3") except: pass self.localization = Localization(__file__, 1, 1) self.context = SSAContext(None) self.context.set_type_of(self.localization, "var1", ClassA) self.context.set_type_of(self.localization, "var2", ClassA)
def __delattr__(self, name): """ For all the types stored in the union type, set the type of the member named member_name to the type specified in member_value. For example, if a UnionType has the types Class1 and Class2, both with the member "attr" so Class1.attr: int and Class2.attr: str, this method, if passsed a float as member_value will turn both classes "attr" to float. :param name: Name of the member to set :return None or a TypeError if the member cannot be set. Warnings are generated if the member of some of the stored objects cannot be set """ # Class is writable over the contained members if name in object.__getattribute__( self, "declared_members") and not name == "__class__": try: object.__delattr__(self, name) except Exception as exc: return StypyTypeError.member_cannot_be_deleted_error( Localization.get_current(), self, name, exc) else: return self.del_member(name)
def test_use_global_in_global_context(self): num_warnings_before = len(TypeWarning.get_warning_msgs()) self.type_store.declare_global(Localization(__file__, 1, 1), "global_var") self.type_store.declare_global(Localization(__file__, 2, 2), "global_func") self.type_store.set_type_of(Localization(__file__, 3, 3), "global_var", int) self.type_store.set_type_of(Localization(__file__, 4, 4), "global_func", types.FunctionType) compare_types(self.type_store.get_type_of(Localization(__file__, 5, 5), "global_var"), types.IntType) compare_types(self.type_store.get_type_of(Localization(__file__, 6, 6), "global_func"), types.FunctionType) num_warnings_after = len(TypeWarning.get_warning_msgs()) assert len(Advice.get_advice_msgs()) == 2 assert num_warnings_after == num_warnings_before
def set_contained_elements_type(proxy_obj, new_type): """ Set the contained elements of a container :param proxy_obj: :param new_type: :return: """ if type(proxy_obj) is type_groups.type_groups.DynamicType: return # Direct containers if type(proxy_obj) in types_that_store_contents_directly: try: if len(proxy_obj) > 0: return proxy_obj.__setitem__(0, new_type) else: return proxy_obj.append(new_type) except: pass # Wrappers if isinstance(proxy_obj, TypeWrapper): if type(proxy_obj.wrapped_type) in types_that_store_contents_directly: try: if len(proxy_obj.wrapped_type) > 0: return proxy_obj.wrapped_type.__setitem__(0, new_type) else: if hasattr(proxy_obj.wrapped_type, 'append'): return proxy_obj.wrapped_type.append(new_type) if isinstance(proxy_obj.wrapped_type, set): proxy_obj.wrapped_type.add(new_type) except: pass return proxy_obj.set_contained_type(new_type) return StypyTypeError( Localization.get_current(), "Elements of type '{0}' cannot contain types".format( format_type(proxy_obj)))
def setUp(self): self.instanceA = ClassA() self.instanceB = ClassB() try: delattr(self.instanceA, "instance_attribute") except: pass try: delattr(self.instanceA, "instance_attribute2") except: pass try: delattr(self.instanceA, "instance_attribute3") except: pass self.context = SSAContext(None) self.localization = Localization(__file__, 1, 1) self.context.set_type_of(self.localization, "var1", self.instanceA) self.context.set_type_of(self.localization, "var2", self.instanceA)
def set_contained_type(self, type_): """ Sets the contained types of all the types in the union :return: """ errors = [] for t in self.types: ret = stypy_types.type_containers.set_contained_elements_type( t, type_) if isinstance(ret, StypyTypeError): errors.append(ret) if len(errors) == len(self.types): for e in errors: StypyTypeError.remove_error_msg(e) return StypyTypeError( Localization.get_current(), "None of the possible types is able to store elements of type {0}" .format(type_)) else: for e in errors: e.turn_to_warning()