From ab20990e72349ed89a47c35e834657a08336f73a Mon Sep 17 00:00:00 2001 From: Rachel Bittner Date: Thu, 2 Apr 2020 23:40:25 +0200 Subject: [PATCH 1/4] add a base Track class, remove all reprs --- mirdata/beatles.py | 12 +--------- mirdata/dali.py | 24 +------------------- mirdata/gtzan_genre.py | 7 +----- mirdata/guitarset.py | 16 +------------- mirdata/ikala.py | 13 +---------- mirdata/medley_solos_db.py | 11 +--------- mirdata/medleydb_melody.py | 22 +------------------ mirdata/medleydb_pitch.py | 17 +-------------- mirdata/orchset.py | 28 +----------------------- mirdata/rwc_classical.py | 23 +------------------- mirdata/rwc_jazz.py | 24 +------------------- mirdata/rwc_popular.py | 28 +----------------------- mirdata/salami.py | 28 +----------------------- mirdata/tinysol.py | 18 +-------------- mirdata/utils.py | 35 ++++++++++++++++++++++++++++++ tests/test_beatles.py | 12 ---------- tests/test_dali.py | 9 -------- tests/test_gtzan_genre.py | 5 ----- tests/test_ikala.py | 10 --------- tests/test_loaders.py | 7 ++++++ tests/test_medley_solos_db.py | 8 ------- tests/test_medleydb_melody.py | 11 ---------- tests/test_medleydb_pitch.py | 9 -------- tests/test_orchset.py | 13 ----------- tests/test_rwc_classical.py | 11 ---------- tests/test_rwc_jazz.py | 13 ----------- tests/test_rwc_popular.py | 13 ----------- tests/test_salami.py | 14 ------------ tests/test_tinysol.py | 6 ----- tests/test_utils.py | 41 +++++++++++++++++++++++++++++++++++ 30 files changed, 97 insertions(+), 391 deletions(-) diff --git a/mirdata/beatles.py b/mirdata/beatles.py index 12a90b9f9..0445782bc 100644 --- a/mirdata/beatles.py +++ b/mirdata/beatles.py @@ -26,7 +26,7 @@ DATA = utils.LargeData('beatles_index.json') -class Track(object): +class Track(utils.Track): """Beatles track class Args: @@ -70,16 +70,6 @@ def __init__(self, track_id, data_home=None): self.title = os.path.basename(self._track_paths['sections'][0]).split('.')[0] - def __repr__(self): - repr_string = ( - "Beatles Track(track_id={}, audio_path={}, title={}, " - + "beats=BeatData('beat_times, 'beat_positions'), " - + "chords=ChordData('intervals', 'labels'), " - + "key=KeyData('start_times', 'end_times', 'keys'), " - + "sections=SectionData('intervals', 'labels'))" - ) - return repr_string.format(self.track_id, self.audio_path, self.title) - @utils.cached_property def beats(self): """BeatData: human-labeled beat annotation""" diff --git a/mirdata/dali.py b/mirdata/dali.py index 64fcdc532..4481c8814 100644 --- a/mirdata/dali.py +++ b/mirdata/dali.py @@ -55,7 +55,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('dali_index.json', _load_metadata) -class Track(object): +class Track(utils.Track): """DALI melody Track class Args: @@ -133,28 +133,6 @@ def __init__(self, track_id, data_home=None): self.language = None self.audio_path = None - def __repr__(self): - repr_string = ( - "DALI Track(track_id={}, audio_path={}, " - + "audio_url={}, audio_working={}, ground_truth={}, artist={}, title={}," - + "dataset_version={}, scores_ncc={}, scores_manual={}, album={}, release_date={}, language={})" - ) - return repr_string.format( - self.track_id, - self.audio_path, - self.audio_url, - self.url_working, - self.ground_truth, - self.artist, - self.title, - self.dataset_version, - round(self.scores_ncc, 4), - self.scores_manual, - self.album, - self.release_date, - self.language, - ) - @utils.cached_property def notes(self): """NoteData: note-aligned lyrics""" diff --git a/mirdata/gtzan_genre.py b/mirdata/gtzan_genre.py index afbfef97c..59f137a94 100644 --- a/mirdata/gtzan_genre.py +++ b/mirdata/gtzan_genre.py @@ -34,7 +34,7 @@ DATA = utils.LargeData("gtzan_genre_index.json") -class Track(object): +class Track(utils.Track): """gtzan_genre Track class Args: @@ -71,11 +71,6 @@ def audio(self): """(np.ndarray, float): audio signal, sample rate""" return load_audio(self.audio_path, sample_rate=22050) - def __repr__(self): - return "GTZAN-Genre Track(track_id='{track_id}', genre='{genre}')".format( - track_id=self.track_id, genre=self.genre - ) - def to_jams(self): """(Not Implemented) Jams: the track's data in jams format""" raise NotImplementedError diff --git a/mirdata/guitarset.py b/mirdata/guitarset.py index 48239c406..438e7e0c6 100644 --- a/mirdata/guitarset.py +++ b/mirdata/guitarset.py @@ -99,7 +99,7 @@ DATA = utils.LargeData('guitarset_index.json') -class Track(object): +class Track(utils.Track): """guitarset Track class Args: @@ -157,20 +157,6 @@ def __init__(self, track_id, data_home=None): self.tempo = float(tempo) self.style = _STYLE_DICT[style[:-1]] - def __repr__(self): - repr_string = ( - 'GuitarSet Track(' - + 'track_id={}, jams_path={},\n'.format(self.track_id, self.jams_path) - + 'tempo={}, mode={}, style={},\n'.format(self.tempo, self.mode, self.style) - + "beats=BeatData('beat_times', 'beat_positions'),\n" - + "leadsheet_chords=ChordData('start_times', 'end_times', 'chords'),\n" - + "inferred_chords=ChordData('start_times', 'end_times', 'chords'),\n" - + "key_mode=KeyData('start_times', 'end_times', 'keys'),\n" - + "pitch_contours=dict(F0Data('times', 'frequencies', 'confidence')),\n" - + "notes=dict(NoteData('intervals', 'notes', 'confidence')))" - ) - return repr_string - @utils.cached_property def beats(self): """BeatData: the track's beat positions""" diff --git a/mirdata/ikala.py b/mirdata/ikala.py index 41f763814..9d410a07b 100644 --- a/mirdata/ikala.py +++ b/mirdata/ikala.py @@ -63,7 +63,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('ikala_index.json', _load_metadata) -class Track(object): +class Track(utils.Track): """ikala Track class Args: @@ -107,17 +107,6 @@ def __init__(self, track_id, data_home=None): else: self.singer_id = None - def __repr__(self): - repr_string = ( - "iKala Track(track_id={}, audio_path={}, song_id={}, " - + "section={}, singer_id={}, " - + "f0=F0Data('times', 'frequencies', 'confidence'), " - + "lyrics=LyricData('start_times', 'end_times', 'lyrics', 'pronunciations'))" - ) - return repr_string.format( - self.track_id, self.audio_path, self.song_id, self.section, self.singer_id - ) - @utils.cached_property def f0(self): """F0Data: The human-annotated singing voice pitch""" diff --git a/mirdata/medley_solos_db.py b/mirdata/medley_solos_db.py index 826e8fa07..499da7333 100644 --- a/mirdata/medley_solos_db.py +++ b/mirdata/medley_solos_db.py @@ -80,7 +80,7 @@ def _load_metadata(data_home): DATA = utils.LargeData("medley_solos_db_index.json", _load_metadata) -class Track(object): +class Track(utils.Track): """medley_solos_db Track class Args: @@ -130,15 +130,6 @@ def __init__(self, track_id, data_home=None): self.song_id = self._track_metadata["song_id"] self.subset = self._track_metadata["subset"] - def __repr__(self): - repr_string = ( - "Medley-solos-DB Track(track_id={}, audio_path={}, " - + "instrument={}, song_id={}, subset={})" - ) - return repr_string.format( - self.track_id, self.audio_path, self.instrument, self.song_id, self.subset - ) - @property def audio(self): """(np.ndarray, float): audio signal, sample rate""" diff --git a/mirdata/medleydb_melody.py b/mirdata/medleydb_melody.py index f5dc6b3a1..9ee66ae77 100644 --- a/mirdata/medleydb_melody.py +++ b/mirdata/medleydb_melody.py @@ -45,7 +45,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('medleydb_melody_index.json', _load_metadata) -class Track(object): +class Track(utils.Track): """medleydb_melody Track class Args: @@ -112,26 +112,6 @@ def __init__(self, track_id, data_home=None): self.is_instrumental = self._track_metadata['is_instrumental'] self.n_sources = self._track_metadata['n_sources'] - def __repr__(self): - repr_string = ( - "MedleyDb-Melody Track(track_id={}, audio_path={}, " - + "artist={}, title={}, genre={}, is_excerpt={}, " - + "is_instrumental={}, n_sources={}, " - + "melody1=F0Data('times', 'frequencies', confidence'), " - + "melody2=F0Data('times', 'frequencies', confidence'), " - + "melody3=MultipitchData('times', 'frequencies', confidence'))" - ) - return repr_string.format( - self.track_id, - self.audio_path, - self.artist, - self.title, - self.genre, - self.is_excerpt, - self.is_instrumental, - self.n_sources, - ) - @utils.cached_property def melody1(self): """F0Data: The pitch of the single most predominant source (often the voice)""" diff --git a/mirdata/medleydb_pitch.py b/mirdata/medleydb_pitch.py index ecea7a5ea..5ce23ec7d 100644 --- a/mirdata/medleydb_pitch.py +++ b/mirdata/medleydb_pitch.py @@ -45,7 +45,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('medleydb_pitch_index.json', _load_metadata) -class Track(object): +class Track(utils.Track): """medleydb_pitch Track class Args: @@ -96,21 +96,6 @@ def __init__(self, track_id, data_home=None): self.title = self._track_metadata['title'] self.genre = self._track_metadata['genre'] - def __repr__(self): - repr_string = ( - "MedleyDb-Pitch Track(track_id={}, audio_path={}, " - + "artist={}, title={}, genre={}, instrument={}, " - + "pitch=PitchData('times', 'pitches', 'confidence'))" - ) - return repr_string.format( - self.track_id, - self.audio_path, - self.artist, - self.title, - self.genre, - self.instrument, - ) - @utils.cached_property def pitch(self): """F0Data: The human-annotated pitch""" diff --git a/mirdata/orchset.py b/mirdata/orchset.py index 3e7cc827e..64f0bd924 100644 --- a/mirdata/orchset.py +++ b/mirdata/orchset.py @@ -98,7 +98,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('orchset_index.json', _load_metadata) -class Track(object): +class Track(utils.Track): """orchset Track class Args: @@ -177,32 +177,6 @@ def __init__(self, track_id, data_home=None): self.only_winds = self._track_metadata['only_winds'] self.only_brass = self._track_metadata['only_brass'] - def __repr__(self): - repr_string = ( - "Orchset Track(track_id={}, audio_path_stereo={}, " - + "audio_path_mono={}, composer={}, work={}, excerpt={}, " - + "predominant_melodic_instruments={}, alternating_melody={}, " - + "contains_winds={}, contains_strings={}, contains_brass={}, " - + "only_strings={}, only_winds={}, only_brass={}, " - + "melody=F0Data('times', 'frequencies', 'confidence'))" - ) - return repr_string.format( - self.track_id, - self.audio_path_stereo, - self.audio_path_mono, - self.composer, - self.work, - self.excerpt, - self.predominant_melodic_instruments, - self.alternating_melody, - self.contains_winds, - self.contains_strings, - self.contains_brass, - self.only_strings, - self.only_winds, - self.only_brass, - ) - @utils.cached_property def melody(self): """F0Data: melody annotation""" diff --git a/mirdata/rwc_classical.py b/mirdata/rwc_classical.py index bb80c0782..2ed02e576 100644 --- a/mirdata/rwc_classical.py +++ b/mirdata/rwc_classical.py @@ -88,7 +88,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('rwc_classical_index.json', _load_metadata) -class Track(object): +class Track(utils.Track): """rwc_classical Track class Args: @@ -157,27 +157,6 @@ def __init__(self, track_id, data_home=None): self.duration = self._track_metadata['duration'] self.category = self._track_metadata['category'] - def __repr__(self): - repr_string = ( - "RWC-Classical Track(track_id={}, audio_path={}, " - + "piece_number={}, suffix={}, track_number={}, title={}, composer={}, " - + "artist={}, duration={}, category={}" - + "sections=SectionData('intervals', 'labels'), " - + "beats=BeatData('beat_times', 'beat_positions'))" - ) - return repr_string.format( - self.track_id, - self.audio_path, - self.piece_number, - self.suffix, - self.track_number, - self.title, - self.composer, - self.artist, - self.duration, - self.category, - ) - @utils.cached_property def sections(self): """SectionData: human labeled section annotations""" diff --git a/mirdata/rwc_jazz.py b/mirdata/rwc_jazz.py index 1efd0edfb..b2549a635 100644 --- a/mirdata/rwc_jazz.py +++ b/mirdata/rwc_jazz.py @@ -32,7 +32,6 @@ For more details, please visit: https://staff.aist.go.jp/m.goto/RWC-MDB/rwc-mdb-j.html """ import csv -import librosa import logging import os @@ -115,7 +114,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('rwc_jazz_index.json', _load_metadata) -class Track(object): +class Track(utils.Track): """rwc_jazz Track class Args: @@ -181,27 +180,6 @@ def __init__(self, track_id, data_home=None): self.variation = self._track_metadata['variation'] self.instruments = self._track_metadata['instruments'] - def __repr__(self): - repr_string = ( - "RWC-Jazz Track(track_id={}, audio_path={}, " - + "piece_number={}, suffix={}, track_number={}, title={}, " - + "artist={}, duration={}, variation={}, instruments={}, " - + "sections=SectionData('intervals', 'labels'), " - + "beats=BeatData('beat_times', 'beat_positions'))" - ) - return repr_string.format( - self.track_id, - self.audio_path, - self.piece_number, - self.suffix, - self.track_number, - self.title, - self.artist, - self.duration, - self.variation, - self.instruments, - ) - @utils.cached_property def sections(self): """SectionData: human-labeled section data""" diff --git a/mirdata/rwc_popular.py b/mirdata/rwc_popular.py index 7c10c37d3..4592b6aa5 100644 --- a/mirdata/rwc_popular.py +++ b/mirdata/rwc_popular.py @@ -107,7 +107,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('rwc_popular_index.json', _load_metadata) -class Track(object): +class Track(utils.Track): """rwc_popular Track class Args: @@ -189,32 +189,6 @@ def __init__(self, track_id, data_home=None): self.instruments = self._track_metadata['instruments'] self.drum_information = self._track_metadata['drum_information'] - def __repr__(self): - repr_string = ( - "RWC-Popular Track(track_id={}, audio_path={}, " - + "piece_number={}, suffix={}, track_number={}, title={}, " - + "artist={}, singer_information={}, duration={}, " - + "tempo={}, instruments={}, drum_information={}, " - + "sections=SectionData('intervals', 'labels'), " - + "beats=BeatData('beat_times', 'beat_positions'))" - + "chords=ChordData('intervals', 'labels'), " - + "vocal_instrument_activity=EventData('start_times', 'end_times', 'event')" - ) - return repr_string.format( - self.track_id, - self.audio_path, - self.piece_number, - self.suffix, - self.track_number, - self.title, - self.artist, - self.singer_information, - self.duration, - self.tempo, - self.instruments, - self.drum_information, - ) - @utils.cached_property def sections(self): """SectionData: human-labeled section annotation""" diff --git a/mirdata/salami.py b/mirdata/salami.py index b326b8d85..587bd2bd1 100644 --- a/mirdata/salami.py +++ b/mirdata/salami.py @@ -78,7 +78,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('salami_index.json', _load_metadata) -class Track(object): +class Track(utils.Track): """salami Track class Args: @@ -158,32 +158,6 @@ def __init__(self, track_id, data_home=None): self.broad_genre = self._track_metadata['class'] self.genre = self._track_metadata['genre'] - def __repr__(self): - repr_string = ( - "Salami Track(track_id={}, audio_path={}, source={}, " - + "title={}, artist={}, duration={}, annotator_1_id={}, " - + "annotator_2_id={}, annotator_1_time={}, annotator_2_time={}, " - + "broad_genre={}, genre={}, " - + "sections_annotator_1_uppercase=SectionData('intervals', 'labels'), " - + "sections_annotator_1_lowercase=SectionData('intervals', 'labels'), " - + "sections_annotator_2_uppercase=SectionData('intervals', 'labels'), " - + "sections_annotator_2_lowercase=SectionData('intervals', 'labels'))" - ) - return repr_string.format( - self.track_id, - self.audio_path, - self.source, - self.title, - self.artist, - self.duration, - self.annotator_1_id, - self.annotator_2_id, - self.annotator_1_time, - self.annotator_2_time, - self.broad_genre, - self.genre, - ) - @utils.cached_property def sections_annotator_1_uppercase(self): """SectionData: annotations in hierarchy level 0 from annotator 1""" diff --git a/mirdata/tinysol.py b/mirdata/tinysol.py index 184ce9632..a0de5b31c 100644 --- a/mirdata/tinysol.py +++ b/mirdata/tinysol.py @@ -108,7 +108,7 @@ def _load_metadata(data_home): DATA = utils.LargeData("tinysol_index.json", _load_metadata) -class Track(object): +class Track(utils.Track): """tinysol Track class Args: @@ -186,22 +186,6 @@ def __init__(self, track_id, data_home=None): self.string_id = None self.is_resampled = self._track_metadata["Resampled"] - def __repr__(self): - if self.string_id: - repr_string = ( - "TinySOL Track(instrument={}, pitch={}, dynamics={}, string={})" - ).format( - self.instrument_full, - self.pitch, - self.dynamics, - STRING_ROMAN_NUMERALS[self.string_id], - ) - else: - repr_string = ( - "TinySOL Track(instrument={}, pitch={}, dynamics={})" - ).format(self.instrument_full, self.pitch, self.dynamics) - return repr_string - @property def audio(self): """(np.ndarray, float): audio signal, sample rate""" diff --git a/mirdata/utils.py b/mirdata/utils.py index e34391f20..359a4a3ef 100644 --- a/mirdata/utils.py +++ b/mirdata/utils.py @@ -29,11 +29,46 @@ import hashlib import os import json +import types MIR_DATASETS_DIR = os.path.join(os.getenv('HOME', '/tmp'), 'mir_datasets') +class Track(object): + def __repr__(self): + properties = [v for v in dir(self.__class__) if not v.startswith('_')] + attributes = [ + v for v in dir(self) if not v.startswith('_') and + v not in properties + ] + + repr_str = "Track(\n" + + for attr in attributes: + val = getattr(self, attr) + if isinstance(val, str): + val = '"{}"'.format(val) + repr_str += " {}={},\n".format(attr, val) + + for prop in properties: + val = getattr(self.__class__, prop) + if isinstance(val, types.FunctionType): + continue + + if val.__doc__ is None: + raise ValueError("{} has no documentation".format(prop)) + + val_type_str = val.__doc__.split(':')[0] + repr_str += " {}: {},\n".format(prop, val_type_str) + + repr_str += ")" + return repr_str + + def to_jams(self): + raise NotImplementedError + + def md5(file_path): """Get md5 hash of a file. diff --git a/tests/test_beatles.py b/tests/test_beatles.py index ff2975056..fdcc23f54 100644 --- a/tests/test_beatles.py +++ b/tests/test_beatles.py @@ -40,18 +40,6 @@ def test_track(): assert sr == 44100 assert audio.shape == (44100 * 2,) - repr_string = ( - "Beatles Track(track_id=0111, " - + "audio_path=tests/resources/mir_datasets/Beatles/audio/" - + "01_-_Please_Please_Me/11_-_Do_You_Want_To_Know_A_Secret.wav, " - + "title=11_-_Do_You_Want_To_Know_A_Secret, " - + "beats=BeatData('beat_times, 'beat_positions'), " - + "chords=ChordData('intervals', 'labels'), " - + "key=KeyData('start_times', 'end_times', 'keys'), " - + "sections=SectionData('intervals', 'labels'))" - ) - assert track.__repr__() == repr_string - track = beatles.Track('10212') assert track.beats is None assert track.key is None diff --git a/tests/test_dali.py b/tests/test_dali.py index 6984d9f0c..811efd0f5 100644 --- a/tests/test_dali.py +++ b/tests/test_dali.py @@ -50,15 +50,6 @@ def test_track(): assert sr == 48000 assert audio.shape == (94208,) - repr_string = ( - "DALI Track(track_id=4b196e6c99574dd49ad00d56e132712b, " - + "audio_path=tests/resources/mir_datasets/DALI/audio/4b196e6c99574dd49ad00d56e132712b.mp3, " - + "audio_url=zUzd9KyIDrM, audio_working=True, ground_truth=False, artist=System Of A Down, " - + "title=B.Y.O.B.,dataset_version=1, scores_ncc=0.9645, scores_manual=0, " - + "album=Mezmerize, release_date=2005, language=english)" - ) - assert track.__repr__() == repr_string - def test_load_notes(): notes_path = ( diff --git a/tests/test_gtzan_genre.py b/tests/test_gtzan_genre.py index 052c40b17..dc5be63ad 100644 --- a/tests/test_gtzan_genre.py +++ b/tests/test_gtzan_genre.py @@ -34,8 +34,3 @@ def test_track(): audio, sr = track.audio assert sr == 22050 assert audio.shape == (663300,) - - -def test_repr(): - track = gtzan_genre.Track("country.00000", data_home=TEST_DATA_HOME) - assert str(track) == "GTZAN-Genre Track(track_id='country.00000', genre='country')" diff --git a/tests/test_ikala.py b/tests/test_ikala.py index 9e711cc1f..c2e499940 100644 --- a/tests/test_ikala.py +++ b/tests/test_ikala.py @@ -54,16 +54,6 @@ def test_track(): assert mix.shape == (44100 * 2,) assert np.array_equal(mix, instrumental + vocal) - repr_string = ( - "iKala Track(track_id=10161_chorus, " - + "audio_path=tests/resources/mir_datasets/iKala/Wavfile/" - + "10161_chorus.wav, song_id=10161, section=chorus, singer_id=1, " - + "f0=F0Data('times', 'frequencies', 'confidence'), " - + "lyrics=LyricData('start_times', 'end_times', 'lyrics', " - + "'pronunciations'))" - ) - assert track.__repr__() == repr_string - def test_to_jams(): diff --git a/tests/test_loaders.py b/tests/test_loaders.py index 9bc32db81..8e5cd9df5 100644 --- a/tests/test_loaders.py +++ b/tests/test_loaders.py @@ -9,6 +9,7 @@ import pytest import mirdata +import mirdata.utils as utils from tests.test_utils import DEFAULT_DATA_HOME DATASETS = [importlib.import_module("mirdata.{}".format(d)) for d in mirdata.__all__] @@ -64,8 +65,14 @@ def test_track(): track_default = dataset.Track(trackid) assert track_default._data_home == os.path.join( DEFAULT_DATA_HOME, dataset.DATASET_DIR) + + assert isinstance(track_default, utils.Track) + assert hasattr(track_default, 'to_jams') + # will fail if something goes wrong with __repr__ + print(track_default) + with pytest.raises(ValueError): dataset.Track('~faketrackid~?!') diff --git a/tests/test_medley_solos_db.py b/tests/test_medley_solos_db.py index 339dbf57e..f3061339f 100644 --- a/tests/test_medley_solos_db.py +++ b/tests/test_medley_solos_db.py @@ -28,14 +28,6 @@ def test_track(): assert y.shape == (65536,) assert sr == 22050 - repr_string = ( - 'Medley-solos-DB Track(track_id=d07b1fc0-567d-52c2-fef4-239f31c9d40e, ' - + 'audio_path=tests/resources/mir_datasets/Medley-solos-DB/audio/' - + 'Medley-solos-DB_validation-3_d07b1fc0-567d-52c2-fef4-239f31c9d40e.wav, ' - + 'instrument=flute, song_id=210, subset=validation)' - ) - assert track.__repr__() == repr_string - def test_to_jams(): diff --git a/tests/test_medleydb_melody.py b/tests/test_medleydb_melody.py index d13745f35..853f99cab 100644 --- a/tests/test_medleydb_melody.py +++ b/tests/test_medleydb_melody.py @@ -42,17 +42,6 @@ def test_track(): assert sr == 44100 assert y.shape == (44100 * 2,) - repr_string = ( - "MedleyDb-Melody Track(track_id=MusicDelta_Beethoven, " - + "audio_path=tests/resources/mir_datasets/MedleyDB-Melody/audio/" - + "MusicDelta_Beethoven_MIX.wav, artist=MusicDelta, title=Beethoven," - + " genre=Classical, is_excerpt=True, is_instrumental=True, " - + "n_sources=18, melody1=F0Data('times', 'frequencies', confidence')," - + " melody2=F0Data('times', 'frequencies', confidence'), " - + "melody3=MultipitchData('times', 'frequencies', confidence'))" - ) - assert track.__repr__() == repr_string - def test_to_jams(): diff --git a/tests/test_medleydb_pitch.py b/tests/test_medleydb_pitch.py index d2b531d0e..dd1096dd5 100644 --- a/tests/test_medleydb_pitch.py +++ b/tests/test_medleydb_pitch.py @@ -34,15 +34,6 @@ def test_track(): assert sr == 44100 assert y.shape == (44100 * 2,) - repr_string = ( - "MedleyDb-Pitch Track(track_id=AClassicEducation_NightOwl_STEM_08, " - + "audio_path=tests/resources/mir_datasets/MedleyDB-Pitch/audio/" - + "AClassicEducation_NightOwl_STEM_08.wav, " - + "artist=AClassicEducation, title=NightOwl, genre=Singer/Songwriter, " - + "instrument=male singer, pitch=PitchData('times', 'pitches', 'confidence'))" - ) - assert track.__repr__() == repr_string - def test_to_jams(): diff --git a/tests/test_orchset.py b/tests/test_orchset.py index 70aa5752d..c92a5a518 100644 --- a/tests/test_orchset.py +++ b/tests/test_orchset.py @@ -47,19 +47,6 @@ def test_track(): assert sr_stereo == 44100 assert y_stereo.shape == (2, 44100 * 2) - repr_string = ( - "Orchset Track(track_id=Beethoven-S3-I-ex1, " - + "audio_path_stereo=tests/resources/mir_datasets/Orchset/audio/" - + "stereo/Beethoven-S3-I-ex1.wav, " - + "audio_path_mono=tests/resources/mir_datasets/Orchset/audio/" - + "mono/Beethoven-S3-I-ex1.wav, composer=Beethoven, work=S3-I, " - + "excerpt=1, predominant_melodic_instruments=['strings', 'winds'], " - + "alternating_melody=True, contains_winds=True, contains_strings=True, " - + "contains_brass=False, only_strings=False, only_winds=False, " - + "only_brass=False, melody=F0Data('times', 'frequencies', 'confidence'))" - ) - assert track.__repr__() == repr_string - def test_to_jams(): diff --git a/tests/test_rwc_classical.py b/tests/test_rwc_classical.py index 1ccec116c..7b8ee010c 100644 --- a/tests/test_rwc_classical.py +++ b/tests/test_rwc_classical.py @@ -42,17 +42,6 @@ def test_track(): assert sr == 44100 assert y.shape == (44100 * 2,) - repr_string = ( - "RWC-Classical Track(track_id=RM-C003, " - + "audio_path=tests/resources/mir_datasets/RWC-Classical/audio/rwc-c-m01/3.wav, " - + "piece_number=No. 3, suffix=M01, track_number=Tr. 03, " - + "title=Symphony no.5 in C minor, op.67. 1st mvmt., composer=Beethoven, Ludwig van, " - + "artist=Tokyo City Philharmonic Orchestra, duration=435.0, category=Symphony" - + "sections=SectionData('intervals', 'labels'), " - + "beats=BeatData('beat_times', 'beat_positions'))" - ) - assert track.__repr__() == repr_string - def test_to_jams(): diff --git a/tests/test_rwc_jazz.py b/tests/test_rwc_jazz.py index 6569e1db2..2ddf3b1c6 100644 --- a/tests/test_rwc_jazz.py +++ b/tests/test_rwc_jazz.py @@ -41,19 +41,6 @@ def test_track(): assert sr == 44100 assert y.shape == (44100 * 2,) - repr_string = ( - "RWC-Jazz Track(track_id=RM-J004, " - + "audio_path=tests/resources/mir_datasets/RWC-Jazz/audio/rwc-j-m01/4.wav, " - + "piece_number=No. 4, suffix=M01, track_number=Tr. 04, " - + "title=Crescent Serenade (Piano Solo), artist=Makoto Nakamura, " - + "duration=167.0, variation=Instrumentation 1, instruments=Pf, " - + "sections=SectionData('intervals', 'labels'), " - + "beats=BeatData('beat_times', 'beat_positions'))" - ) - assert track.__repr__() == repr_string - - print(track.to_jams()) - def test_to_jams(): diff --git a/tests/test_rwc_popular.py b/tests/test_rwc_popular.py index f4dd463a1..e201f7ecf 100644 --- a/tests/test_rwc_popular.py +++ b/tests/test_rwc_popular.py @@ -51,19 +51,6 @@ def test_track(): assert sr == 44100 assert y.shape == (44100 * 2,) - repr_string = ( - "RWC-Popular Track(track_id=RM-P001, " - + "audio_path=tests/resources/mir_datasets/RWC-Popular/audio/rwc-p-m01/1.wav, " - + "piece_number=No. 1, suffix=M01, track_number=Tr. 01, title=Eien no replica, " - + "artist=Kazuo Nishi, singer_information=Male, duration=209.0, " - + "tempo=135, instruments=Gt, drum_information=Drum sequences, " - + "sections=SectionData('intervals', 'labels'), " - + "beats=BeatData('beat_times', 'beat_positions'))" - + "chords=ChordData('intervals', 'labels'), " - + "vocal_instrument_activity=EventData('start_times', 'end_times', 'event')" - ) - assert track.__repr__() == repr_string - def test_to_jams(): diff --git a/tests/test_salami.py b/tests/test_salami.py index 11a8b0a6c..fa7e8b767 100644 --- a/tests/test_salami.py +++ b/tests/test_salami.py @@ -50,20 +50,6 @@ def test_track(): assert sr == 44100 assert y.shape == (89856,) - repr_string = ( - "Salami Track(track_id=2, " - + "audio_path=tests/resources/mir_datasets/Salami/audio/2.mp3, " - + "source=Codaich, title=For_God_And_Country, " - + "artist=The_Smashing_Pumpkins, duration=264.0, annotator_1_id=5, " - + "annotator_2_id=8, annotator_1_time=37, annotator_2_time=45, " - + "broad_genre=popular, genre=Alternative_Pop___Rock, " - + "sections_annotator_1_uppercase=SectionData('intervals', 'labels'), " - + "sections_annotator_1_lowercase=SectionData('intervals', 'labels'), " - + "sections_annotator_2_uppercase=SectionData('intervals', 'labels'), " - + "sections_annotator_2_lowercase=SectionData('intervals', 'labels'))" - ) - assert track.__repr__() == repr_string - # Test file with missing annotations track = salami.Track('192', data_home=data_home) diff --git a/tests/test_tinysol.py b/tests/test_tinysol.py index 8e55e23d7..1cbdbe878 100644 --- a/tests/test_tinysol.py +++ b/tests/test_tinysol.py @@ -38,15 +38,9 @@ def test_track(): y, sr = track.audio assert y.shape == (272417,) assert sr == 44100 - repr_string = 'TinySOL Track(instrument=Flute, pitch=C4, dynamics=mf)' - assert track.__repr__() == repr_string # test with a string instrument track = tinysol.Track('Cb-ord-A2-mf-2c-N', data_home=data_home) - repr_string = ( - 'TinySOL Track(instrument=Contrabass, pitch=A2, ' + 'dynamics=mf, string=II)' - ) - assert track.__repr__() == repr_string def test_to_jams(): diff --git a/tests/test_utils.py b/tests/test_utils.py index d92dd9bac..4cfcc918e 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -143,3 +143,44 @@ def test_validator(mocker, mock_check_index, missing_files, invalid_checksums): def test_get_default_dataset_path(): assert '/tmp/mir_datasets/data_home' == utils.get_default_dataset_path('data_home') + + +def test_track_repr(): + + class TestTrack(utils.Track): + def __init__(self): + self.a = 'asdf' + self.b = 1.2345678 + self.c = {1: 'a', 'b': 2} + self._d = 'hidden' + self.e = None + + @property + def f(self): + """ThisObjectType: I have a docstring""" + return None + + @property + def g(self): + """I have an improper docstring""" + return None + + def h(self): + return "I'm a function!" + + expected1 = """Track(\n a="asdf",\n b=1.2345678,\n """ + expected2 = """c={1: 'a', 'b': 2},\n e=None,\n f: ThisObjectType,\n """ + expected3 = """g: I have an improper docstring,\n)""" + + test_track = TestTrack() + actual = test_track.__repr__() + assert actual == expected1 + expected2 + expected3 + + class NoDocsTrack(utils.Track): + @property + def no_doc(self): + return "whee!" + + bad_track = NoDocsTrack() + with pytest.raises(ValueError): + bad_track.__repr__() From 7bc4464c0192e4b6d71b9dae1720adb2beab1a61 Mon Sep 17 00:00:00 2001 From: Rachel Bittner Date: Thu, 2 Apr 2020 23:44:48 +0200 Subject: [PATCH 2/4] remove repr from example --- CONTRIBUTING.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d496c90f2..d281da48f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -170,7 +170,7 @@ DATA = utils.LargeData('example_index.json', _load_metadata) # DATA = utils.LargeData('example_index.json') ## use this if your dataset has no metadata -class Track(object): +class Track(utils.Track): """Example track class # -- YOU CAN AUTOMATICALLY GENERATE THIS DOCSTRING BY CALLING THE SCRIPT: # -- `scripts/print_track_docstring.py my_dataset` @@ -212,14 +212,6 @@ class Track(object): else: self.some_metadata = None - # -- this lets users run `print(Track)` and get actual information - def __repr__(self): - repr_string = "Example Track(track_id={}, audio_path={}, " + \ - "some_metadata{}, " - "annotation=AnnotationData('start_times', 'end_times', 'annotation'), " + \ - return repr_string.format( - self.track_id, self.audio_path, self.some_metadata) - # -- `annotation` will behave like an attribute, but it will only be loaded # -- and saved when someone accesses it. Useful when loading slightly # -- bigger files or for bigger datasets. By default, we make any time From b17d048b46ecbf1faee6d1be1307c147e8497cc7 Mon Sep 17 00:00:00 2001 From: Rachel Bittner Date: Thu, 2 Apr 2020 23:51:45 +0200 Subject: [PATCH 3/4] reformat --- mirdata/utils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mirdata/utils.py b/mirdata/utils.py index 359a4a3ef..f0d50a909 100644 --- a/mirdata/utils.py +++ b/mirdata/utils.py @@ -39,8 +39,7 @@ class Track(object): def __repr__(self): properties = [v for v in dir(self.__class__) if not v.startswith('_')] attributes = [ - v for v in dir(self) if not v.startswith('_') and - v not in properties + v for v in dir(self) if not v.startswith('_') and v not in properties ] repr_str = "Track(\n" From 0ba276c20b28f48d4cb5ae08ddc54382afbb1de8 Mon Sep 17 00:00:00 2001 From: Rachel Bittner Date: Fri, 3 Apr 2020 16:36:36 +0200 Subject: [PATCH 4/4] move base Track object to new module --- CONTRIBUTING.md | 3 +- docs/source/mirdata.rst | 6 ++++ mirdata/beatles.py | 3 +- mirdata/dali.py | 3 +- mirdata/gtzan_genre.py | 3 +- mirdata/guitarset.py | 3 +- mirdata/ikala.py | 3 +- mirdata/medley_solos_db.py | 3 +- mirdata/medleydb_melody.py | 3 +- mirdata/medleydb_pitch.py | 3 +- mirdata/orchset.py | 3 +- mirdata/rwc_classical.py | 3 +- mirdata/rwc_jazz.py | 3 +- mirdata/rwc_popular.py | 3 +- mirdata/salami.py | 3 +- mirdata/tinysol.py | 3 +- mirdata/track.py | 45 +++++++++++++++++++++++++++++ mirdata/utils.py | 34 ---------------------- tests/test_loaders.py | 4 +-- tests/test_track.py | 58 ++++++++++++++++++++++++++++++++++++++ tests/test_utils.py | 41 --------------------------- 21 files changed, 141 insertions(+), 92 deletions(-) create mode 100644 mirdata/track.py create mode 100644 tests/test_track.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d281da48f..c8ab40f49 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -136,6 +136,7 @@ from __future__ import print_function # -- import whatever you need here +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -170,7 +171,7 @@ DATA = utils.LargeData('example_index.json', _load_metadata) # DATA = utils.LargeData('example_index.json') ## use this if your dataset has no metadata -class Track(utils.Track): +class Track(track.Track): """Example track class # -- YOU CAN AUTOMATICALLY GENERATE THIS DOCSTRING BY CALLING THE SCRIPT: # -- `scripts/print_track_docstring.py my_dataset` diff --git a/docs/source/mirdata.rst b/docs/source/mirdata.rst index b97f5296d..26732dbf9 100644 --- a/docs/source/mirdata.rst +++ b/docs/source/mirdata.rst @@ -107,6 +107,12 @@ mirdata.tinysol Utilities ---------- +mirdata.track +^^^^^^^^^^^^^ + +.. automodule:: mirdata.track + :members: + mirdata.utils ^^^^^^^^^^^^^ diff --git a/mirdata/beatles.py b/mirdata/beatles.py index 0445782bc..c2ce2abdc 100644 --- a/mirdata/beatles.py +++ b/mirdata/beatles.py @@ -11,6 +11,7 @@ import os import numpy as np +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -26,7 +27,7 @@ DATA = utils.LargeData('beatles_index.json') -class Track(utils.Track): +class Track(track.Track): """Beatles track class Args: diff --git a/mirdata/dali.py b/mirdata/dali.py index 4481c8814..0c459e9eb 100644 --- a/mirdata/dali.py +++ b/mirdata/dali.py @@ -35,6 +35,7 @@ ) raise +import mirdata.track as track import mirdata.utils as utils DATASET_DIR = 'DALI' @@ -55,7 +56,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('dali_index.json', _load_metadata) -class Track(utils.Track): +class Track(track.Track): """DALI melody Track class Args: diff --git a/mirdata/gtzan_genre.py b/mirdata/gtzan_genre.py index 59f137a94..776c9de77 100644 --- a/mirdata/gtzan_genre.py +++ b/mirdata/gtzan_genre.py @@ -18,6 +18,7 @@ import librosa from mirdata import download_utils +import mirdata.track as track from mirdata import utils @@ -34,7 +35,7 @@ DATA = utils.LargeData("gtzan_genre_index.json") -class Track(utils.Track): +class Track(track.Track): """gtzan_genre Track class Args: diff --git a/mirdata/guitarset.py b/mirdata/guitarset.py index 438e7e0c6..dac7f25dd 100644 --- a/mirdata/guitarset.py +++ b/mirdata/guitarset.py @@ -53,6 +53,7 @@ import jams import logging +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils @@ -99,7 +100,7 @@ DATA = utils.LargeData('guitarset_index.json') -class Track(utils.Track): +class Track(track.Track): """guitarset Track class Args: diff --git a/mirdata/ikala.py b/mirdata/ikala.py index 9d410a07b..d1c217678 100644 --- a/mirdata/ikala.py +++ b/mirdata/ikala.py @@ -21,6 +21,7 @@ import logging import numpy as np +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -63,7 +64,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('ikala_index.json', _load_metadata) -class Track(utils.Track): +class Track(track.Track): """ikala Track class Args: diff --git a/mirdata/medley_solos_db.py b/mirdata/medley_solos_db.py index 499da7333..e75b08bdf 100644 --- a/mirdata/medley_solos_db.py +++ b/mirdata/medley_solos_db.py @@ -31,6 +31,7 @@ import logging import os +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -80,7 +81,7 @@ def _load_metadata(data_home): DATA = utils.LargeData("medley_solos_db_index.json", _load_metadata) -class Track(utils.Track): +class Track(track.Track): """medley_solos_db Track class Args: diff --git a/mirdata/medleydb_melody.py b/mirdata/medleydb_melody.py index 9ee66ae77..b776a2007 100644 --- a/mirdata/medleydb_melody.py +++ b/mirdata/medleydb_melody.py @@ -21,6 +21,7 @@ import numpy as np import os +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -45,7 +46,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('medleydb_melody_index.json', _load_metadata) -class Track(utils.Track): +class Track(track.Track): """medleydb_melody Track class Args: diff --git a/mirdata/medleydb_pitch.py b/mirdata/medleydb_pitch.py index 5ce23ec7d..6d163cc8f 100644 --- a/mirdata/medleydb_pitch.py +++ b/mirdata/medleydb_pitch.py @@ -21,6 +21,7 @@ import numpy as np import os +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -45,7 +46,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('medleydb_pitch_index.json', _load_metadata) -class Track(utils.Track): +class Track(track.Track): """medleydb_pitch Track class Args: diff --git a/mirdata/orchset.py b/mirdata/orchset.py index 64f0bd924..a1c9a8a7f 100644 --- a/mirdata/orchset.py +++ b/mirdata/orchset.py @@ -20,6 +20,7 @@ import os import shutil +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -98,7 +99,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('orchset_index.json', _load_metadata) -class Track(utils.Track): +class Track(track.Track): """orchset Track class Args: diff --git a/mirdata/rwc_classical.py b/mirdata/rwc_classical.py index 2ed02e576..0ab091c51 100644 --- a/mirdata/rwc_classical.py +++ b/mirdata/rwc_classical.py @@ -17,6 +17,7 @@ import numpy as np import os +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -88,7 +89,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('rwc_classical_index.json', _load_metadata) -class Track(utils.Track): +class Track(track.Track): """rwc_classical Track class Args: diff --git a/mirdata/rwc_jazz.py b/mirdata/rwc_jazz.py index b2549a635..5164d8b20 100644 --- a/mirdata/rwc_jazz.py +++ b/mirdata/rwc_jazz.py @@ -35,6 +35,7 @@ import logging import os +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -114,7 +115,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('rwc_jazz_index.json', _load_metadata) -class Track(utils.Track): +class Track(track.Track): """rwc_jazz Track class Args: diff --git a/mirdata/rwc_popular.py b/mirdata/rwc_popular.py index 4592b6aa5..e77c4b925 100644 --- a/mirdata/rwc_popular.py +++ b/mirdata/rwc_popular.py @@ -14,6 +14,7 @@ import numpy as np import os +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -107,7 +108,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('rwc_popular_index.json', _load_metadata) -class Track(utils.Track): +class Track(track.Track): """rwc_popular Track class Args: diff --git a/mirdata/salami.py b/mirdata/salami.py index 587bd2bd1..29159f104 100644 --- a/mirdata/salami.py +++ b/mirdata/salami.py @@ -17,6 +17,7 @@ import numpy as np import os +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -78,7 +79,7 @@ def _load_metadata(data_home): DATA = utils.LargeData('salami_index.json', _load_metadata) -class Track(utils.Track): +class Track(track.Track): """salami Track class Args: diff --git a/mirdata/tinysol.py b/mirdata/tinysol.py index a0de5b31c..61bcdabbc 100644 --- a/mirdata/tinysol.py +++ b/mirdata/tinysol.py @@ -50,6 +50,7 @@ import logging import os +import mirdata.track as track import mirdata.utils as utils import mirdata.download_utils as download_utils import mirdata.jams_utils as jams_utils @@ -108,7 +109,7 @@ def _load_metadata(data_home): DATA = utils.LargeData("tinysol_index.json", _load_metadata) -class Track(utils.Track): +class Track(track.Track): """tinysol Track class Args: diff --git a/mirdata/track.py b/mirdata/track.py new file mode 100644 index 000000000..8a126d19e --- /dev/null +++ b/mirdata/track.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +"""track object utility functions +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import types + +MAX_STR_LEN = 100 + + +class Track(object): + def __repr__(self): + properties = [v for v in dir(self.__class__) if not v.startswith('_')] + attributes = [ + v for v in dir(self) if not v.startswith('_') and v not in properties + ] + + repr_str = "Track(\n" + + for attr in attributes: + val = getattr(self, attr) + if isinstance(val, str): + if len(val) > MAX_STR_LEN: + val = '...{}'.format(val[-MAX_STR_LEN:]) + val = '"{}"'.format(val) + repr_str += " {}={},\n".format(attr, val) + + for prop in properties: + val = getattr(self.__class__, prop) + if isinstance(val, types.FunctionType): + continue + + if val.__doc__ is None: + raise ValueError("{} has no documentation".format(prop)) + + val_type_str = val.__doc__.split(':')[0] + repr_str += " {}: {},\n".format(prop, val_type_str) + + repr_str += ")" + return repr_str + + def to_jams(self): + raise NotImplementedError diff --git a/mirdata/utils.py b/mirdata/utils.py index f0d50a909..e34391f20 100644 --- a/mirdata/utils.py +++ b/mirdata/utils.py @@ -29,45 +29,11 @@ import hashlib import os import json -import types MIR_DATASETS_DIR = os.path.join(os.getenv('HOME', '/tmp'), 'mir_datasets') -class Track(object): - def __repr__(self): - properties = [v for v in dir(self.__class__) if not v.startswith('_')] - attributes = [ - v for v in dir(self) if not v.startswith('_') and v not in properties - ] - - repr_str = "Track(\n" - - for attr in attributes: - val = getattr(self, attr) - if isinstance(val, str): - val = '"{}"'.format(val) - repr_str += " {}={},\n".format(attr, val) - - for prop in properties: - val = getattr(self.__class__, prop) - if isinstance(val, types.FunctionType): - continue - - if val.__doc__ is None: - raise ValueError("{} has no documentation".format(prop)) - - val_type_str = val.__doc__.split(':')[0] - repr_str += " {}: {},\n".format(prop, val_type_str) - - repr_str += ")" - return repr_str - - def to_jams(self): - raise NotImplementedError - - def md5(file_path): """Get md5 hash of a file. diff --git a/tests/test_loaders.py b/tests/test_loaders.py index 8e5cd9df5..bac2efe36 100644 --- a/tests/test_loaders.py +++ b/tests/test_loaders.py @@ -9,7 +9,7 @@ import pytest import mirdata -import mirdata.utils as utils +import mirdata.track as track from tests.test_utils import DEFAULT_DATA_HOME DATASETS = [importlib.import_module("mirdata.{}".format(d)) for d in mirdata.__all__] @@ -66,7 +66,7 @@ def test_track(): assert track_default._data_home == os.path.join( DEFAULT_DATA_HOME, dataset.DATASET_DIR) - assert isinstance(track_default, utils.Track) + assert isinstance(track_default, track.Track) assert hasattr(track_default, 'to_jams') diff --git a/tests/test_track.py b/tests/test_track.py new file mode 100644 index 000000000..5486b9dbc --- /dev/null +++ b/tests/test_track.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import sys +import pytest + +from mirdata import track + +if sys.version_info.major == 3: + builtin_module_name = 'builtins' +else: + builtin_module_name = '__builtin__' + + +def test_track_repr(): + + class TestTrack(track.Track): + def __init__(self): + self.a = 'asdf' + self.b = 1.2345678 + self.c = {1: 'a', 'b': 2} + self._d = 'hidden' + self.e = None + self.long = 'a' + 'b' * 50 + 'c' * 50 + + @property + def f(self): + """ThisObjectType: I have a docstring""" + return None + + @property + def g(self): + """I have an improper docstring""" + return None + + def h(self): + return "I'm a function!" + + expected1 = """Track(\n a="asdf",\n b=1.2345678,\n """ + expected2 = """c={1: 'a', 'b': 2},\n e=None,\n """ + expected3 = """long="...{}",\n """.format('b' * 50 + 'c' * 50) + expected4 = """f: ThisObjectType,\n g: I have an improper docstring,\n)""" + + test_track = TestTrack() + actual = test_track.__repr__() + assert actual == expected1 + expected2 + expected3 + expected4 + + with pytest.raises(NotImplementedError): + test_track.to_jams() + + class NoDocsTrack(track.Track): + @property + def no_doc(self): + return "whee!" + + bad_track = NoDocsTrack() + with pytest.raises(ValueError): + bad_track.__repr__() diff --git a/tests/test_utils.py b/tests/test_utils.py index 4cfcc918e..d92dd9bac 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -143,44 +143,3 @@ def test_validator(mocker, mock_check_index, missing_files, invalid_checksums): def test_get_default_dataset_path(): assert '/tmp/mir_datasets/data_home' == utils.get_default_dataset_path('data_home') - - -def test_track_repr(): - - class TestTrack(utils.Track): - def __init__(self): - self.a = 'asdf' - self.b = 1.2345678 - self.c = {1: 'a', 'b': 2} - self._d = 'hidden' - self.e = None - - @property - def f(self): - """ThisObjectType: I have a docstring""" - return None - - @property - def g(self): - """I have an improper docstring""" - return None - - def h(self): - return "I'm a function!" - - expected1 = """Track(\n a="asdf",\n b=1.2345678,\n """ - expected2 = """c={1: 'a', 'b': 2},\n e=None,\n f: ThisObjectType,\n """ - expected3 = """g: I have an improper docstring,\n)""" - - test_track = TestTrack() - actual = test_track.__repr__() - assert actual == expected1 + expected2 + expected3 - - class NoDocsTrack(utils.Track): - @property - def no_doc(self): - return "whee!" - - bad_track = NoDocsTrack() - with pytest.raises(ValueError): - bad_track.__repr__()