mirror of https://github.com/jab/bidict.git
202 lines
4.6 KiB
Plaintext
202 lines
4.6 KiB
Plaintext
Test script for bidict.bidict::
|
|
|
|
>>> from bidict import bidict
|
|
>>> keys = (1, 2, 3)
|
|
>>> vals = ('one', 'two', 'three')
|
|
>>> bi = bidict(zip(keys, vals))
|
|
>>> bi == bidict({1: 'one', 2: 'two', 3: 'three'})
|
|
True
|
|
|
|
Works like dict for getting and changing forward mappings::
|
|
|
|
>>> bi[2]
|
|
'two'
|
|
>>> bi[2] = 'twain'
|
|
>>> bi[2]
|
|
'twain'
|
|
>>> bi[4]
|
|
Traceback (most recent call last):
|
|
...
|
|
KeyError: 4
|
|
>>> del bi[2]
|
|
>>> bi.pop(3)
|
|
'three'
|
|
>>> bi
|
|
bidict({1: 'one'})
|
|
|
|
``put`` can also be used to insert a mapping as long as its key and value
|
|
don't already exist::
|
|
|
|
>>> bi.put(0, 'zero')
|
|
>>> bi[0]
|
|
'zero'
|
|
>>> bi.put(1, 'aught')
|
|
Traceback (most recent call last):
|
|
...
|
|
KeyDuplicationError: 1
|
|
>>> del bi[1]
|
|
>>> bi.put(1, 'aught')
|
|
>>> bi[1]
|
|
'aught'
|
|
>>> del bi[0]
|
|
>>> bi
|
|
bidict({1: 'aught'})
|
|
|
|
bidicts maintain references to their inverses via the ``inv`` property,
|
|
which can also be used to access or modify them::
|
|
|
|
>>> bi.inv
|
|
bidict({'aught': 1})
|
|
>>> bi.inv['aught']
|
|
1
|
|
>>> bi.inv['aught'] = 'one'
|
|
>>> bi
|
|
bidict({'one': 'aught'})
|
|
>>> bi.inv.pop('aught')
|
|
'one'
|
|
>>> bi == bi.inv == bidict()
|
|
True
|
|
>>> bi.inv.update(one=1)
|
|
>>> bi
|
|
bidict({1: 'one'})
|
|
>>> bi is bi.inv.inv
|
|
True
|
|
>>> bi.inv is bi.inv.inv.inv
|
|
True
|
|
|
|
bidicts work with ``inverted`` as expected::
|
|
|
|
>>> from bidict import inverted
|
|
>>> biinv = bidict(inverted(bi))
|
|
>>> biinv
|
|
bidict({'one': 1})
|
|
|
|
This created a new object (equivalent but not identical)::
|
|
|
|
>>> biinv == bi.inv
|
|
True
|
|
>>> biinv is bi.inv
|
|
False
|
|
|
|
Inverting the inverse should round-trip::
|
|
|
|
>>> bi == bidict(inverted(inverted(bi)))
|
|
True
|
|
>>> bi = bi.inv
|
|
>>> bi == bidict(inverted(inverted(bi)))
|
|
True
|
|
|
|
The rest of the ``MutableMapping`` interface is supported::
|
|
|
|
>>> bi.get('one')
|
|
1
|
|
>>> bi.get('zero')
|
|
>>> bi.get('zero', 0)
|
|
0
|
|
>>> list(bi.keys())
|
|
['one']
|
|
>>> list(bi.values())
|
|
[1]
|
|
>>> list(bi.items())
|
|
[('one', 1)]
|
|
>>> bi.setdefault('one', 2)
|
|
1
|
|
>>> bi.setdefault('two', 2)
|
|
2
|
|
>>> bi.pop('one')
|
|
1
|
|
>>> bi.pop('wrong', 'number', 'of', 'args')
|
|
Traceback (most recent call last):
|
|
...
|
|
TypeError: pop expected at most 2 arguments (got 4)
|
|
>>> bi.popitem()
|
|
('two', 2)
|
|
>>> bi.popitem()
|
|
Traceback (most recent call last):
|
|
...
|
|
KeyError: 'popitem(): bidict is empty'
|
|
>>> bi.inv.setdefault(3, 'three')
|
|
'three'
|
|
>>> bi
|
|
bidict({'three': 3})
|
|
>>> len(bi) # calls __len__
|
|
1
|
|
>>> [key for key in bi] # calls __iter__, returns keys like dict
|
|
['three']
|
|
>>> 'three' in bi # calls __contains__
|
|
True
|
|
>>> list(bi.keys())
|
|
['three']
|
|
>>> list(bi.values())
|
|
[3]
|
|
>>> bi.update([('four', 4)])
|
|
>>> bi.update({'five': 5}, six=6, seven=7)
|
|
>>> sorted(bi.items(), key=lambda x: x[1])
|
|
[('three', 3), ('four', 4), ('five', 5), ('six', 6), ('seven', 7)]
|
|
>>> bi.clear()
|
|
>>> bi
|
|
bidict({})
|
|
|
|
Initializing with different keys mapping to the same value fails::
|
|
|
|
>>> bidict([(1, 1), (2, 1)])
|
|
Traceback (most recent call last):
|
|
...
|
|
ValueDuplicationError: 1
|
|
|
|
Adding a new key associated with an existing value fails::
|
|
|
|
>>> b = bidict({1: 1})
|
|
>>> b[2] = 1
|
|
Traceback (most recent call last):
|
|
...
|
|
ValueDuplicationError: 1
|
|
>>> b.update({2: 1})
|
|
Traceback (most recent call last):
|
|
...
|
|
ValueDuplicationError: 1
|
|
|
|
``forceput`` and ``forceupdate`` can be used instead::
|
|
|
|
>>> b.forceput(2, 1)
|
|
>>> b
|
|
bidict({2: 1})
|
|
>>> b.forceupdate({1: 1})
|
|
>>> b
|
|
bidict({1: 1})
|
|
|
|
Trying to insert an existing mapping does not raise, and is a no-op::
|
|
|
|
>>> b = bidict({1: 'one'})
|
|
>>> b[1] = 'one'
|
|
>>> b[1]
|
|
'one'
|
|
>>> b.inv['one'] = 1
|
|
>>> b.inv['one']
|
|
1
|
|
|
|
The following case does not half-succeed,
|
|
leaving a bidict in an inconsistent state::
|
|
|
|
>>> b = bidict(one=1, two=2)
|
|
>>> b['one'] = 2
|
|
Traceback (most recent call last):
|
|
...
|
|
KeyAndValueDuplicationError: ('one', 2)
|
|
>>> len(b) == len(b.inv)
|
|
True
|
|
|
|
``put`` and ``putall`` allow you to have
|
|
per-call control over collision behavior
|
|
(see doctests in ``../docs/unique-values.rst.inc``).
|
|
|
|
Even with RAISE collision behavior,
|
|
inserting existing items is a no-op (i.e. it doesn't raise)::
|
|
|
|
>>> from bidict import RAISE
|
|
>>> b.putall([('three', 3), ('one', 1)],
|
|
... on_dup_key=RAISE, on_dup_val=RAISE) is not 'an error'
|
|
True
|
|
>>> sorted(b.items(), key=lambda x: x[1])
|
|
[('one', 1), ('two', 2), ('three', 3)]
|