Skip to content

Release 0.6.5

Choose a tag to compare

@OutSquareCapital OutSquareCapital released this 09 Jan 16:04
· 1986 commits to master since this release

πŸš€ pyochain 0.6.5 β€” Release Notes

Date: 2026-01-09 πŸ“…

πŸ†• Highlights

β€’ Iter.unzip() & Iter.repeat() now fully lazy β€” Memory-efficient evaluation using itertools.tee()
β€’ PyoCollection mixin trait β€” New shared collection trait
β€’ Iter.from_ref() & .cloned() β€” New lazy copying methods for efficient Iter branching
β€’ Sorting refactor β€” Iter.is_sorted() split into Iter.is_sorted() and Iter.is_sorted_by(key=...)
β€’ Iter.try_collect() narrowed β€” Now focuses on Option/Result types only
β€’ 3 Breaking Changes β€” See section below for migration guide

πŸ”„ API Changes & New Features

New Trait

PyoCollection is a new mixin trait for all Collection types

Provides:

  • .length() and .contains() methods
  • Implementations for __len__ and __contains__ dunders methods
  • collections.abc.Collection inerhitance and valid implementation

Iter.is_sorted(key=...) β€” Removed. Must use Iter.is_sorted_by(key=...) for key-based sorting checks.

>>> import pyochain as pc
>>> pc.Iter([1, 2, 3, 4]).is_sorted()
True
>>> pc.Iter(["1", "2", "3"]).is_sorted_by(key=int)
True

Iter.try_collect() β€” Now only accepts Iter[Option[T]] or Iter[Result[T, E]]. Removed support for Iter[T | None].
❌ Before - now broken

import pyochain as pc
pc.Iter([1, None, 3]).try_collect()

βœ… After - must use Option

>>> import pyochain as pc
>>> pc.Iter([pc.Some(1), pc.Some(2), pc.Some(3)]).try_collect()
Some(Vec(1, 2, 3))
>>> pc.Iter([pc.Ok(1), pc.Ok(2)]).try_collect()
Some(Vec(1, 2))
>>> pc.Iter([pc.Some(1), pc.NONE, pc.Some(3)]).try_collect()
NONE
>>> # If you need old behavior, map to Option first
>>> pc.Iter([1, None, 3]).map(pc.Option).try_collect()
NONE

Dict.contains_key() β€” Replaced. Moved to PyoCollection.contains() for shared usability across all collection types.

>>> import pyochain as pc
>>> d = pc.Dict({1: "a", 2: "b"})
>>> d.contains(1)
True
>>> pc.Seq([1, 2, 3]).contains(2)
True
>>> pc.Set({1, 2, 3}).contains(3)
True

repeat method β€” Both methods repeat Self as elements in a new Iter, but differ in internal implementation:

  • PyoCollection.repeat(n) returns an Iter[Self] where each element is the entire (eager) collection repeated n times lazily. This was the previous behavior of Iter.repeat(), which collected eagerly the data original data in an hidden way who might be confusing.
  • Iter.repeat(n) returns an Iter[Iter[T]] and is fully lazy (outer and inners Iter)

In other words:

  • Iter.repeat return an Iterator of Iterator
  • PyoCollection.repeat an Iterator of Collection
>>> import pyochain as pc
>>> pc.Iter([1, 2]).repeat(2).map(list).collect()
Seq([1, 2], [1, 2])
>>> pc.Seq([1, 2]).repeat(2).map(list).collect()
Seq([1, 2], [1, 2])

Iter.from_ref() / .cloned() β€” New lazy methods for efficient Iter copying using itertools.tee()

>>> import pyochain as pc
>>> iter1 = pc.Iter([1, 2, 3])
>>> iter2 = pc.Iter.from_ref(iter1)
>>> # Both can be consumed independently
>>> iter1.take(2).collect()
Seq(1, 2)
>>> iter2.collect()
Seq(1, 2, 3)

Iter.empty() β†’ Iter.new() β€” Consolidated at PyoIterable level (deprecated)

>>> import pyochain as pc
>>> pc.Iter.new().collect()
Seq()
>>> pc.Seq.new()
Seq()

⚑ Performance & Memory Improvements

β€’ Iter.unzip() β€” Now fully lazy using itertools.tee() instead of eager collection
β€’ Iter.try_collect() β€” Narrowed to Option/Result types only, reduced code paths and internal list optimization
β€’ Iter.repeat() β€” Fixed to be truly lazy with proper generator chaining


πŸ“š Documentation Updates

β€’ Added PyoIterable and PyoCollection reference pages
β€’ Improved Iter.product() examples
β€’ Various docstring improvements and warning block formatting fixes

🎯 Upgrade Recommendations

  1. βœ… Update Iter.empty() β†’ Iter.new() if you use it
  2. ⚠️ Update is_sorted(key=func) β†’ is_sorted_by(key=func) β€” Breaking change
  3. ⚠️ Update Iter.try_collect() for Option/Result types only β€” Breaking change, no more U | None support
  4. βœ… Update Dict.contains_key() β†’ Dict.contains() β€” Now unified across all collections
  5. βœ… Consider using Iter.from_ref() and .cloned() for better lazy copying
  6. βœ… Leverage PyoCollection trait if implementing custom collections

Questions? Report issues on our GitHub Issues page.