def __getitem__(localization, proxy_obj, arguments): if type(arguments[0]) is str: # string with a concrete value if arguments[0] is not str(): ret = get_contained_elements_type_for_key( get_self(proxy_obj), arguments[0]) if ret is UndefinedType: ret = get_contained_elements_type_for_key( get_self(proxy_obj), str()) if ret is UndefinedType: return StypyTypeError( localization, "No elements exist for the key {0}".format( arguments[0])) else: return ret else: return ret else: # String with an undefined value self_obj = get_self(proxy_obj) union_ret = None for key in self_obj.keys(): if key is arguments[0] or type(arguments[0]) is type(key): union_ret = union_type.UnionType.add( union_ret, get_contained_elements_type_for_key(self_obj, key)) return union_ret ret = get_contained_elements_type_for_key(get_self(proxy_obj), arguments[0]) if ret is UndefinedType: return StypyTypeError.key_error(localization, arguments[0]) return ret
def update(localization, proxy_obj, arguments): ret = get_self(proxy_obj) param = arguments[0] if can_store_keypairs(param): keys = get_key_types(param) if isinstance(keys, union_type.UnionType): keys = keys.types else: keys = list(keys) for key in keys: value = get_contained_elements_type_for_key(param, key) set_contained_elements_type_for_key(ret, key, value) else: if param.can_store_elements(): contents = get_contained_elements_type(param) if isinstance(contents, tuple): keys = get_contained_elements_type(contents) values = get_contained_elements_type(contents) for key in keys: set_contained_elements_type_for_key(ret, key, values) else: return StypyTypeError.invalid_length_error( localization, "Dictionary 'update' sequence", 1, 2) else: return StypyTypeError.object_must_be_type_error( localization, "The 'update' method second parameter", "dict or an iterable object") return ret
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(localization, proxy_obj, arguments): ret = get_contained_elements_type_for_key(get_self(proxy_obj), arguments[0]) if ret is UndefinedType: if len(arguments) > 1: return arguments[1] else: return types.NoneType return ret
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 get_values_from_key(obj, key): return get_contained_elements_type_for_key(obj, key)