@@ -20,7 +20,7 @@ _T = TypeVar('_T')
2020# Non-callable types accepted by the extended function protocol (funcmakers.make_func):
2121# int/slice for itemgetter, str/bytes/re.Pattern for regex,
2222# Mapping for lookup, Set for membership, None for identity/bool
23- # FIX: should include Callable into _Func, it's unied anyway all the time
23+ # FIX: should include Callable into _Func, it's unied anyway all the time, also name it _XFunc
2424_Func = int | slice | str | bytes | re.Pattern[str] | Mapping[Any, Any] | AbstractSet[Any] | None
2525_ReResult: TypeAlias = str | tuple[str, ...] | dict[str, str]
2626
@@ -43,75 +43,48 @@ def merge_with(f: Callable[[list[Any]], _V], *dicts: Mapping[_K, Any]) -> dict[_
4343
4444### Walk / Select
4545
46- # 1-param collections × XFunc (quadratic expansion)
47- # FIX: add abstract collections like MutableMapping, Mapping, Sequence, Set, Iterator, Iterable
48- # drop catch all stuff
49- # RES: Sequence, Set, Iterator, Iterable not added - constructors not guaranteed to accept iterables,
50- # and Set/frozenset already covered by concrete expansion above
51- # FIX: the above RES is untrue, walk will work with all of the above
52- def walk[C: (list, set, frozenset)](f: XFunc[[_T], _V], coll: C[_T]) -> C[_V]: ...
5346# dict/MutableMapping/Mapping: typed Callable with pair→pair signature
54- # FIX: this also works with collections of pairs, add a test and fix it here
55- # also might need to reorder. Relying on last catch all is not the best solution!
56- # We loose type checking of arguments, i.e. that element types match callable
57- def walk(f: Callable[[tuple[_K, _V]], tuple[_K2, _V2]], coll: dict[_K, _V]) -> dict[_K2, _V2]: ...
58- def walk(f: Callable[[tuple[_K, _V]], tuple[_K2, _V2]], coll: MutableMapping[_K, _V]) -> dict[_K2, _V2]: ...
59- def walk(f: Callable[[tuple[_K, _V]], tuple[_K2, _V2]], coll: Mapping[_K, _V]) -> dict[_K2, _V2]: ...
47+ # (must come before COLLS — dict is Iterable[K], so Iterable overload would shadow)
48+ def walk[C: MAPS](f: Callable[[tuple[_K, _V]], tuple[_K2, _V2]], coll: C[_K, _V]) -> C[_K2, _V2]: ...
6049# catch-alls for _Func and other collection types
61- def walk(f: Callable[..., Any] | _Func, coll: dict[Any, Any]) -> dict[Any, Any]: ...
50+ def walk[C: MAPS](f: Callable[..., Any] | _Func, coll: C[Any, Any]) -> C[Any, Any]: ...
51+ # 1-param collections × XFunc (quadratic expansion)
52+ def walk[C: COLLS](f: XFunc[[_T], _V], coll: C[_T]) -> C[_V]: ...
53+ # catch-all for other collection types
6254def walk(f: Callable[..., Any] | _Func, coll: _T) -> _T: ...
6355
6456# walk_keys: collection of pairs × XFunc
6557# xfunc_skip: slice
66- def walk_keys[C: (list, set, frozenset)](f: XFunc[[_K], _K2], coll: C[tuple[_K, _V]]) -> C[tuple[_K2, _V]]: ...
67- # walk_keys: dict/MutableMapping/Mapping always returns dict
68- # xfunc_skip: slice
69- def walk_keys(f: XFunc[[_K], _K2], coll: dict[_K, _V]) -> dict[_K2, _V]: ...
58+ def walk_keys[C: COLLS](f: XFunc[[_K], _K2], coll: C[tuple[_K, _V]]) -> C[tuple[_K2, _V]]: ...
7059# xfunc_skip: slice
71- def walk_keys(f: XFunc[[_K], _K2], coll: MutableMapping[_K, _V]) -> dict[_K2, _V]: ...
72- # xfunc_skip: slice
73- def walk_keys(f: XFunc[[_K], _K2], coll: Mapping[_K, _V]) -> dict[_K2, _V]: ...
60+ def walk_keys[C: MAPS](f: XFunc[[_K], _K2], coll: C[_K, _V]) -> C[_K2, _V]: ...
7461
75- # walk_values: collection of pairs × XFunc
76- def walk_values[C: (list, set, frozenset)](f: XFunc[[_V], _V2], coll: C[tuple[_K, _V]]) -> C[tuple[_K, _V2]]: ...
77- # walk_values: dict/MutableMapping/Mapping always returns dict
78- def walk_values(f: XFunc[[_V], _V2], coll: dict[_K, _V]) -> dict[_K, _V2]: ...
79- def walk_values(f: XFunc[[_V], _V2], coll: MutableMapping[_K, _V]) -> dict[_K, _V2]: ...
80- def walk_values(f: XFunc[[_V], _V2], coll: Mapping[_K, _V]) -> dict[_K, _V2]: ...
62+ def walk_values[C: COLLS](f: XFunc[[_V], _V2], coll: C[tuple[_K, _V]]) -> C[tuple[_K, _V2]]: ...
63+ def walk_values[C: MAPS](f: XFunc[[_V], _V2], coll: C[_K, _V]) -> C[_K, _V2]: ...
8164
82- # 1-param collections × XPred
83- def select[C: (list, set, frozenset)](pred: XPred[_T], coll: C[_T]) -> C[_T]: ...
8465# dict/Mapping: pred receives (key, value) pairs, only Callable is meaningful
66+ # (must come before COLLS — dict is Iterable[K], so Iterable overload would shadow these)
8567# FIX: should use coll parametrization here
86- def select(pred: Callable[[tuple[_K, _V]], Any], coll: dict [_K, _V]) -> dict [_K, _V]: ...
87- def select(pred: Callable[[tuple[_K, _V]], Any], coll: MutableMapping[_K, _V]) -> MutableMapping[_K, _V]: ...
88- def select(pred: Callable[[tuple[_K, _V]], Any], coll: Mapping[_K, _V ]) -> Mapping[_K, _V ]: ...
68+ def select[C: MAPS] (pred: Callable[[tuple[_K, _V]], Any], coll: C [_K, _V]) -> C [_K, _V]: ...
69+ # 1-param collections × XPred
70+ def select[C: COLLS] (pred: XPred[_T], coll: C[_T ]) -> C[_T ]: ...
8971# catch-all for other collection types
9072def select(pred: Callable[..., Any] | _Func, coll: _T) -> _T: ...
9173# select_keys: collection of pairs × XPred
92- def select_keys[C: (list, set, frozenset) ](pred: XPred[_K], coll: C[tuple[_K, _V]]) -> C[tuple[_K, _V]]: ...
74+ def select_keys[C: COLLS ](pred: XPred[_K], coll: C[tuple[_K, _V]]) -> C[tuple[_K, _V]]: ...
9375# select_keys: dict/MutableMapping/Mapping
94- def select_keys[C: (dict, MutableMapping, Mapping)](pred: XPred[_K], coll: C[_K, _V]) -> C[_K, _V]: ...
95-
96- # FIX0: looks like we are getting lazy everywhere, i.e. here it should be not (list, set, frozenset)
97- # but (list, tuple[T, ...], set, frozenset, Sequence, Iterator, Iterable)
98- # and this is repeating patterns, so let's come up with a systemic decision, we'll add aliases
99- # like ALL_SEQUENCES, ALL_MAPPINGS, ALL_CONTAINERS - these should be global find a good place
100- # for those maybe a separate pyih file like global.pyih or defines.pyih. Then use those aliases
101- # instead of literal listing collection types. Update our pyih translator to support this.
102- #
103- # Maybe move other global stuff there too. Could be imports?
76+ def select_keys[C: MAPS](pred: XPred[_K], coll: C[_K, _V]) -> C[_K, _V]: ...
77+
10478# select_values: collection of pairs × XPred
105- def select_values[C: (list, set, frozenset) ](pred: XPred[_V], coll: C[tuple[_K, _V]]) -> C[tuple[_K, _V]]: ...
79+ def select_values[C: COLLS ](pred: XPred[_V], coll: C[tuple[_K, _V]]) -> C[tuple[_K, _V]]: ...
10680# select_values: dict/MutableMapping/Mapping
107- def select_values[C: (dict, MutableMapping, Mapping) ](pred: XPred[_V], coll: C[_K, _V]) -> C[_K, _V]: ...
81+ def select_values[C: MAPS ](pred: XPred[_V], coll: C[_K, _V]) -> C[_K, _V]: ...
10882
10983def split_keys(pred: XPred[_K], coll: Mapping[_K, _V]) -> tuple[dict[_K, _V], dict[_K, _V]]: ...
11084
111- def compact[C: (list, set, frozenset)](coll: C[_T]) -> C[_T]: ...
112- def compact(coll: dict[_K, _V]) -> dict[_K, _V]: ...
113- def compact(coll: MutableMapping[_K, _V]) -> MutableMapping[_K, _V]: ...
114- def compact(coll: Mapping[_K, _V]) -> Mapping[_K, _V]: ...
85+ # (dict/Mapping must come before COLLS — dict is Iterable[K], so Iterable overload would shadow)
86+ def compact[C: MAPS](coll: C[_K, _V]) -> C[_K, _V]: ...
87+ def compact[C: COLLS](coll: C[_T]) -> C[_T]: ...
11588def compact(coll: _T) -> _T: ...
11689
11790### Content tests
@@ -137,10 +110,10 @@ def some(pred: XPred[_T], seq: Iterable[_T]) -> _T | None: ...
137110### Dict utilities
138111
139112def zipdict(keys: Iterable[_K], vals: Iterable[_V]) -> dict[_K, _V]: ...
140- def flip[C: (dict, MutableMapping, Mapping) ](mapping: C[_K, _V]) -> C[_V, _K]: ...
141- def flip[C: (list, set, frozenset) ](coll: C[tuple[_K, _V]]) -> C[tuple[_V, _K]]: ...
142- def project[C: (dict, MutableMapping, Mapping) ](mapping: C[_K, _V], keys: Iterable[_K]) -> C[_K, _V]: ...
143- def omit[C: (dict, MutableMapping, Mapping) ](mapping: C[_K, _V], keys: Iterable[_K]) -> C[_K, _V]: ...
113+ def flip[C: MAPS ](mapping: C[_K, _V]) -> C[_V, _K]: ...
114+ def flip[C: COLLS ](coll: C[tuple[_K, _V]]) -> C[tuple[_V, _K]]: ...
115+ def project[C: MAPS ](mapping: C[_K, _V], keys: Iterable[_K]) -> C[_K, _V]: ...
116+ def omit[C: MAPS ](mapping: C[_K, _V], keys: Iterable[_K]) -> C[_K, _V]: ...
144117
145118def zip_values(*dicts: Mapping[_K, _V]) -> Iterator[tuple[_V, ...]]: ...
146119def zip_dicts(*dicts: Mapping[_K, _V]) -> Iterator[tuple[_K, tuple[_V, ...]]]: ...
@@ -149,11 +122,11 @@ def zip_dicts(*dicts: Mapping[_K, _V]) -> Iterator[tuple[_K, tuple[_V, ...]]]: .
149122
150123def get_in(coll: Mapping[Any, Any] | Sequence[Any], path: Iterable[Any], default: Any = ...) -> Any: ...
151124def get_lax(coll: Mapping[Any, Any] | Sequence[Any], path: Iterable[Any], default: Any = ...) -> Any: ...
152- def set_in[C: (dict, MutableMapping) ](coll: C[_K, _V], path: Sequence[Any], value: Any) -> C[_K, _V]: ...
125+ def set_in[C: MUT_MAPS ](coll: C[_K, _V], path: Sequence[Any], value: Any) -> C[_K, _V]: ...
153126def set_in(coll: _T, path: Sequence[Any], value: Any) -> _T: ...
154- def update_in[C: (dict, MutableMapping) ](coll: C[_K, _V], path: Sequence[Any], update: Callable[[Any], Any], default: Any = ...) -> C[_K, _V]: ...
127+ def update_in[C: MUT_MAPS ](coll: C[_K, _V], path: Sequence[Any], update: Callable[[Any], Any], default: Any = ...) -> C[_K, _V]: ...
155128def update_in(coll: _T, path: Sequence[Any], update: Callable[[Any], Any], default: Any = ...) -> _T: ...
156- def del_in[C: (dict, MutableMapping) ](coll: C[_K, _V], path: Sequence[Any]) -> C[_K, _V]: ...
129+ def del_in[C: MUT_MAPS ](coll: C[_K, _V], path: Sequence[Any]) -> C[_K, _V]: ...
157130def del_in(coll: _T, path: Sequence[Any]) -> _T: ...
158131def has_path(coll: Mapping[Any, Any] | Sequence[Any], path: Iterable[Any]) -> bool: ...
159132
0 commit comments