mirror of
https://github.com/KevinMidboe/python-gpiozero.git
synced 2025-10-29 17:50:37 +00:00
Change CompositeDevice to reject invalid identifiers
Also updated StatusBoard and StatusZero to reject duplicate identifiers (namedtuple doesn't pick 'em up because they're passed in a dict and thus the dups are squashed prior to the call). Added tests for all the relevant stuff.
This commit is contained in:
@@ -12,7 +12,7 @@ except ImportError:
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
from itertools import repeat, cycle, chain
|
from itertools import repeat, cycle, chain
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict, Counter
|
||||||
|
|
||||||
from .exc import (
|
from .exc import (
|
||||||
DeviceClosed,
|
DeviceClosed,
|
||||||
@@ -819,6 +819,8 @@ class StatusZero(LEDBoard):
|
|||||||
|
|
||||||
.. _STATUS Zero: https://thepihut.com/statuszero
|
.. _STATUS Zero: https://thepihut.com/statuszero
|
||||||
"""
|
"""
|
||||||
|
default_labels = ('one', 'two', 'three')
|
||||||
|
|
||||||
def __init__(self, *labels, **kwargs):
|
def __init__(self, *labels, **kwargs):
|
||||||
pins = (
|
pins = (
|
||||||
(17, 4),
|
(17, 4),
|
||||||
@@ -826,12 +828,14 @@ class StatusZero(LEDBoard):
|
|||||||
(9, 10),
|
(9, 10),
|
||||||
)
|
)
|
||||||
if len(labels) == 0:
|
if len(labels) == 0:
|
||||||
labels = ['one', 'two', 'three']
|
labels = self.default_labels
|
||||||
elif len(labels) > len(pins):
|
elif len(labels) > len(pins):
|
||||||
raise ValueError
|
raise ValueError("StatusZero doesn't support more than three labels")
|
||||||
|
dup, count = Counter(labels).most_common(1)[0]
|
||||||
|
if count > 1:
|
||||||
|
raise ValueError("Duplicate label %s" % dup)
|
||||||
strips = OrderedDict()
|
strips = OrderedDict()
|
||||||
for index, label in enumerate(labels):
|
for (green, red), label in zip(pins, labels):
|
||||||
green, red = pins[index]
|
|
||||||
strips[label] = LEDBoard(red=red, green=green,
|
strips[label] = LEDBoard(red=red, green=green,
|
||||||
_order=('red', 'green'), **kwargs)
|
_order=('red', 'green'), **kwargs)
|
||||||
super(StatusZero, self).__init__(_order=strips.keys(), **strips)
|
super(StatusZero, self).__init__(_order=strips.keys(), **strips)
|
||||||
@@ -861,6 +865,8 @@ class StatusBoard(CompositeOutputDevice):
|
|||||||
|
|
||||||
.. _STATUS: https://thepihut.com/status
|
.. _STATUS: https://thepihut.com/status
|
||||||
"""
|
"""
|
||||||
|
default_labels = ('one', 'two', 'three', 'four', 'five')
|
||||||
|
|
||||||
def __init__(self, *labels, **kwargs):
|
def __init__(self, *labels, **kwargs):
|
||||||
pins = (
|
pins = (
|
||||||
(17, 4, 14),
|
(17, 4, 14),
|
||||||
@@ -870,12 +876,14 @@ class StatusBoard(CompositeOutputDevice):
|
|||||||
(13, 6, 18),
|
(13, 6, 18),
|
||||||
)
|
)
|
||||||
if len(labels) == 0:
|
if len(labels) == 0:
|
||||||
labels = ['one', 'two', 'three', 'four', 'five']
|
labels = self.default_labels
|
||||||
elif len(labels) > len(pins):
|
elif len(labels) > len(pins):
|
||||||
raise ValueError
|
raise ValueError("StatusBoard doesn't support more than five labels")
|
||||||
|
dup, count = Counter(labels).most_common(1)[0]
|
||||||
|
if count > 1:
|
||||||
|
raise ValueError("Duplicate label %s" % dup)
|
||||||
strips = OrderedDict()
|
strips = OrderedDict()
|
||||||
for index, label in enumerate(labels):
|
for (green, red, button), label in zip(pins, labels):
|
||||||
green, red, button = pins[index]
|
|
||||||
strips[label] = CompositeOutputDevice(
|
strips[label] = CompositeOutputDevice(
|
||||||
button=Button(button),
|
button=Button(button),
|
||||||
lights=LEDBoard(
|
lights=LEDBoard(
|
||||||
|
|||||||
@@ -330,8 +330,7 @@ class CompositeDevice(Device):
|
|||||||
raise CompositeDeviceBadDevice("%s doesn't inherit from Device" % dev)
|
raise CompositeDeviceBadDevice("%s doesn't inherit from Device" % dev)
|
||||||
self._named = frozendict(kwargs)
|
self._named = frozendict(kwargs)
|
||||||
self._namedtuple = namedtuple('%sValue' % self.__class__.__name__, chain(
|
self._namedtuple = namedtuple('%sValue' % self.__class__.__name__, chain(
|
||||||
(str(i) for i in range(len(args))), self._order),
|
('device_%d' % i for i in range(len(args))), self._order))
|
||||||
rename=True)
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
# if _named doesn't exist yet, pretend it's an empty dict
|
# if _named doesn't exist yet, pretend it's an empty dict
|
||||||
|
|||||||
@@ -783,13 +783,21 @@ def test_energenie():
|
|||||||
|
|
||||||
def test_statuszero_init():
|
def test_statuszero_init():
|
||||||
with StatusZero() as sz:
|
with StatusZero() as sz:
|
||||||
assert sz
|
assert sz.namedtuple._fields == ('one', 'two', 'three')
|
||||||
with StatusZero('a') as sz:
|
with StatusZero('a') as sz:
|
||||||
assert sz
|
assert sz.namedtuple._fields == ('a',)
|
||||||
with StatusZero('a', 'b') as sz:
|
with StatusZero('a', 'b') as sz:
|
||||||
assert sz
|
assert sz.namedtuple._fields == ('a', 'b')
|
||||||
with StatusZero('a', 'b', 'c') as sz:
|
with StatusZero('a', 'b', 'c') as sz:
|
||||||
assert sz
|
assert sz.namedtuple._fields == ('a', 'b', 'c')
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
StatusZero('a', 'b', 'c', 'd')
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
StatusZero('0')
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
StatusZero('foo', 'hello world')
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
StatusZero('foo', 'foo')
|
||||||
|
|
||||||
def test_statuszero():
|
def test_statuszero():
|
||||||
with StatusZero() as sz:
|
with StatusZero() as sz:
|
||||||
@@ -824,13 +832,21 @@ def test_statuszero_named():
|
|||||||
|
|
||||||
def test_statusboard_init():
|
def test_statusboard_init():
|
||||||
with StatusBoard() as sb:
|
with StatusBoard() as sb:
|
||||||
assert sb
|
assert sb.namedtuple._fields == ('one', 'two', 'three', 'four', 'five')
|
||||||
with StatusBoard('a') as sb:
|
with StatusBoard('a') as sb:
|
||||||
assert sb
|
assert sb.namedtuple._fields == ('a',)
|
||||||
with StatusBoard('a', 'b') as sb:
|
with StatusBoard('a', 'b') as sb:
|
||||||
assert sb
|
assert sb.namedtuple._fields == ('a', 'b',)
|
||||||
with StatusBoard('a', 'b', 'c', 'd', 'e') as sb:
|
with StatusBoard('a', 'b', 'c', 'd', 'e') as sb:
|
||||||
assert sb
|
assert sb.namedtuple._fields == ('a', 'b', 'c', 'd', 'e')
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
StatusBoard('a', 'b', 'c', 'd', 'e', 'f')
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
StatusBoard('0')
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
StatusBoard('foo', 'hello world')
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
StatusBoard('foo', 'foo')
|
||||||
|
|
||||||
def test_statusboard():
|
def test_statusboard():
|
||||||
with StatusBoard() as sb:
|
with StatusBoard() as sb:
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ def test_composite_device_sequence():
|
|||||||
assert len(device) == 2
|
assert len(device) == 2
|
||||||
assert device[0].pin.number == 4
|
assert device[0].pin.number == 4
|
||||||
assert device[1].pin.number == 5
|
assert device[1].pin.number == 5
|
||||||
assert device.namedtuple._fields == ('_0', '_1')
|
assert device.namedtuple._fields == ('device_0', 'device_1')
|
||||||
|
|
||||||
def test_composite_device_values():
|
def test_composite_device_values():
|
||||||
with CompositeDevice(
|
with CompositeDevice(
|
||||||
|
|||||||
Reference in New Issue
Block a user