diff --git a/bidict/_common.py b/bidict/_common.py index 1104b61..0fe6f4f 100644 --- a/bidict/_common.py +++ b/bidict/_common.py @@ -56,10 +56,14 @@ class BidirectionalMapping(Mapping): Returns True if only its start is not None and False if only its stop is not None. """ - if slice.step is not None or \ - (not ((slice.start is None) ^ (slice.stop is None))): + start_missing = slice.start is None + start_found = not start_missing + stop_missing = slice.stop is None + step_found = slice.step is not None + + if step_found or start_missing == stop_missing: raise TypeError('Slice must specify only either start or stop') - return slice.start is not None + return start_found def __getitem__(self, keyorslice): """ diff --git a/tests/test_slice.py b/tests/test_slice.py new file mode 100644 index 0000000..bc2f4cb --- /dev/null +++ b/tests/test_slice.py @@ -0,0 +1,49 @@ +from itertools import product + +import pytest + +from bidict import bidict + + +@pytest.fixture +def b(): + return bidict(H='hydrogen') + +single_test_data = {'H', 'hydrogen', -1, 0, 1} +bad_start_values = single_test_data - {'H'} +bad_stop_values = single_test_data - {'hydrogen'} +pair_test_data = product(single_test_data, single_test_data) + + +def test_good_start(b): + assert b['H'] == 'hydrogen' + assert b['H':] == 'hydrogen' + +@pytest.mark.parametrize('start', bad_start_values) +def test_bad_start(b, start): + with pytest.raises(KeyError): + b[start] + with pytest.raises(KeyError): + b[start:] + +def test_good_stop(b): + assert b[:'hydrogen'] == 'H' + +@pytest.mark.parametrize('stop', bad_stop_values) +def test_stop(b, stop): + with pytest.raises(KeyError): + b[:stop] + +@pytest.mark.parametrize('start, stop', pair_test_data) +def test_start_stop(b, start, stop): + with pytest.raises(TypeError): + b[start:stop] + +@pytest.mark.parametrize('step', single_test_data) +def test_step(b, step): + with pytest.raises(TypeError): + b[::step] + +def test_empty(b): + with pytest.raises(TypeError): + b[::]