From 45bb6b7b89dbce0c7ce4bea5a0b78f2de0764491 Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Mon, 26 Apr 2021 20:32:06 +0200 Subject: [PATCH 01/11] Scheme: store reference to database --- audformat/core/database.py | 17 +++++++++++++++-- audformat/core/scheme.py | 13 +++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/audformat/core/database.py b/audformat/core/database.py index d3c0895c..effd3cd7 100644 --- a/audformat/core/database.py +++ b/audformat/core/database.py @@ -151,12 +151,16 @@ def __init__( r"""Dictionary of media information""" self.raters = HeaderDict(value_type=Rater) r"""Dictionary of raters""" - self.schemes = HeaderDict(value_type=Scheme) + self.schemes = HeaderDict( + value_type=Scheme, + set_callback=self._set_scheme, + ) r"""Dictionary of schemes""" self.splits = HeaderDict(value_type=Split) r"""Dictionary of splits""" self.tables = HeaderDict( - value_type=Table, set_callback=self._set_table, + value_type=Table, + set_callback=self._set_table, ) r"""Dictionary of tables""" @@ -733,6 +737,15 @@ def load_header_from_yaml(header: dict) -> 'Database': return db + def _set_scheme( + self, + scheme_id: str, + scheme: Scheme, + ) -> Scheme: + scheme._db = self + scheme._id = scheme_id + return scheme + def _set_table( self, table_id: str, diff --git a/audformat/core/scheme.py b/audformat/core/scheme.py index 7e02653f..34493d53 100644 --- a/audformat/core/scheme.py +++ b/audformat/core/scheme.py @@ -113,6 +113,19 @@ def __init__( self.maximum = maximum if self.is_numeric else None r"""Maximum value""" + self._db = None + self._id = None + + @property + def db(self): + r"""Database object. + + Returns: + database object or ``None`` if not assigned yet + + """ + return self._db + @property def is_numeric(self) -> bool: r"""Check if data type is numeric. From 7e59477ea552fcff61fd2fddc281766ad8a9fc71 Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Mon, 26 Apr 2021 20:35:12 +0200 Subject: [PATCH 02/11] TST: test Scheme.db --- tests/test_scheme.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_scheme.py b/tests/test_scheme.py index af384830..7336fa67 100644 --- a/tests/test_scheme.py +++ b/tests/test_scheme.py @@ -9,6 +9,9 @@ def test_scheme(): db = audformat.testing.create_db() + for scheme_id in db.schemes: + assert db.schemes[scheme_id].db == db + assert 'tests' in db.schemes['string'] assert 0.0 in db.schemes['float'] assert 1.0 in db.schemes['float'] From b96d8bddf2b6d755194133c2d0ca887e0094b2f7 Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Mon, 26 Apr 2021 21:19:16 +0200 Subject: [PATCH 03/11] Scheme: add update_labels --- audformat/core/scheme.py | 24 +++++++++- tests/test_database.py | 24 +++++++++- tests/test_scheme.py | 96 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 140 insertions(+), 4 deletions(-) diff --git a/audformat/core/scheme.py b/audformat/core/scheme.py index 34493d53..f8252bb9 100644 --- a/audformat/core/scheme.py +++ b/audformat/core/scheme.py @@ -212,7 +212,8 @@ def to_pandas_dtype(self) -> typing.Union[ # allow nullable labels = pd.array(labels, dtype=pd.Int64Dtype()) return pd.api.types.CategoricalDtype( - categories=labels, ordered=False, + categories=labels, + ordered=False, ) elif self.dtype == define.DataType.BOOL: return 'boolean' @@ -224,6 +225,27 @@ def to_pandas_dtype(self) -> typing.Union[ return 'timedelta64[ns]' return self.dtype + def update_labels( + self, + labels: typing.Union[dict, list], + ): + if self.labels is None: + raise RuntimeError( + 'Cannot update labels because scheme does not define labels.' + ) + + self.labels = labels + + if self._db is not None and self._id is not None: + for table in self._db.tables.values(): + for column in table.columns.values(): + if column.scheme_id == self._id: + column.get(copy=False).cat.set_categories( + new_categories=self.labels, + ordered=False, + inplace=True, + ) + def __contains__(self, item: typing.Any) -> bool: r"""Check if scheme contains data type of item. diff --git a/tests/test_database.py b/tests/test_database.py index 61b90ead..3f2a022a 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -312,12 +312,16 @@ def test_update(): db.meta['meta'] = 'meta' db.raters['rater'] = audformat.Rater() db.schemes['float'] = audformat.Scheme(float) + db.schemes['labels'] = audformat.Scheme(labels=['a', 'b']) audformat.testing.add_table( db, 'table', audformat.define.IndexType.FILEWISE, num_files=[0, 1], - columns={'float': ('float', 'rater')}, + columns={ + 'float': ('float', 'rater'), + 'labels': ('labels', None), + }, ) assert db.update(db) == db @@ -329,12 +333,17 @@ def test_update(): other1.raters['rater2'] = audformat.Rater() other1.schemes['int'] = audformat.Scheme(int) other1.schemes['float'] = audformat.Scheme(float) + other1.schemes['labels'] = audformat.Scheme(labels=['b', 'c']) audformat.testing.add_table( other1, 'table', audformat.define.IndexType.FILEWISE, num_files=[1, 2], - columns={'int': ('int', 'rater'), 'float': ('float', 'rater2')}, + columns={ + 'int': ('int', 'rater'), + 'float': ('float', 'rater2'), + 'labels': ('labels', None), + }, ) # database with new table @@ -349,6 +358,17 @@ def test_update(): columns={'str': ('str', 'rater2')}, ) + # raises error because schemes do not match + + with pytest.raises(ValueError): + audformat.utils.concat( + [db['table'].df, other1['table'].df], + overwrite=True, + ) + + # update scheme to avoid error + + db.schemes['labels'].update_labels(other1.schemes['labels'].labels) df = audformat.utils.concat( [db['table'].df, other1['table'].df], overwrite=True, diff --git a/tests/test_scheme.py b/tests/test_scheme.py index 7336fa67..be302a91 100644 --- a/tests/test_scheme.py +++ b/tests/test_scheme.py @@ -7,7 +7,7 @@ def test_scheme(): - db = audformat.testing.create_db() + db = pytest.DB for scheme_id in db.schemes: assert db.schemes[scheme_id].db == db @@ -23,6 +23,9 @@ def test_scheme(): assert 'label1' in db.schemes['label_map_str'] assert 1 in db.schemes['label_map_int'] + +def test_scheme_errors(): + # dtype mismatch with pytest.raises(ValueError): audformat.Scheme( @@ -41,3 +44,94 @@ def test_scheme(): # labels do not have the same type with pytest.raises(ValueError): audformat.Scheme(labels=[1, '2', 3]) + + # update labels when scheme has no label + with pytest.raises(RuntimeError): + scheme = audformat.Scheme(audformat.define.DataType.INTEGER) + scheme.update_labels(['a', 'b']) + + +@pytest.mark.parametrize( + 'values, labels, new_labels, expected', + [ + ( + pd.Series( + index=audformat.filewise_index(), + dtype=pd.CategoricalDtype(), + ), + [], + [], + pd.Series( + index=audformat.filewise_index(), + dtype=pd.CategoricalDtype(), + ), + ), + ( + pd.Series( + index=audformat.filewise_index(), + dtype=pd.CategoricalDtype(['a', 'b']), + ), + ['a', 'b'], + ['b', 'c', 'd'], + pd.Series( + index=audformat.filewise_index(), + dtype=pd.CategoricalDtype(['b', 'c', 'd']), + ), + ), + ( + pd.Series( + ['a', 'b'], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype(['a', 'b']), + ), + ['a', 'b'], + ['a'], + pd.Series( + ['a', None], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype(['a']), + ), + ), + ( + pd.Series( + ['a', 'b'], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype(['a', 'b']), + ), + ['a', 'b'], + ['a', 'b', 'c'], + pd.Series( + ['a', 'b'], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype(['a', 'b', 'c']), + ), + ), + ( + pd.Series( + ['a', 'b'], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype(['a', 'b']), + ), + ['a', 'b'], + ['c'], + pd.Series( + [None, None], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype(['c']), + ), + ), + ] +) +def test_update_labels(values, labels, new_labels, expected): + + db = audformat.testing.create_db(minimal=True) + db.schemes['scheme'] = audformat.Scheme(labels=labels) + db['table'] = audformat.Table(index=values.index) + db['table']['columns'] = audformat.Column(scheme_id='scheme') + db['table']['columns'].set(values) + db.schemes['scheme'].update_labels(new_labels) + pd.testing.assert_series_equal( + db['table']['columns'].get(), + expected, + check_names=False, + ) From 5775cdd246e0ea13863152a1d723805b1034bb1a Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Mon, 26 Apr 2021 21:41:41 +0200 Subject: [PATCH 04/11] DOC: add docstring --- audformat/core/scheme.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/audformat/core/scheme.py b/audformat/core/scheme.py index f8252bb9..8e47a460 100644 --- a/audformat/core/scheme.py +++ b/audformat/core/scheme.py @@ -229,6 +229,19 @@ def update_labels( self, labels: typing.Union[dict, list], ): + r"""Update labels. + + If scheme is part of a :class:`audformat.Database` + the dtype of :class:`audformat.Column`s that reference the scheme + will be updated. Values of removed labels are set to ``NaN``. + + Args: + labels: new labels + + Raises: + RuntimeError: if scheme does not define labels + + """ if self.labels is None: raise RuntimeError( 'Cannot update labels because scheme does not define labels.' From 28dce5621d8aca93b80ebdfab45eb08a88888cd6 Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Tue, 27 Apr 2021 06:28:28 +0200 Subject: [PATCH 05/11] DOC: docstring example --- audformat/core/scheme.py | 32 ++++++++++++++++++++++++++++---- tests/test_scheme.py | 16 +++++++++++++++- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/audformat/core/scheme.py b/audformat/core/scheme.py index 8e47a460..cc65166d 100644 --- a/audformat/core/scheme.py +++ b/audformat/core/scheme.py @@ -233,18 +233,42 @@ def update_labels( If scheme is part of a :class:`audformat.Database` the dtype of :class:`audformat.Column`s that reference the scheme - will be updated. Values of removed labels are set to ``NaN``. + will be updated. Removed labels are set to ``NaN``. Args: labels: new labels Raises: - RuntimeError: if scheme does not define labels + ValueError: if scheme does not define labels + + Example: + >>> speaker = Scheme( + ... labels={ + ... 0: {'gender': 'female'}, + ... 1: {'gender': 'male'}, + ... } + ... ) + >>> speaker + dtype: int + labels: + 0: {gender: female} + 1: {gender: male} + >>> speaker.update_labels( + ... labels={ + ... 1: {'gender': 'male', 'age': 33}, + ... 2: {'gender': 'female', 'age': 44}, + ... } + ... ) + >>> speaker + dtype: int + labels: + 1: {gender: male, age: 33} + 2: {gender: female, age: 44} """ if self.labels is None: - raise RuntimeError( - 'Cannot update labels because scheme does not define labels.' + raise ValueError( + 'Cannot update labels when scheme does not define labels.' ) self.labels = labels diff --git a/tests/test_scheme.py b/tests/test_scheme.py index be302a91..3e41e927 100644 --- a/tests/test_scheme.py +++ b/tests/test_scheme.py @@ -46,7 +46,7 @@ def test_scheme_errors(): audformat.Scheme(labels=[1, '2', 3]) # update labels when scheme has no label - with pytest.raises(RuntimeError): + with pytest.raises(ValueError): scheme = audformat.Scheme(audformat.define.DataType.INTEGER) scheme.update_labels(['a', 'b']) @@ -120,6 +120,20 @@ def test_scheme_errors(): dtype=pd.CategoricalDtype(['c']), ), ), + ( + pd.Series( + [0, 1], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype([0, 1]), + ), + {0: 'a', 1: 'b'}, + {1: 'b', 2: 'c'}, + pd.Series( + [None, 1], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype([1, 2]), + ), + ), ] ) def test_update_labels(values, labels, new_labels, expected): From d627dfbfe56e6e45790fa16ab86d43c3c6953e58 Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Tue, 27 Apr 2021 06:51:15 +0200 Subject: [PATCH 06/11] raise error if dtype of new labels does not match dtype of scheme --- audformat/core/scheme.py | 68 +++++++++++++++++++++++++++------------- tests/test_scheme.py | 44 +++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 22 deletions(-) diff --git a/audformat/core/scheme.py b/audformat/core/scheme.py index cc65166d..805f5d76 100644 --- a/audformat/core/scheme.py +++ b/audformat/core/scheme.py @@ -81,28 +81,16 @@ def __init__( if dtype is None and labels is None: dtype = define.DataType.STRING - if labels is not None and len(labels) > 0: - if not isinstance(labels, (dict, list)): + if labels is not None: + dtype_labels = self._dtype_from_labels(labels) + if dtype is not None and dtype != dtype_labels: raise ValueError( - 'Labels must be passed as a dictionary or a list.' + "Data type is set to " + f"'{dtype}', " + "but data type of labels is " + f"'{dtype_labels}'." ) - derived_dtype = type(list(labels)[0]) - if not all(isinstance(x, derived_dtype) for x in list(labels)): - raise ValueError( - 'All labels must be of the same data type.' - ) - if derived_dtype in self._dtypes: - derived_dtype = self._dtypes[derived_dtype] - define.DataType.assert_has_attribute_value(derived_dtype) - if dtype is not None: - if dtype != derived_dtype: - raise ValueError( - "Data type is set to " - f"'{dtype}', " - "but data type of labels is " - f"'{derived_dtype}'." - ) - dtype = derived_dtype + dtype = dtype_labels self.dtype = dtype r"""Data type""" @@ -240,6 +228,8 @@ def update_labels( Raises: ValueError: if scheme does not define labels + ValueError: if dtype of new labels does not match dtype of + scheme Example: >>> speaker = Scheme( @@ -268,7 +258,17 @@ def update_labels( """ if self.labels is None: raise ValueError( - 'Cannot update labels when scheme does not define labels.' + 'Cannot update labels when ' + 'scheme does not define labels.' + ) + + dtype_labels = self._dtype_from_labels(labels) + if dtype_labels != self.dtype: + raise ValueError( + "Data type of labels must not change: \n" + f"'{self.dtype}' \n" + f"!=\n" + f"'{dtype_labels}'" ) self.labels = labels @@ -283,6 +283,32 @@ def update_labels( inplace=True, ) + def _dtype_from_labels( + self, + labels: typing.Union[dict, list], + ) -> str: + r"""Derive dtype from labels.""" + + if not isinstance(labels, (dict, list)): + raise ValueError( + 'Labels must be passed as a dictionary or a list.' + ) + + if len(labels) > 0: + dtype = type(list(labels)[0]) + else: + dtype = 'str' + if not all(isinstance(x, dtype) for x in list(labels)): + raise ValueError( + 'All labels must be of the same data type.' + ) + + if dtype in self._dtypes: + dtype = self._dtypes[dtype] + define.DataType.assert_has_attribute_value(dtype) + + return dtype + def __contains__(self, item: typing.Any) -> bool: r"""Check if scheme contains data type of item. diff --git a/tests/test_scheme.py b/tests/test_scheme.py index 3e41e927..510654aa 100644 --- a/tests/test_scheme.py +++ b/tests/test_scheme.py @@ -120,6 +120,34 @@ def test_scheme_errors(): dtype=pd.CategoricalDtype(['c']), ), ), + ( + pd.Series( + ['a', 'b'], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype(['a', 'b']), + ), + ['a', 'b'], + [], + pd.Series( + [None, None], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype([]), + ), + ), + ( + pd.Series( + [0, 1], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype([0, 1]), + ), + {0: 'a', 1: 'b'}, + {1: {'b': 'B'}, 2: {'c': 'C'}}, + pd.Series( + [None, 1], + index=audformat.filewise_index(['f1', 'f2']), + dtype=pd.CategoricalDtype([1, 2]), + ), + ), ( pd.Series( [0, 1], @@ -127,13 +155,27 @@ def test_scheme_errors(): dtype=pd.CategoricalDtype([0, 1]), ), {0: 'a', 1: 'b'}, - {1: 'b', 2: 'c'}, + [1, 2], pd.Series( [None, 1], index=audformat.filewise_index(['f1', 'f2']), dtype=pd.CategoricalDtype([1, 2]), ), ), + # error: dtype of labels does not match + pytest.param( + pd.Series( + index=audformat.filewise_index(), + dtype=pd.CategoricalDtype(), + ), + ['a', 'b'], + [0, 1], + pd.Series( + index=audformat.filewise_index(), + dtype=pd.CategoricalDtype(), + ), + marks=pytest.mark.xfail(raises=ValueError), + ) ] ) def test_update_labels(values, labels, new_labels, expected): From aca9fb8dc0f0bb235e457f319bfcfb3b2e061425 Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Tue, 27 Apr 2021 14:13:57 +0200 Subject: [PATCH 07/11] Scheme: rename to replace_labels() --- audformat/core/scheme.py | 8 ++++---- tests/test_database.py | 4 ++-- tests/test_scheme.py | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/audformat/core/scheme.py b/audformat/core/scheme.py index 805f5d76..741138d6 100644 --- a/audformat/core/scheme.py +++ b/audformat/core/scheme.py @@ -213,11 +213,11 @@ def to_pandas_dtype(self) -> typing.Union[ return 'timedelta64[ns]' return self.dtype - def update_labels( + def replace_labels( self, labels: typing.Union[dict, list], ): - r"""Update labels. + r"""Replace labels. If scheme is part of a :class:`audformat.Database` the dtype of :class:`audformat.Column`s that reference the scheme @@ -243,7 +243,7 @@ def update_labels( labels: 0: {gender: female} 1: {gender: male} - >>> speaker.update_labels( + >>> speaker.replace_labels( ... labels={ ... 1: {'gender': 'male', 'age': 33}, ... 2: {'gender': 'female', 'age': 44}, @@ -258,7 +258,7 @@ def update_labels( """ if self.labels is None: raise ValueError( - 'Cannot update labels when ' + 'Cannot replace labels when ' 'scheme does not define labels.' ) diff --git a/tests/test_database.py b/tests/test_database.py index 3f2a022a..f94db981 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -366,9 +366,9 @@ def test_update(): overwrite=True, ) - # update scheme to avoid error + # replace labels to avoid error - db.schemes['labels'].update_labels(other1.schemes['labels'].labels) + db.schemes['labels'].replace_labels(other1.schemes['labels'].labels) df = audformat.utils.concat( [db['table'].df, other1['table'].df], overwrite=True, diff --git a/tests/test_scheme.py b/tests/test_scheme.py index 510654aa..b331429c 100644 --- a/tests/test_scheme.py +++ b/tests/test_scheme.py @@ -48,7 +48,7 @@ def test_scheme_errors(): # update labels when scheme has no label with pytest.raises(ValueError): scheme = audformat.Scheme(audformat.define.DataType.INTEGER) - scheme.update_labels(['a', 'b']) + scheme.replace_labels(['a', 'b']) @pytest.mark.parametrize( @@ -178,14 +178,14 @@ def test_scheme_errors(): ) ] ) -def test_update_labels(values, labels, new_labels, expected): +def test_replace_labels(values, labels, new_labels, expected): db = audformat.testing.create_db(minimal=True) db.schemes['scheme'] = audformat.Scheme(labels=labels) db['table'] = audformat.Table(index=values.index) db['table']['columns'] = audformat.Column(scheme_id='scheme') db['table']['columns'].set(values) - db.schemes['scheme'].update_labels(new_labels) + db.schemes['scheme'].replace_labels(new_labels) pd.testing.assert_series_equal( db['table']['columns'].get(), expected, From 491eebe4858a8258d46119a75872e23faee35d9c Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Wed, 28 Apr 2021 14:13:17 +0200 Subject: [PATCH 08/11] Update audformat/core/scheme.py Co-authored-by: Hagen Wierstorf --- audformat/core/scheme.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audformat/core/scheme.py b/audformat/core/scheme.py index 741138d6..7826a62e 100644 --- a/audformat/core/scheme.py +++ b/audformat/core/scheme.py @@ -220,7 +220,7 @@ def replace_labels( r"""Replace labels. If scheme is part of a :class:`audformat.Database` - the dtype of :class:`audformat.Column`s that reference the scheme + the dtype of all :class:`audformat.Column` objects that reference the scheme will be updated. Removed labels are set to ``NaN``. Args: From 7158484c07bad3cd46bea9357b609d9f0f7cc835 Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Wed, 28 Apr 2021 14:13:34 +0200 Subject: [PATCH 09/11] Update audformat/core/scheme.py Co-authored-by: Hagen Wierstorf --- audformat/core/scheme.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audformat/core/scheme.py b/audformat/core/scheme.py index 7826a62e..40edf077 100644 --- a/audformat/core/scheme.py +++ b/audformat/core/scheme.py @@ -244,7 +244,7 @@ def replace_labels( 0: {gender: female} 1: {gender: male} >>> speaker.replace_labels( - ... labels={ + ... { ... 1: {'gender': 'male', 'age': 33}, ... 2: {'gender': 'female', 'age': 44}, ... } From 4822edb5cb335d78b4be9d720b6bca5ec55d3493 Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Wed, 28 Apr 2021 14:19:42 +0200 Subject: [PATCH 10/11] DOC: fix long line --- audformat/core/scheme.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/audformat/core/scheme.py b/audformat/core/scheme.py index 40edf077..dc72f638 100644 --- a/audformat/core/scheme.py +++ b/audformat/core/scheme.py @@ -220,8 +220,9 @@ def replace_labels( r"""Replace labels. If scheme is part of a :class:`audformat.Database` - the dtype of all :class:`audformat.Column` objects that reference the scheme - will be updated. Removed labels are set to ``NaN``. + the dtype of all :class:`audformat.Column` objects + that reference the scheme will be updated. + Removed labels are set to ``NaN``. Args: labels: new labels From ad4d07190c091c26dea487303f01b473e87e8f5c Mon Sep 17 00:00:00 2001 From: Johannes Wagner Date: Wed, 28 Apr 2021 14:22:32 +0200 Subject: [PATCH 11/11] Scheme: remove db attribute --- audformat/core/scheme.py | 10 ---------- tests/test_scheme.py | 3 --- 2 files changed, 13 deletions(-) diff --git a/audformat/core/scheme.py b/audformat/core/scheme.py index dc72f638..f8a7882d 100644 --- a/audformat/core/scheme.py +++ b/audformat/core/scheme.py @@ -104,16 +104,6 @@ def __init__( self._db = None self._id = None - @property - def db(self): - r"""Database object. - - Returns: - database object or ``None`` if not assigned yet - - """ - return self._db - @property def is_numeric(self) -> bool: r"""Check if data type is numeric. diff --git a/tests/test_scheme.py b/tests/test_scheme.py index b331429c..83be95d8 100644 --- a/tests/test_scheme.py +++ b/tests/test_scheme.py @@ -9,9 +9,6 @@ def test_scheme(): db = pytest.DB - for scheme_id in db.schemes: - assert db.schemes[scheme_id].db == db - assert 'tests' in db.schemes['string'] assert 0.0 in db.schemes['float'] assert 1.0 in db.schemes['float']