Skip to content

Add Stream.isAtEnd() (AI) - #2007

Open
sankalpsthakur wants to merge 3 commits into
cuthbertLab:masterfrom
sankalpsthakur:stream-is-at-end
Open

Add Stream.isAtEnd() (AI)#2007
sankalpsthakur wants to merge 3 commits into
cuthbertLab:masterfrom
sankalpsthakur:stream-is-at-end

Conversation

@sankalpsthakur

Copy link
Copy Markdown

Fixes #1069

Adds Stream.isAtEnd(element) next to storeAtEnd(), using the form
agreed on the issue:

return self.elementOffset(element, returnSpecial=True) is OffsetSpecial.AT_END

If the element is not in the Stream, SitesException from elementOffset
is left uncaught.

quantize() already iterates useStream._elements, so end elements are
already skipped. Other _endElements uses are Stream internals, freeze/thaw,
tree construction, or the getOffsetBySite fallback after elementOffset
has already failed. None of those were a safe one-line swap to isAtEnd().

Tests:

uv run pytest \
  music21/stream/tests.py::Test::testIsAtEnd \
  music21/stream/tests.py::Test::testStoreAtEndFailures \
  music21/stream/tests.py::Test::testElementsHighestTimeA \
  music21/stream/tests.py::Test::testElementsHighestTimeB \
  music21/stream/tests.py::Test::testElementsHighestTimeC \
  music21/stream/base.py::music21.stream.base.Stream.isAtEnd \
  music21/stream/base.py::music21.stream.base.Stream.storeAtEnd

7 passed.

uv run ruff check music21/stream/base.py music21/stream/tests.py
uv run mypy music21/stream/base.py

both passed.

This PR is entirely AI written.

AI/LLM disclosure

  • AI coding tools (including Grok and/or Codex agent-assisted editing) were used to help draft or modify code and this PR description.
  • I reviewed the complete change, understand the reasoning, and ran the reported local tests before submitting.
  • This submission is original work of authorship under the project CLA / contributor terms; AI output was not pasted unreviewed.

@coveralls

coveralls commented Aug 22, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 93.332% (+0.003%) from 93.329% — sankalpsthakur:stream-is-at-end into cuthbertLab:master

@mscuthbert

Copy link
Copy Markdown
Member

Thank you! Please document and give an example of the error case of an element not in stream. Thanks for making the docs concise.

Please have agent check whether this is any place in the codebase where we should have used this (possibly not any cases but just have it check )

@sankalpsthakur

Copy link
Copy Markdown
Author

Error case is in the docstring now (SitesException when the element is not in the Stream).

No call sites to switch. The _endElements reads are Stream internals, freeze/thaw, tree build, and __contains__ (already covered by _offsetDict). The getOffsetBySite fallback after elementOffset fails cannot call isAtEnd() without recursing.

@jacobtylerwalls

Copy link
Copy Markdown
Member

The use case I had in mind was to replace iterations over _elements, not _endElements. See the main loop in quantize(). You could iterate elements, and continue if isAtEnd.

quantize() iterated the private _elements to avoid touching elements
stored at the end. Iterate the public .elements instead and skip them
with the new isAtEnd(), which is the use case the method was added for.

This is not only cosmetic: elementOffset() returns a concrete offset for
an at-end element, so quantizing one would overwrite its AT_END marker
while leaving it in _endElements. The added test fails without the skip.
@sankalpsthakur

Copy link
Copy Markdown
Author

good call, that one works. quantize() now iterates .elements and continues on isAtEnd instead of reaching into _elements. it turned out not to be cosmetic: elementOffset returns a real offset for an at-end element, so quantizing one clears its AT_END marker while it stays in _endElements. added a test that fails without the skip.

@mscuthbert

Copy link
Copy Markdown
Member

The use case I had in mind was to replace iterations over _elements, not _endElements. See the main loop in quantize(). You could iterate elements, and continue if isAtEnd.

I barely remember that .elements exists as a public method (so old! so flaky because of activeSites). I wonder if we might expose it in another way....well, I'll make a discussion issue about StreamCore anyhow soon...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Need a Stream method for finding whether a contained element is in its _endElements

4 participants