Casts a non-null Starlark value x to a Dict after checking that all keys and values are instances of keyType and valueType, respectively. On error, it throws an EvalException whose message includes what, ideally a string literal, as a description of the
(Object x, Class<K> keyType, Class<V> valueType, String what)
| 657 | * description of the role of {@code x}. If x is null, it returns an immutable empty dict. |
| 658 | */ |
| 659 | public static <K, V> Dict<K, V> cast(Object x, Class<K> keyType, Class<V> valueType, String what) |
| 660 | throws EvalException { |
| 661 | Preconditions.checkNotNull(x); |
| 662 | if (!(x instanceof Dict)) { |
| 663 | throw Starlark.errorf("got %s for '%s', want dict", Starlark.type(x), what); |
| 664 | } |
| 665 | |
| 666 | for (Map.Entry<?, ?> e : ((Map<?, ?>) x).entrySet()) { |
| 667 | if (!keyType.isAssignableFrom(e.getKey().getClass()) |
| 668 | || !valueType.isAssignableFrom(e.getValue().getClass())) { |
| 669 | // TODO(adonovan): change message to "found <K2, V2> entry", |
| 670 | // without suggesting that the entire dict is <K2, V2>. |
| 671 | throw Starlark.errorf( |
| 672 | "got dict<%s, %s> for '%s', want dict<%s, %s>", |
| 673 | Starlark.type(e.getKey()), |
| 674 | Starlark.type(e.getValue()), |
| 675 | what, |
| 676 | Starlark.classType(keyType), |
| 677 | Starlark.classType(valueType)); |
| 678 | } |
| 679 | } |
| 680 | |
| 681 | @SuppressWarnings("unchecked") // safe |
| 682 | Dict<K, V> res = (Dict<K, V>) x; |
| 683 | return res; |
| 684 | } |
| 685 | |
| 686 | /** Like {@link #cast}, but if x is None, returns an empty Dict. */ |
| 687 | public static <K, V> Dict<K, V> noneableCast( |
no test coverage detected