Description
Locations' docstring documents pts as Union[...] or iterable of same, but passing a generator/iterator (e.g. the result of map) raises ValueError. In practice only list, tuple, filter, and set are flattened — other iterables are not.
Reproduction
from build123d import Locations, BuildSketch, Rectangle, Plane
pts = map(lambda p: (p, 0), [10, 20, 30]) # an iterable of VectorLike
with BuildSketch(Plane.XY):
with Locations(pts): # docstring: "iterable of same" should be accepted
Rectangle(1, 1)
Result:
ValueError: Locations doesn't accept type <class 'map'>
Splatting or wrapping in a list works fine:
Locations(*pts) # ok
Locations(list(pts)) # ok
Cause
Locations.__init__ runs its args through flatten_sequence (build_common.py), which only recurses into a hard-coded set of container types:
if isinstance(item, (list, tuple, filter, set)) and not _is_point(item):
flat_list.extend(flatten_sequence(*item))
else:
flat_list.append(item)
A map/generator isn't in that set, so it's appended as a single opaque item and then rejected by the type checks in Locations.__init__.
The # Note: there explains why a blanket isinstance(item, Iterable) check isn't used (Vector/Vertex are iterable and would be broken into floats), so the allow-list is intentional — but it omits the most common lazy iterables (map, generators), which contradicts the documented "iterable of same".
Suggested fix
Either:
- update the docstring to name the actually-supported container types (
list, tuple, filter, set), or
- honor the documented contract by materializing generic iterators while still excluding the point-like iterables (
Vector, Vertex, etc.).
Workaround
Locations(*gen) or Locations(list(gen)).
Environment
- build123d 0.11.0
- Python 3.14
- macOS
Description
Locations' docstring documentsptsasUnion[...] or iterable of same, but passing a generator/iterator (e.g. the result ofmap) raisesValueError. In practice onlylist,tuple,filter, andsetare flattened — other iterables are not.Reproduction
Result:
Splatting or wrapping in a list works fine:
Cause
Locations.__init__runs its args throughflatten_sequence(build_common.py), which only recurses into a hard-coded set of container types:A
map/generator isn't in that set, so it's appended as a single opaque item and then rejected by the type checks inLocations.__init__.The
# Note:there explains why a blanketisinstance(item, Iterable)check isn't used (Vector/Vertexare iterable and would be broken into floats), so the allow-list is intentional — but it omits the most common lazy iterables (map, generators), which contradicts the documented "iterable of same".Suggested fix
Either:
list,tuple,filter,set), orVector,Vertex, etc.).Workaround
Locations(*gen)orLocations(list(gen)).Environment