def __add__(localization, proxy_obj, arguments): ret_type = get_builtin_python_type_instance(localization, 'list') existing_type = get_contained_elements_type(get_self(proxy_obj)) params = arguments[0] if can_store_elements(params): if existing_type is not None: if not isinstance(existing_type, union_type.UnionType): new_type = existing_type else: new_type = existing_type.duplicate() else: new_type = None other_type = get_contained_elements_type(params) if not isinstance(other_type, union_type.UnionType): other_type = [other_type] else: other_type = other_type.types for par in other_type: new_type = union_type.UnionType.add(new_type, par) else: new_type = union_type.UnionType.add(existing_type, arguments[0]) set_contained_elements_type(ret_type, new_type) return ret_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 is_suitable_for_loop_condition(localization, condition_type): """ A loop must iterate an iterable object or data structure or an string. This function checks this :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 RecursionType: return False if type(condition_type) is file: return True if condition_type is undefined_type.UndefinedType: return False if not (can_store_elements(condition_type) or can_represent_type(Str, condition_type) or ( can_represent_type(IterableObject, condition_type)) or call_utilities.is_iterable(condition_type)): StypyTypeError(localization, "The type of this for loop condition is erroneous") return False return True
def nan_to_num(localization, proxy_obj, arguments): if RealNumber == type(arguments[0]): return call_utilities.cast_to_numpy_type(arguments[0]) if can_store_elements(arguments[0]): return call_utilities.create_numpy_array( get_contained_elements_type(arguments[0])) return call_utilities.create_numpy_array(arguments[0].wrapped_type)
def turn_to_type(obj): """ As in our type analysis process we may have to deal with code whose sources are not available, calls to this code must be performed so we can obtain return values that can be used in our program analysis. This code is responsible of turning the values obtained from these calls to its types so stypy is able to use its return types to analyze the program. :param obj: :return: """ # Already wrapped: it is already a type if type(obj) is StandardWrapper: return obj if type(obj) in types_without_value: obj = type(obj)() wrapped_obj = wrap_contained_type(obj) # Special handling for dicts and similar if type_containers.can_store_keypairs(wrapped_obj): collected_items = dict() keys = obj.keys() for key in keys: values_for_key = type_containers.get_contained_elements_type_for_key(obj, key) key_type = turn_to_type(key) value_types = turn_to_type(values_for_key) try: existing_values = collected_items[key_type] except: existing_values = None collected_items[key_type] = UnionType.add(value_types, existing_values) for key in keys: del obj[key] for key, value in collected_items.items(): type_containers.set_contained_elements_type_for_key(wrapped_obj, key, value) return wrapped_obj # Special handling for containers if type_containers.can_store_elements(wrapped_obj): union_contained = None for elem in obj: elem = turn_to_type(elem) if elem is type: union_contained = UnionType.add(union_contained, elem) else: try: union_contained = UnionType.add(union_contained, known_python_types.get_sample_instance_for_type( type(elem).__name__)) except Exception as exc: union_contained = UnionType.add(union_contained, elem) wrapped_obj.set_contained_type(union_contained) return wrapped_obj return obj
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 __setslice__(localization, proxy_obj, arguments): existing_type = get_contained_elements_type(get_self(proxy_obj)) params = arguments[2] if can_store_elements(params): new_type = existing_type other_type = get_contained_elements_type(params) if not isinstance(other_type, collections.Iterable): other_type = [other_type] for par in other_type: new_type = union_type.UnionType.add(new_type, par) else: new_type = union_type.UnionType.add(existing_type, arguments[2]) set_contained_elements_type(get_self(proxy_obj), new_type) return types.NoneType
def extend(localization, proxy_obj, arguments): existing_type = get_contained_elements_type(get_self(proxy_obj)) params = arguments[0] if can_store_elements(params): new_type = existing_type other_type = get_contained_elements_type(params) if not isinstance(other_type, collections.Iterable): other_type = [other_type] for par in other_type: new_type = union_type.UnionType.add(new_type, par) else: return StypyTypeError.wrong_parameter_type_error( localization, "iterable", type(params).__name__) set_contained_elements_type(get_self(proxy_obj), new_type) return types.NoneType
def __repr__(self): """ str operator overload :return: """ txt = type(self.wrapped_type).__name__ if can_store_keypairs(self): txt += "{" keys = get_key_types(self) if is_union_type(keys): keys = keys.get_types() else: keys = list(keys) if len(keys) == 0: txt += "UndefinedType" else: for key in keys: values = get_contained_elements_type_for_key(self, key) if not isinstance(values, TypeWrapper): contents = type(values).__name__ else: contents = str(values) txt += type(key).__name__ + ": " + contents + "; " txt = txt[:-2] return txt + "}\n" if can_store_elements(self): contained_type = get_contained_elements_type(self) if not isinstance(contained_type, TypeWrapper): if is_undefined(contained_type): contents = "UndefinedType" else: contents = type(contained_type).__name__ else: contents = str(contained_type) return txt + "[" + contents + "]" return txt
def defaultdict(localization, proxy_obj, arguments): ret = StandardWrapper(defaultdict()) ret.stypy_default_value = types.NoneType if len(arguments) == 0: return ret if len(arguments) == 2: if hasattr(arguments[1], 'wrapped_type') and type( arguments[1].wrapped_type) is defaultdict: d = arguments[1] else: d = StandardWrapper(dict()) set_contained_elements_type_for_key( d, get_contained_elements_type(arguments[1]), get_contained_elements_type(arguments[1])) return StandardWrapper(defaultdict(arguments[0], d)) else: if can_store_keypairs(arguments[0]): if compare_type(arguments[0], types.DictProxyType): if isinstance(arguments[0], StandardWrapper): contents = arguments[0].get_wrapped_type() else: contents = arguments[0] ret = defaultdict(contents) ret.stypy_default_value = contents ret = StandardWrapper(ret) return ret return arguments[0] else: if can_store_elements(arguments[0]): contents = get_contained_elements_type(arguments[0]) if not compare_type(contents, tuple): return StypyTypeError.object_must_be_type_error( localization, 'Iterable argument to build a dictionary', '(key,value) tuple') else: keys = get_contained_elements_type(contents) values = keys if isinstance(keys, union_type.UnionType): keys = keys.types else: keys = [keys] for key in keys: set_contained_elements_type_for_key( ret, key, values) return ret else: ret.setdefault(arguments[0]) if arguments[0] is types.NoneType: ret.stypy_default_value = arguments[0] else: if hasattr(arguments[0], '__name__'): ret.stypy_default_value = get_builtin_python_type_instance( localization, arguments[0].__name__) else: return StypyTypeError( localization, "Invalid first parameter of defaultdict constructor: it must be a type or None" ) return ret
def __set_contained_elements_type(localization, container, elements): """ Modifies the types stored by a container, not dealing with union type indexes :param localization: :param container: :param elements: :return: """ Localization.set_current(localization) if is_error_type(container): return container try: if type(elements) is tuple: # Key, value data structures if type_containers.can_store_keypairs(container): return type_containers.set_contained_elements_type_for_key(container, elements[0], elements[1]) # Indexable data structures if type_containers.can_store_elements(container): if not type_group_generator.Integer == type(elements[0]): if not hasattr(container, '__index__'): # Ellipsis if not (type_inspection.compare_type(elements[0], slice) and (type_inspection.compare_type( elements[1], slice) or type_inspection.compare_type( elements[1], list))): return StypyTypeError(localization, "Indexes of indexable containers must be Integers or instances that " "implement the __index__ method") else: index_getter = getattr(container, '__index__') if index_getter is not None: if hasattr(index_getter, '__objclass__') and not index_getter.__objclass__.__name__ == "ndarray": # res = invoke(localization, container, '__index__') res = invoke(localization, index_getter) if not type_group_generator.Integer == type(res): return StypyTypeError(localization, "Indexes of indexable containers must be Integers or instances that " "implement the __index__ method") else: # Other classes that define __setitem__ m_set = type_containers.get_setitem_method(container) if m_set is not None: try: return m_set(localization, *elements) except TypeError: return m_set(*elements) if type_containers.is_slice(elements[0]): if type_containers.can_store_elements(elements[1]): return type_containers.set_contained_elements_type(container, type_containers.get_contained_elements_type( elements[1])) else: return type_containers.set_contained_elements_type(container, elements[1]) else: return type_containers.set_contained_elements_type(container, elements[1]) type_containers.set_contained_elements_type(container, elements) except Exception as ex: return StypyTypeError(localization, "Cannot store elements '{1}' into an object of type '{0}': {2}".format( type(container), str(elements), str(ex)) )