Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .agents/memory/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ Project-shared agent memory for music21. One file per fact; see frontmatter for
- [sortedcontainers for streams](sortedcontainers-for-streams.md) — tried twice to make streams always-sorted via SortedList; abandoned, too slow for tiny streams
- [Stream subclass generic defaults](stream-subclass-generic-defaults.md) — how `inherit-generics` should work once PEP 696 default type params land; maybe add typing_extensions
- [BFS-flatten-iterator](bfs-flatten-iterator.md) — lazy breadth-first flatten is writable (maybe for tree first), but must not reuse the flat/flatten name tied to offsetInHierarchy
- [Docs: audience separation](docs-audience-separation.md) — maintenance notes and private-method references go in code comments, never public docstrings
- [Docs: no untaken paths](docs-no-untaken-paths.md) — docstrings state what the code does, never contrast with rejected designs
- [Issue #1349 romanNumeral direction](issue-1349-romanNumeral-direction.md) — raised-^6/^7 fix landed; CAUTIONARY default kept; items 2+4 open with pablopupo/Malcolm
- [Meter immutability re-apply](meter-immutability-reapply.md) — meter-speed is too stale to merge; re-apply FrozenDuration + immutable MeterTerminal + tuple NumDenom fresh on master
20 changes: 20 additions & 0 deletions .agents/memory/docs-audience-separation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: docs-audience-separation
description: Public docstrings are for library users; maintenance notes and private-symbol references go in code comments
metadata:
type: feedback
---

Never put maintenance notes ("change one and check the others", refactoring
caveats, cross-references between internal implementations) in music21 public
docstrings, and never reference private (underscore) methods from public
docstrings. Put that material in `#` code comments instead.

**Why:** docstrings render into the published docs and serve library *users*;
comments serve *maintainers*. Myke: "there are different users with different
roles." A user reading the API docs should never see internal plumbing they
cannot call.

**How to apply:** before finishing a doc pass, scan new docstring text for
underscore-prefixed names and maintainer-facing advice; relocate to a comment
just below the docstring. Related style rule: [[docs-no-untaken-paths]].
21 changes: 21 additions & 0 deletions .agents/memory/docs-no-untaken-paths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
name: docs-no-untaken-paths
description: Docstrings and doctests describe what the code does, never the designs it avoided
metadata:
type: feedback
---

When writing docstrings and doctests for music21, do not spend words (or
doctest lines) explaining what the code *doesn't* do or contrasting with
rejected alternatives — e.g. cut "not literally 'mod 7', which would make it
0" from a description that already states the value is always 1-7. Myke: "we
don't spend doctest time reinforcing paths we didn't take."

**Why:** every sentence in a docstring is maintained forever and read by users
who never saw the alternative; contrast-with-the-wrong-design is
reviewer-facing noise, like comments justifying a change.

**How to apply:** state the positive contract with examples of real values. If
a name is misleading (like `GenericInterval.mod7`, which actually returns
simple-interval values 1-7), document the actual behavior — don't argue with
the name in prose. Related style rule: [[docs-audience-separation]].
40 changes: 40 additions & 0 deletions .agents/memory/issue-1349-romanNumeral-direction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: issue-1349-romanNumeral-direction
description: Status and direction for RomanNumeral.romanNumeral vs romanNumeralFromChord (GitHub issues #1349 and #1249)
metadata:
type: project
---

As of 2026-07-06 (branch `fix-1349-raised-67`): the core raised-^6/^7 bug in
GitHub issue #1349 is FIXED — `correctRNAlterationForMinor` gained a
keyword-only `chordHasMajorThird` argument so major-quality chords on raised
^6/^7 in minor keep their sharp (figure `#VI`, `.romanNumeral` `'#VI'`), and
the tsvConverter `localKeyAsRn` workaround was removed. (Naming settled after
two rounds: name the parameter for the chord-level fact it carries, not for
its consequence like "uppercaseNumeral" — the numeral doesn't exist yet when
the function runs.) Myke decided NOT to
flip the `romanNumeralFromChord` default from CAUTIONARY to QUALITY (the 2022
idea in the issue) for now. Still open, to discuss with contributor pablopupo
and Malcolm Sailor on the issue: (2) adding `sixthMinor`/`seventhMinor`
parameters to `romanNumeralFromChord` and possibly flipping its default, and
(4) issue #1249 (secondary-numeral `#vii` prefixing).

**Why:** `.romanNumeral` is the *semantic* root-degree token (alteration
relative to the key's natural scale, read from `frontAlterationAccidental`),
while `.figure` is notational. `harmonicFunction.romanToFunction` and the
tsvConverter DCML export depend on the semantic reading, so the property
should never be deprecated. Known remaining wart: seventh chords on raised
^6/^7 in minor still don't round-trip their figures (e.g. `#VIb753` reparses
with G-flat) — the CAUTIONARY generation convention computes inversion figures
against an "altered key" while parsing measures against the original scale,
and the mismatch differs per degree.

**How to apply:** when returning to items 2+4, the minor-^6/^7 accidental
convention lives in three places that must stay in sync (see the maintenance
comment in `correctRNAlterationForMinor`). The same session renamed
`FigureTuple.aboveBass` to `degFromRefPitch` and `ChordFigureTuple` to
`PitchFigureTuple`, and replaced `figureTupleSolo` with the classmethod
constructor `FigureTuple.fromPitchAndReference(pitchObj, keyObj, refPitch)`
(old name kept as a deprecated v11→v12 alias). Myke is not all-in on
classmethod constructors in general, but preferred one here over a
module-level function whose name read as the verb "figure".
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ charset = utf-8
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
max_line_length = 100
ij_visual_guides = 80,100
2 changes: 1 addition & 1 deletion music21/humdrum/spineParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def __init__(self, dataStream: str|list[str]) -> None:
self.protoSpines: list[ProtoSpine] = []
self.eventCollections: list[EventCollection] = []
self.spineCollection: SpineCollection|None = None
# populated by insertGlobalEvents(), consumed by parseMetadata()
# populated by insertGlobalEvents(), used by parseMetadata()
self.globalReferences: list[GlobalReference] = []

if isinstance(dataStream, str):
Expand Down
Loading
Loading