mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
fix: incorrect Dict!.update!
typing
This commit is contained in:
parent
eedbfc27dc
commit
d3304b3491
6 changed files with 52 additions and 17 deletions
|
@ -547,6 +547,7 @@ impl Context {
|
|||
return self.supertype_of(&evaled, rhs);
|
||||
}
|
||||
}
|
||||
// REVIEW: is this OK?
|
||||
if lhs.has_unbound_var() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3953,17 +3953,20 @@ impl Context {
|
|||
)
|
||||
.quantify();
|
||||
dict_mut.register_py_builtin(PROC_SETDEFAULT, setdefault_t, Some(FUNC_SETDEFAULT), 69);
|
||||
let update_t = pr_met(
|
||||
let update_t = kw_var_pr_met(
|
||||
ref_mut(dict_mut_kv_t.clone(), None),
|
||||
vec![kw(
|
||||
KW_ITERABLE,
|
||||
poly(ITERABLE, vec![ty_tp(tuple_t(vec![K.clone(), V.clone()]))]),
|
||||
)],
|
||||
vec![],
|
||||
None,
|
||||
vec![kw(
|
||||
KW_CONFLICT_RESOLVER,
|
||||
func2(V.clone(), V.clone(), V.clone()),
|
||||
)],
|
||||
vec![
|
||||
kw(
|
||||
KW_ITERABLE,
|
||||
// TODO: Iterable((K, V)) | {K: V}(<: Iterable(K))
|
||||
poly(ITERABLE, vec![ty_tp(tuple_t(vec![K.clone(), V.clone()]))])
|
||||
| mono(GENERIC_DICT),
|
||||
),
|
||||
kw(KW_CONFLICT_RESOLVER, func2(V.clone(), V.clone(), V.clone())),
|
||||
],
|
||||
Some(pos(Obj)),
|
||||
NoneType,
|
||||
)
|
||||
.quantify();
|
||||
|
|
|
@ -15,9 +15,9 @@ class Dict(dict):
|
|||
return Dict({k: v for k, v in self.items() if k not in other})
|
||||
|
||||
# other: Iterable
|
||||
def update(self, other, conflict_resolver=None):
|
||||
def update(self, other={}, conflict_resolver=None, **kwargs):
|
||||
if conflict_resolver is None:
|
||||
super().update(other)
|
||||
super().update(other, **kwargs)
|
||||
elif isinstance(other, dict):
|
||||
self.merge(other, conflict_resolver)
|
||||
else:
|
||||
|
@ -26,10 +26,15 @@ class Dict(dict):
|
|||
self[k] = conflict_resolver(self[k], v)
|
||||
else:
|
||||
self[k] = v
|
||||
self.merge(kwargs, conflict_resolver)
|
||||
|
||||
# other: Dict
|
||||
def merge(self, other, conflict_resolver=None):
|
||||
self.update(other, conflict_resolver)
|
||||
for k, v in other.items():
|
||||
if k in self and conflict_resolver is not None:
|
||||
self[k] = conflict_resolver(self[k], v)
|
||||
else:
|
||||
self[k] = v
|
||||
|
||||
def insert(self, key, value):
|
||||
self[key] = value
|
||||
|
|
|
@ -201,6 +201,8 @@ impl OwnershipChecker {
|
|||
.find(|(k, _)| k.as_ref() == Some(kw_arg.keyword.inspect()))
|
||||
{
|
||||
self.check_expr(&kw_arg.expr, *ownership, false);
|
||||
} else if let Some((_, ownership)) = args_owns.kw_var_params.as_ref() {
|
||||
self.check_expr(&kw_arg.expr, *ownership, false);
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -498,20 +498,19 @@ pub fn fn2_met(self_t: Type, l: Type, r: Type, return_t: Type) -> Type {
|
|||
|
||||
pub fn pr_met(
|
||||
self_t: Type,
|
||||
mut non_default_params: Vec<ParamTy>,
|
||||
non_default_params: Vec<ParamTy>,
|
||||
var_params: Option<ParamTy>,
|
||||
default_params: Vec<ParamTy>,
|
||||
return_t: Type,
|
||||
) -> Type {
|
||||
non_default_params.insert(0, ParamTy::kw(Str::ever("self"), self_t));
|
||||
Type::Subr(SubrType::new(
|
||||
SubrKind::Proc,
|
||||
kw_var_pr_met(
|
||||
self_t,
|
||||
non_default_params,
|
||||
var_params,
|
||||
default_params,
|
||||
None,
|
||||
return_t,
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
pub fn pr0_met(self_t: Type, return_t: Type) -> Type {
|
||||
|
@ -526,6 +525,25 @@ pub fn pr1_kw_met(self_t: Type, input: ParamTy, return_t: Type) -> Type {
|
|||
pr_met(self_t, vec![input], None, vec![], return_t)
|
||||
}
|
||||
|
||||
pub fn kw_var_pr_met(
|
||||
self_t: Type,
|
||||
mut non_default_params: Vec<ParamTy>,
|
||||
var_params: Option<ParamTy>,
|
||||
default_params: Vec<ParamTy>,
|
||||
kw_var_params: Option<ParamTy>,
|
||||
return_t: Type,
|
||||
) -> Type {
|
||||
non_default_params.insert(0, ParamTy::kw(Str::ever("self"), self_t));
|
||||
Type::Subr(SubrType::new(
|
||||
SubrKind::Proc,
|
||||
non_default_params,
|
||||
var_params,
|
||||
default_params,
|
||||
kw_var_params,
|
||||
return_t,
|
||||
))
|
||||
}
|
||||
|
||||
/// function type with non-default parameters
|
||||
#[inline]
|
||||
pub fn nd_func(params: Vec<ParamTy>, var_params: Option<ParamTy>, ret: Type) -> Type {
|
||||
|
|
|
@ -20,3 +20,9 @@ Manager.
|
|||
show_tasks! self, id: Int =
|
||||
for! self.tasks, task =>
|
||||
print! task[id]
|
||||
|
||||
sd as Dict! {Str: Int} = !{"a": 1}
|
||||
sd.update!([("b", 2)])
|
||||
sd.update! {"c": 3}
|
||||
sd.update! d := 1
|
||||
assert sd == {"a": 1, "b": 2, "c": 3, "d": 1}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue