• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nocarryr / tslumd / 7388595068

02 Jan 2024 05:18PM UTC coverage: 94.411%. First build
7388595068

push

github

nocarryr
Run doctest in separate pytest invocation

929 of 984 relevant lines covered (94.41%)

4.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.61
/src/tslumd/common.py
1
from __future__ import annotations
5✔
2
import enum
5✔
3
from typing import Tuple, Iterator
5✔
4

5
__all__ = ('TallyColor', 'TallyType', 'TallyState', 'MessageType', 'TallyKey')
5✔
6

7
class TallyColor(enum.IntFlag):
5✔
8
    """Color enum for tally indicators
9

10
    Since this is an :class:`~enum.IntFlag`, its members can be combined using
11
    bitwise operators, making :attr:`AMBER` a combination of
12
    :attr:`RED` and :attr:`GREEN`
13

14
    This allows merging one color with another
15

16
    >>> from tslumd import TallyColor
17
    >>> TallyColor.RED
18
    <TallyColor.RED: 1>
19
    >>> TallyColor.GREEN
20
    <TallyColor.GREEN: 2>
21
    >>> TallyColor.AMBER
22
    <TallyColor.AMBER: 3>
23
    >>> TallyColor.RED | TallyColor.GREEN
24
    <TallyColor.AMBER: 3>
25

26

27
    .. versionchanged:: 0.0.4
28
        Bitwise operators
29
    """
30
    OFF = 0             #: Off
5✔
31
    RED = 1             #: Red
5✔
32
    GREEN = 2           #: Green
5✔
33
    AMBER = RED | GREEN #: Amber
5✔
34

35
    @staticmethod
5✔
36
    def from_str(s: str) -> TallyColor:
4✔
37
        """Return the member matching the given name (case-insensitive)
38

39
        >>> TallyColor.from_str('RED')
40
        <TallyColor.RED: 1>
41
        >>> TallyColor.from_str('green')
42
        <TallyColor.GREEN: 2>
43
        >>> TallyColor.from_str('Amber')
44
        <TallyColor.AMBER: 3>
45

46
        .. versionadded:: 0.0.5
47
        """
48
        return getattr(TallyColor, s.upper())
5✔
49

50
    def to_str(self) -> str:
5✔
51
        """The member name as a string
52

53
        >>> TallyColor.RED.to_str()
54
        'RED'
55
        >>> TallyColor.GREEN.to_str()
56
        'GREEN'
57
        >>> TallyColor.AMBER.to_str()
58
        'AMBER'
59
        >>> (TallyColor.RED | TallyColor.GREEN).to_str()
60
        'AMBER'
61

62
        .. versionadded:: 0.0.5
63
        """
64
        return self.name
5✔
65

66
    def __str__(self):
5✔
67
        return self.name
5✔
68

69
    @classmethod
5✔
70
    def all(cls):
4✔
71
        """Iterate over all members
72

73
        .. versionadded:: 0.0.6
74
        """
75
        yield from cls.__members__.values()
5✔
76

77
    def __format__(self, format_spec):
5✔
78
        if format_spec == '':
5✔
79
            return str(self)
5✔
80
        return super().__format__(format_spec)
×
81

82
class TallyType(enum.IntFlag):
5✔
83
    """Enum for the three tally display types in the UMD protocol
84

85
    Since this is an :class:`~enum.IntFlag`, its members can be combined using
86
    bitwise operators. The members can then be iterated over to retrieve the
87
    individual "concrete" values of :attr:`rh_tally`, :attr:`txt_tally`
88
    and :attr:`lh_tally`
89

90
    >>> from tslumd import TallyType
91
    >>> list(TallyType.rh_tally)
92
    [<TallyType.rh_tally: 1>]
93
    >>> list(TallyType.rh_tally | TallyType.txt_tally)
94
    [<TallyType.rh_tally: 1>, <TallyType.txt_tally: 2>]
95
    >>> list(TallyType.all_tally)
96
    [<TallyType.rh_tally: 1>, <TallyType.txt_tally: 2>, <TallyType.lh_tally: 4>]
97

98
    .. versionchanged:: 0.0.4
99
        Added support for bitwise operators and member iteration
100
    """
101
    no_tally = 0  #: No-op
5✔
102
    rh_tally = 1  #: :term:`Right-hand tally <rh_tally>`
