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,5 +1,7 @@
1 1
 """Python bindings for PD Buddy Sink configuration"""
2 2
 
3
+from collections import namedtuple
4
+
3 5
 try:
4 6
     # Try importing enum from the standard library
5 7
     import enum
@@ -210,46 +212,14 @@ class Sink:
210 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 224
     def __str__(self):
255 225
         """Print the SinkStatus in the manner of the configuration shell"""
@@ -286,27 +256,6 @@ class SinkConfig:
286 256
         else:
287 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 259
     @classmethod
311 260
     def from_text(cls, text):
312 261
         """Creates a SinkConfig from text returned by Sink.send_command
@@ -330,7 +279,7 @@ class SinkConfig:
330 279
                 raise IndexError("configuration index out of range")
331 280
             # If there is no configuration, return an empty SinkConfig
332 281
             elif line.startswith(b"No configuration"):
333
-                return cls()
282
+                return cls(None, None, None, None)
334 283
             # If this line is the status field
335 284
             elif line.startswith(b"status: "):
336 285
                 line = line.split()[1:]

+ 12
- 7
test_pdbuddy/__init__.py View File

@@ -117,8 +117,10 @@ class SinkTestCase(unittest.TestCase):
117 117
 class SinkConfigTestCase(unittest.TestCase):
118 118
 
119 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 124
         self.obj_valid = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
123 125
                 flags=pdbuddy.SinkFlags.NONE, v=15000, i=3000)
124 126
         self.obj_invalid = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.INVALID,
@@ -157,11 +159,12 @@ class SinkConfigTestCase(unittest.TestCase):
157 159
                 "status: valid\nflags: (none)\nv: 15.00 V\ni: 1.00 A")
158 160
 
159 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 165
     def test_eq_valid(self):
163 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 169
         self.assertTrue(self.obj_valid == self.obj_invalid)
167 170
 
@@ -181,11 +184,12 @@ class SinkConfigTestCase(unittest.TestCase):
181 184
         self.assertFalse(self.obj_valid == self.obj_valid_1a)
182 185
 
183 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 190
     def test_ne_valid(self):
187 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 194
         self.assertFalse(self.obj_valid != self.obj_invalid)
191 195
 
@@ -196,7 +200,8 @@ class SinkConfigTestCase(unittest.TestCase):
196 200
         self.assertTrue(self.obj_valid != self.obj_invalid)
197 201
 
198 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 206
     def test_hash_different(self):
202 207
         self.assertNotEqual(hash(self.obj_none), hash(self.obj_valid))

Loading…
Cancel
Save