diff --git a/tests/test_cli.py b/tests/test_cli.py index 8e0d207..cc2b783 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -49,9 +49,10 @@ def test_load_config(tmpdir, monkeypatch): assert general == {'foo': 1, 'status_path': status_path} assert pairs == {'bob': ('bob_a', 'bob_b', {'bam': True}, {'foo': 'bar'})} assert storages == { - 'bob_a': {'type': 'filesystem', 'path': contacts_path, - 'fileext': '.vcf', 'yesno': False, 'number': 42}, - 'bob_b': {'type': 'carddav'} + 'bob_a': {'type': 'filesystem', 'path': contacts_path, 'fileext': + '.vcf', 'yesno': False, 'number': 42, + 'instance_name': 'bob_a'}, + 'bob_b': {'type': 'carddav', 'instance_name': 'bob_b'} } assert len(errors) == 1 diff --git a/tests/utils/test_main.py b/tests/utils/test_main.py index 58975f2..929a48a 100644 --- a/tests/utils/test_main.py +++ b/tests/utils/test_main.py @@ -157,5 +157,5 @@ def test_get_class_init_args_on_storage(): from vdirsyncer.storage.memory import MemoryStorage all, required = utils.get_class_init_args(MemoryStorage) - assert all == set(['collection', 'read_only']) + assert all == set(['collection', 'read_only', 'instance_name']) assert not required diff --git a/vdirsyncer/cli.py b/vdirsyncer/cli.py index ae9f368..1e48ac4 100644 --- a/vdirsyncer/cli.py +++ b/vdirsyncer/cli.py @@ -55,6 +55,7 @@ def load_config(fname, pair_options=('collections', 'conflict_resolution')): def handle_storage(storage_name, options): storages.setdefault(storage_name, {}).update(options) + storages[storage_name]['instance_name'] = storage_name def handle_pair(pair_name, options): a, b = options.pop('a'), options.pop('b') diff --git a/vdirsyncer/storage/base.py b/vdirsyncer/storage/base.py index d2a0e5a..56b8184 100644 --- a/vdirsyncer/storage/base.py +++ b/vdirsyncer/storage/base.py @@ -36,7 +36,14 @@ class Storage(object): ''' fileext = '.txt' - storage_name = None # The name used in the config file. + + # The string used in the config to denote the type of storage. Should be + # overridden by subclasses. + storage_name = None + + # The string used in the config to denote a particular instance. Should be + # overridden during instantiation. + instance_name = None # A value of True means the storage does not support write-methods such as # upload, update and delete. A value of False means the storage does @@ -46,12 +53,13 @@ class Storage(object): # The attribute values to show in the representation of the storage. _repr_attributes = () - def __init__(self, read_only=None): + def __init__(self, instance_name=None, read_only=None): if read_only is None: read_only = self.read_only if self.read_only and not read_only: raise ValueError('This storage is read-only.') self.read_only = bool(read_only) + self.instance_name = instance_name @classmethod def discover(cls, **kwargs): @@ -66,7 +74,7 @@ class Storage(object): raise NotImplementedError() def __repr__(self): - return '<{}(**{})>'.format( + return self.instance_name or '<{}(**{})>'.format( self.__class__.__name__, dict((x, getattr(self, x)) for x in self._repr_attributes) )