Browse Source

Made SinkConfig a collections.namedtuple

Since it's a class used for little more than storage, with no
interesting non-magic instance methods, it makes sense for SinkConfig to
be a namedtuple.  The rest of its code was mostly just boilerplate,
after all.  What remains makes it do everything we need with only slight
changes to its behavior (most notably, SinkConfig must be instantiated
with all its arguments now).
Clara Hobbs 6 years ago
parent
commit
af836b08d0
2 changed files with 22 additions and 68 deletions
  1. 10
    61
      pdbuddy/__init__.py
  2. 12
    7
      test_pdbuddy/__init__.py

+ 10
- 61
pdbuddy/__init__.py View File

1
 """Python bindings for PD Buddy Sink configuration"""
1
 """Python bindings for PD Buddy Sink configuration"""
2
 
2
 
3
+from collections import namedtuple
4
+
3
 try:
5
 try:
4
     # Try importing enum from the standard library
6
     # Try importing enum from the standard library
5
     import enum
7
     import enum
210
             cls.pid))
212
             cls.pid))
211
 
213
 
212
 
214
 
213
-class SinkConfig:
214
-    """Python representation of a PD Buddy Sink configuration object"""
215
-
216
-    def __init__(self, status=None, flags=None, v=None, i=None):
217
-        """Create a SinkConfig object
218
-        
219
-        :param status: A `SinkStatus` value
220
-        :param flags: Zero or more `SinkFlags` values
221
-        :param v: Voltage in millivolts
222
-        :param i: Current in milliamperes
223
-        """
224
-        self.status = status
225
-        self.flags = flags
226
-        self.v = v
227
-        self.i = i
228
-
229
-    def __repr__(self):
230
-        s = self.__class__.__name__ + "("
215
+class SinkConfig(namedtuple("SinkConfig", "status flags v i")):
216
+    """Python representation of a PD Buddy Sink configuration object
231
 
217
 
232
-        if self.status is not None:
233
-            s += "status={}".format(self.status)
234
-
235
-        if self.flags is not None:
236
-            if not s.endswith("("):
237
-                s += ", "
238
-            s += "flags={}".format(self.flags)
239
-
240
-        if self.v is not None:
241
-            if not s.endswith("("):
242
-                s += ", "
243
-            s += "v={}".format(self.v)
244
-
245
-        if self.i is not None:
246
-            if not s.endswith("("):
247
-                s += ", "
248
-            s += "i={}".format(self.i)
249
-
250
-        s += ")"
251
-
252
-        return s
218
+    ``status`` should be a `SinkStatus` object.  ``flags`` should be zero or
219
+    more `SinkFlags` values.  ``v`` is the voltage in millivolts, and ``i``
220
+    is the current in milliamperes.  `None` is also an acceptible value for
221
+    any of the fields."""
222
+    __slots__ = ()
253
 
223
 
254
     def __str__(self):
224
     def __str__(self):
255
         """Print the SinkStatus in the manner of the configuration shell"""
225
         """Print the SinkStatus in the manner of the configuration shell"""
286
         else:
256
         else:
287
             return "No configuration"
257
             return "No configuration"
288
 
258
 
289
-    def __eq__(self, other):
290
-        if isinstance(other, self.__class__):
291
-            if other.status is not self.status:
292
-                return False
293
-            if other.flags is not self.flags:
294
-                return False
295
-            if other.v != self.v:
296
-                return False
297
-            if other.i != self.i:
298
-                return False
299
-            return True
300
-        return NotImplemented
301
-
302
-    def __ne__(self, other):
303
-        if isinstance(other, self.__class__):
304
-            return not self.__eq__(other)
305
-        return NotImplemented
306
-
307
-    def __hash__(self):
308
-        return hash(tuple(sorted(self.__dict__.items())))
309
-
310
     @classmethod
259
     @classmethod
311
     def from_text(cls, text):
260
     def from_text(cls, text):
312
         """Creates a SinkConfig from text returned by Sink.send_command
261
         """Creates a SinkConfig from text returned by Sink.send_command
330
                 raise IndexError("configuration index out of range")
279
                 raise IndexError("configuration index out of range")
331
             # If there is no configuration, return an empty SinkConfig
