You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The base class for non-mutable abstract sets, collections.abc.Set (and a few others in Lib/_collections_abc.py) provide a classmethod(_from_iterable(Iterable[...]) -> Set[...]) (or similar) class method, which serves as a single place to override how the results of set-wise operations are constructed.
The class method in question, _from_iterable(), doesn't appear anywhere in typeshed (GitHub search of this repo, 2026-01-17).
Motivating example: I have a set-like class Region which acts as a set of all co-ordinates in a 2D area bounded min/max x and y co-ordinates. The results of set-wise operations involving a Region often aren't rectangular, and so can't be represented by a Region. Without _from_iterable(), collections.abc.Set tries to construct the result as Region(<Iterable[Coord]>), which won't (and can't) work. By overriding Set._from_iterable() in Region, I can construct results as set or frozenset instances, which can represent the results in all cases.
_from_iterable is documented for Set and MutableSet in the documentation (footnote 1), so we should include it. The only problems is that it doesn't exist in typing.{Set,AbstractSet}, and these types are identical in typeshed.
A problem I see with this is that _from_iterable does not exist on the canonical frozenset, set, dict_keys and dict_item_types:
deff(x: MutableSet) ->MutableSet:
returntype(x)._from_iterable(x) # passes type checking if this issue is acceptedf( {1,2,3} ) # Error at runtime
So I'd propose to defer this proposal, it's imo more important that the exposed interface of AbstractSet and MutableSet in typeshed is compatible with builtins.frozenset and builtins.set.
If OP of someone else gets builtins.set to implement _from_iterable in cpython, then this should be included of course.
OK, so upstream doesn't plan on supporting _from_iterable on builtins.set. The best we could do then is add a comment or put the method into a if not TYPE_CHECKING block (does that let IDEs discover the method?)
I think we should add the method regardless, as that is closer to runtime, and we prefer false negatives (a type checker not flagging a call to set._from_iterable) over false positives (a type checker flagging a call to MySet()._from_iterable()).
The underlying problem here is how "registering" ABCs and static type checking doesn't work together well.
Edit: Also an argument to do something like in #15152 for set types.
@srittau I think we need to be carefule here. Type checkers are used as language servers. Merging this may mean users get tab completition for set._from[tab], which is very irritating. You shouldn't get tab completition for methods that don't exist.
The underlying problem here is how "registering" ABCs and static type checking doesn't work together well.
Yes, the "original sin" here is that ABCs (and protocols too, unfortunately, if you explicitly inherit from them...) try to serve both as abstract interfaces and mixin classes in Python. But I lean towards @randolf-scholz's opinion here. For these very fundamental ABCs, where many runtime types pretend that they inherit from them even though they don't, I feel like we should emphasise soundness here. We should make the interfaces as broad and general as possible, so that AbstractSet accurately reflects the idea of what it really means for a class to be "set-like" in Python in an abstract sense.
I think this is the same principle that we applied in #15085, and aligns with Jelle's argument in #13432 (comment).
Activity
[-]`collections.abc.Set`, etc., missing `classmethod(_from_iterable(Iterable[...]) -> Set[...])`[/-][+]`collections.abc.Set`, etc., missing `_from_iterable()` classmethod[/+]srittau commentedon Jan 19, 2026
_from_iterableis documented forSetandMutableSetin the documentation (footnote 1), so we should include it. The only problems is that it doesn't exist intyping.{Set,AbstractSet}, and these types are identical in typeshed.PR welcome!
randolf-scholz commentedon Feb 7, 2026
A problem I see with this is that
_from_iterabledoes not exist on the canonicalfrozenset,set,dict_keysanddict_item_types:So I'd propose to defer this proposal, it's imo more important that the exposed interface of
AbstractSetandMutableSetin typeshed is compatible withbuiltins.frozensetandbuiltins.set.If OP of someone else gets
builtins.setto implement_from_iterablein cpython, then this should be included of course.randolf-scholz commentedon Feb 7, 2026
@finite-state-machine @srittau I created python/cpython#144557 so we can get some feedback from upstream.
randolf-scholz commentedon Feb 12, 2026
OK, so upstream doesn't plan on supporting
_from_iterableonbuiltins.set. The best we could do then is add a comment or put the method into aif not TYPE_CHECKINGblock (does that let IDEs discover the method?)srittau commentedon Feb 12, 2026
I think we should add the method regardless, as that is closer to runtime, and we prefer false negatives (a type checker not flagging a call to
set._from_iterable) over false positives (a type checker flagging a call toMySet()._from_iterable()).The underlying problem here is how "registering" ABCs and static type checking doesn't work together well.
Edit: Also an argument to do something like in #15152 for set types.
randolf-scholz commentedon Feb 12, 2026
@srittau I think we need to be carefule here. Type checkers are used as language servers. Merging this may mean users get tab completition for
set._from[tab], which is very irritating. You shouldn't get tab completition for methods that don't exist.AlexWaygood commentedon Feb 12, 2026
Yes, the "original sin" here is that ABCs (and protocols too, unfortunately, if you explicitly inherit from them...) try to serve both as abstract interfaces and mixin classes in Python. But I lean towards @randolf-scholz's opinion here. For these very fundamental ABCs, where many runtime types pretend that they inherit from them even though they don't, I feel like we should emphasise soundness here. We should make the interfaces as broad and general as possible, so that
AbstractSetaccurately reflects the idea of what it really means for a class to be "set-like" in Python in an abstract sense.I think this is the same principle that we applied in #15085, and aligns with Jelle's argument in #13432 (comment).
srittau commentedon Feb 12, 2026
Sorry, I didn't see you comment before merging, Alex. That said, this change had no primer fallout, so I don't think this is particularly worrisome.
finite-state-machine commentedon Feb 12, 2026
Thanks, all!