5✔
103
    txt_tally = 2 #: :term:`Text tally <txt_tally>`
5✔
104
    lh_tally = 4  #: :term:`Left-hand tally <lh_tally>`
5✔
105
    all_tally = rh_tally | txt_tally | lh_tally
5✔
106
    """Combination of all tally types
2✔
107

108
    .. versionadded:: 0.0.4
109
    """
110

111
    @property
5✔
112
    def is_iterable(self) -> bool:
4✔
113
        """Returns ``True`` if this is a combination of multiple members
114

115
        (meaning it must be iterated over)
116

117
        .. versionadded:: 0.0.5
118
        """
119
        if self == TallyType.all_tally:
5✔
120
            return True
5✔
121
        mask = 1 << (self.bit_length() - 1)
5✔
122
        return self ^ mask != 0
5✔
123

124

125
    @classmethod
5✔
126
    def all(cls) -> Iterator[TallyType]:
4✔
127
        """Iterate over all members, excluding :attr:`no_tally` and :attr:`all_tally`
128

129
        .. versionadded:: 0.0.4
130
        """
131
        for ttype in cls:
5✔
132
            if ttype != TallyType.no_tally and ttype != TallyType.all_tally:
5✔
133
                yield ttype
5✔
134

135
    @staticmethod
5✔
136
    def from_str(s: str) -> TallyType:
4✔
137
        """Create an instance from a string of member name(s)
138

139
        The string can be a single member or multiple member names separated by
140
        a "|". For convenience, the names may be shortened by omitting the
141
        ``"_tally"`` portion from the end ("rh" == "rh_tally", etc)
142

143
        >>> TallyType.from_str('rh_tally')
144
        <TallyType.rh_tally: 1>
145
        >>> TallyType.from_str('rh|txt_tally')
146
        <TallyType.rh_tally|txt_tally: 3>
147
        >>> TallyType.from_str('rh|txt|lh')
148
        <TallyType.all_tally: 7>
149
        >>> TallyType.from_str('all')
150
        <TallyType.all_tally: 7>
151

152
        .. versionadded:: 0.0.5
153
        """
154
        if '|' in s:
5✔
155
            result = TallyType.no_tally
5✔
156
            for name in s.split('|'):
5✔
157
                result |= TallyType.from_str(name)
5✔
158
            return result
5✔
159
        s = s.lower()
5✔
160
        if not s.endswith('_tally'):
5✔
161
            s = f'{s}_tally'
5✔
162
        return getattr(TallyType, s)
5✔
163

164
    def to_str(self) -> str:
5✔
165
        """Create a string representation suitable for use in :meth:`from_str`
166

167
        >>> tt = TallyType.rh_tally
168
        >>> tt.to_str()
169
        'rh_tally'
170
        >>> tt |= TallyType.txt_tally
171
        >>> tt.to_str()
172
        'rh_tally|txt_tally'
173
        >>> tt |= TallyType.lh_tally
174
        >>> tt.to_str()
175
        'all_tally'
176

177
        .. versionadded:: 0.0.5
178
        """
179
        if self == TallyType.all_tally:
5✔
180
            return self.name
5✔
181
        if self.is_iterable:
5✔
182
            return '|'.join((obj.name for obj in self))
5✔
183
        return self.name
5✔
184

185
    def __iter__(self) -> Iterator[TallyType]:
5✔
186
        for ttype in self.all():
5✔
187
            if ttype in self:
5✔
188
                yield ttype
5✔
189

190
    def __repr__(self):
191
        return f'<{self.__class__.__name__}.{self.to_str()}: {self.value}>'
192

193

194
class TallyState(enum.IntFlag):
5✔
195
    OFF = 0     #: Off
5✔
196
    PREVIEW = 1 #: Preview
5✔
197
    PROGRAM = 2 #: Program
5✔
198

199
class MessageType(enum.Enum):
5✔
200
    """Message type
201

202
    .. versionadded:: 0.0.2
203
    """
204
    _unset = 0
5✔
205
    display = 1 #: A message containing tally display information
5✔
206
    control = 2 #: A message containing control data
5✔
207

208
TallyKey = Tuple[int, int]
5✔
209
"""A tuple of (:attr:`screen_index <.Screen.index>`,
5✔
210
:attr:`tally_index <.Tally.index>`) to uniquely identify a single :class:`.Tally`
211
within its :class:`.Screen`
212
"""
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc