From 0d100ec7524162b98c9578cb685efdc76135f8dd Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Wed, 31 Jan 2024 10:46:30 -0500 Subject: [PATCH] thread: Create a generic Data class This class is desigend to make it easier to pass data to and from a running Thread. This was inspired by the types.SimpleNamespace object so we can set generic values and use them as class members. Signed-off-by: Anna Schumaker --- emmental/thread.py | 23 +++++++++++++++++++++++ tests/test_thread.py | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 emmental/thread.py create mode 100644 tests/test_thread.py diff --git a/emmental/thread.py b/emmental/thread.py new file mode 100644 index 0000000..589733f --- /dev/null +++ b/emmental/thread.py @@ -0,0 +1,23 @@ +# Copyright 2024 (c) Anna Schumaker. +"""A Thread class designed to easily sync up with the main thread.""" + + +class Data: + """A class for holding generic fields inspired by SimpleNamespace.""" + + def __init__(self, values_dict: dict = {}, **kwargs): + """Initialize our Data class.""" + self.__dict__.update(values_dict | kwargs) + + def __eq__(self, rhs: any) -> bool: + """Compare two Data classes.""" + if isinstance(rhs, Data): + return self.__dict__ == rhs.__dict__ + elif isinstance(rhs, dict): + return self.__dict__ == rhs + return False + + def __repr__(self) -> str: + """Get a string representation of the Data.""" + items = (f"{k}={v!r}" for k, v in self.__dict__.items()) + return f"{type(self).__name__}({', '.join(items)})" diff --git a/tests/test_thread.py b/tests/test_thread.py new file mode 100644 index 0000000..5a8dc66 --- /dev/null +++ b/tests/test_thread.py @@ -0,0 +1,40 @@ +# Copyright 2024 (c) Anna Schumaker. +"""Tests our common Thread class.""" +import emmental.thread +import unittest + + +class TestData(unittest.TestCase): + """Tests our thread Data class.""" + + def test_init_kwargs(self): + """Tests initializing the data class with keyword args.""" + data = emmental.thread.Data(a=1, b=2) + self.assertEqual(data.a, 1) + self.assertEqual(data.b, 2) + self.assertEqual(repr(data), "Data(a=1, b=2)") + + def test_init_values_dict(self): + """Test initializing the data class with a dictionary of values.""" + data = emmental.thread.Data({"a": 1, "b": 2}) + self.assertEqual(data.a, 1) + self.assertEqual(data.b, 2) + self.assertEqual(repr(data), "Data(a=1, b=2)") + + def test_init_both(self): + """Test initializing the data class with both.""" + data = emmental.thread.Data({"a": 1, "b": 2}, b=3, c='4') + self.assertEqual(data.a, 1) + self.assertEqual(data.b, 3) + self.assertEqual(data.c, '4') + self.assertEqual(repr(data), "Data(a=1, b=3, c='4')") + + def test_compare(self): + """Test comparing two data classes.""" + data1 = emmental.thread.Data({"a": 1, "b": 2}) + data2 = emmental.thread.Data({"c": 3, "d": 4}) + self.assertTrue(data1 == data1) + self.assertTrue(data1 == {"a": 1, "b": 2}) + self.assertFalse(data1 == data2) + self.assertFalse(data1 == {"c": 2, "d": 4}) + self.assertFalse(data1 == 3)