Skip to content

Naming Conventions

tonal_py exposes the same surface as tonal.js but follows Python naming rules. This page is the literal mapping for porting JS code.

Function names: snake_case

Every function name converts from camelCase to snake_case.

tonal.js tonal_py
Note.fromMidi(60) Note.from_midi(60)
Note.transposeBy("5P") Note.transpose_by("5P")
Note.transposeFifths("C", 2) Note.transpose_fifths("C", 2)
Note.sortedUniqNames(...) Note.sorted_uniq_names(...)
Pcset.isSubsetOf(...) Pcset.is_subset_of(...)
Chord.chordScales("Cmaj7") Chord.chord_scales("Cmaj7")
Scale.modeNames("C major") Scale.mode_names("C major")
Scale.scaleChords(...) Scale.scale_chords(...)
Key.majorKey("C") Key.major_key("C")
Key.minorKeyChords("A") Key.minor_key_chords("A")
RomanNumeral.romanNumeral(...) RomanNumeral.roman_numeral(...)
Mode.seventhChords("ionian", "C") Mode.seventh_chords("ionian", "C")
Mode.relativeTonic("dorian", "ionian", "C") Mode.relative_tonic("dorian", "ionian", "C")
Midi.midiToNoteName(60) Midi.midi_to_note_name(60)
Midi.freqToMidi(440) Midi.freq_to_midi(440)
Midi.pcsetSteps(...) Midi.pcset_steps(...)
Midi.pcsetDegrees(...) Midi.pcset_degrees(...)
AbcNotation.abcToScientificNotation("c") AbcNotation.abc_to_scientific_notation("c")
RhythmPattern.euclid(8, 3) RhythmPattern.euclid(8, 3) (no change)
Progression.fromRomanNumerals(...) Progression.from_roman_numerals(...)
Progression.toRomanNumerals(...) Progression.to_roman_numerals(...)
VoiceLeading.topNoteDiff(...) VoiceLeading.top_note_diff(...)

The short JS aliases (tr, trBy, trFrom, trFifths) keep their short form in Python too — Note.tr, Note.tr_by, etc. — for ergonomic parity.

Field names: snake_case

Same conversion applies to dataclass fields:

tonal.js field tonal_py field
setNum set_num
rootDegree root_degree
keySignature key_signature
chordType chord_type
modeNum mode_num
minorRelative minor_relative
relativeMajor relative_major
chordsHarmonicFunction chords_harmonic_function
chordScales chord_scales
secondaryDominants secondary_dominants
secondaryDominantSupertonics secondary_dominant_supertonics
substituteDominants substitute_dominants
substituteDominantSupertonics substitute_dominant_supertonics

Namespaces: PascalCase (unchanged)

The 23 top-level namespaces match the JS export shape:

from tonal_py import (
    Note, Interval, Chord, ChordType, Scale, ScaleType, Key, Mode,
    RomanNumeral, Pcset, Midi, Voicing, VoicingDictionary, VoiceLeading,
    RhythmPattern, TimeSignature, DurationValue, AbcNotation, Range,
    Progression, Collection, Core, Array,
)

Plus the deprecated aliases Tonal, PcSet, ChordDictionary, ScaleDictionary.

Constants: UPPER_SNAKE_CASE

The few public constants follow Python conventions:

tonal.js tonal_py
BITMASK (in chord-detect) BITMASK (same)
MODES table MODES
CHORDS table CHORDS
SCALES table SCALES
IVLS array IVLS
NAMES (roman numerals) NAMES
NAMES_MINOR NAMES_MINOR

Empty/sentinel objects

JS uses object freezes named NoNote, NoChord, etc. We use snake_case constants:

tonal.js tonal_py
NoNote NO_NOTE
NoInterval NO_INTERVAL
EmptyPcset EMPTY_PCSET
NoChord NO_CHORD
NoChordType NO_CHORD_TYPE
NoScale NO_SCALE
NoScaleType NO_SCALE_TYPE
NoMode NO_MODE
NoRomanNumeral NO_ROMAN_NUMERAL
NoMajorKey NO_MAJOR_KEY
NoMinorKey NO_MINOR_KEY
NoTimeSignature (NONE) NO_TIME_SIGNATURE
NoDuration NO_DURATION

All of these are importable from tonal_py (top-level) or tonal_py.core / tonal_py._types.

What does NOT change

  • Strings (note names, interval names, chord names, scale names) — exact string parity. "Cmaj7", "Bb dorian", "5P", "#IV" all work.
  • Algorithm semantics — including a few preserved tonal.js bugs (see the relevant module docstrings).
  • Output values — every primitive output (chroma strings, set numbers, intervals, transposition results) matches JS exactly. Verified by the oracle test fixture.