Fix 'pytheory play' chord name parsing for names containing digits

Chord names like Cmaj7 and G7 were incorrectly treated as tone names
because they contain digits. Now tries chord name lookup first. v0.5.1.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-22 14:53:12 -04:00
parent e9c630705e
commit 6aad427fb8
2 changed files with 17 additions and 8 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "pytheory"
version = "0.5.0"
version = "0.5.1"
description = "Music Theory for Humans"
readme = "README.md"
license = "MIT"
+16 -7
View File
@@ -100,14 +100,23 @@ def cmd_play(args):
synth = synth_map[args.synth]
duration = args.duration
# Parse notes — if single note, play as tone; otherwise as chord.
tones = [Tone.from_string(n if any(c.isdigit() for c in n) else f"{n}4",
system="western") for n in args.notes]
if len(tones) == 1:
target = tones[0]
label = target.full_name
# Try chord name first (e.g. "Am", "Cmaj7"), then fall back to individual notes.
if len(args.notes) == 1:
note = args.notes[0]
# Try as chord name first (Am, G7, Cmaj7, etc.)
try:
target = Chord.from_name(note)
name = target.identify() or note
label = f"{name} ({' '.join(t.full_name for t in target.tones)})"
except (ValueError, KeyError):
# Fall back to single tone
target = Tone.from_string(
note if any(c.isdigit() for c in note) else f"{note}4",
system="western")
label = target.full_name
else:
tones = [Tone.from_string(n if any(c.isdigit() for c in n) else f"{n}4",
system="western") for n in args.notes]
target = Chord(tones=tones)
name = target.identify() or "Custom"
label = f"{name} ({' '.join(t.full_name for t in tones)})"