280
             # If there is no configuration, return an empty SinkConfig
332
             elif line.startswith(b"No configuration"):
281
             elif line.startswith(b"No configuration"):
333
-                return cls()
282
+                return cls(None, None, None, None)
334
             # If this line is the status field
283
             # If this line is the status field
335
             elif line.startswith(b"status: "):
284
             elif line.startswith(b"status: "):
336
                 line = line.split()[1:]
285
                 line = line.split()[1:]

+ 12
- 7
test_pdbuddy/__init__.py View File

117
 class SinkConfigTestCase(unittest.TestCase):
117
 class SinkConfigTestCase(unittest.TestCase):
118
 
118
 
119
     def setUp(self):
119
     def setUp(self):
120
-        self.obj_none = pdbuddy.SinkConfig()
121
-        self.obj_empty = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.EMPTY)
120
+        self.obj_none = pdbuddy.SinkConfig(status=None, flags=None, v=None,
121
+                i=None)
122
+        self.obj_empty = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.EMPTY,
123
+                flags=None, v=None, i=None)
122
         self.obj_valid = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
124
         self.obj_valid = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
123
                 flags=pdbuddy.SinkFlags.NONE, v=15000, i=3000)
125
                 flags=pdbuddy.SinkFlags.NONE, v=15000, i=3000)
124
         self.obj_invalid = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.INVALID,
126
         self.obj_invalid = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.INVALID,
157
                 "status: valid\nflags: (none)\nv: 15.00 V\ni: 1.00 A")
159
                 "status: valid\nflags: (none)\nv: 15.00 V\ni: 1.00 A")
158
 
160
 
159
     def test_eq_none(self):
161
     def test_eq_none(self):
160
-        self.assertTrue(self.obj_none == pdbuddy.SinkConfig())
162
+        self.assertTrue(self.obj_none == pdbuddy.SinkConfig(None, None, None,
163
+            None))
161
 
164
 
162
     def test_eq_valid(self):
165
     def test_eq_valid(self):
163
         # Set invalid object as valid
166
         # Set invalid object as valid
164
-        self.obj_invalid.status = pdbuddy.SinkStatus.VALID
167
+        self.obj_invalid = self.obj_invalid._replace(status=pdbuddy.SinkStatus.VALID)
165
 
168
 
166
         self.assertTrue(self.obj_valid == self.obj_invalid)
169
         self.assertTrue(self.obj_valid == self.obj_invalid)
167
 
170
 
181
         self.assertFalse(self.obj_valid == self.obj_valid_1a)
184
         self.assertFalse(self.obj_valid == self.obj_valid_1a)
182
 
185
 
183
     def test_ne_none(self):
186
     def test_ne_none(self):
184
-        self.assertFalse(self.obj_none != pdbuddy.SinkConfig())
187
+        self.assertFalse(self.obj_none != pdbuddy.SinkConfig(None, None, None,
188
+            None))
185
 
189
 
186
     def test_ne_valid(self):
190
     def test_ne_valid(self):
187
         # Set invalid object as valid
191
         # Set invalid object as valid
188
-        self.obj_invalid.status = pdbuddy.SinkStatus.VALID
192
+        self.obj_invalid = self.obj_invalid._replace(status=pdbuddy.SinkStatus.VALID)
189
 
193
 
190
         self.assertFalse(self.obj_valid != self.obj_invalid)
194
         self.assertFalse(self.obj_valid != self.obj_invalid)
191
 
195
 
196
         self.assertTrue(self.obj_valid != self.obj_invalid)
200
         self.assertTrue(self.obj_valid != self.obj_invalid)
197
 
201
 
198
     def test_hash_identical(self):
202
     def test_hash_identical(self):
199
-        self.assertEqual(hash(self.obj_none), hash(pdbuddy.SinkConfig()))
203
+        self.assertEqual(hash(self.obj_none), hash(pdbuddy.SinkConfig(None,
204
+            None, None, None)))
200
 
205
 
201
     def test_hash_different(self):
206
     def test_hash_different(self):
202
         self.assertNotEqual(hash(self.obj_none), hash(self.obj_valid))
207
         self.assertNotEqual(hash(self.obj_none), hash(self.obj_valid))

Loading…
Cancel
Save