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)