diff --git a/CHANGELOG.md b/CHANGELOG.md index f9f57d74e19c896d7713ce619ce8e166061176ce..218f83ade23663d69884dd6e20530fcf0622dae2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1,3 @@ # v2.15.6 + +* added equality checking and membership test to Optional diff --git a/satella/__init__.py b/satella/__init__.py index a493016be145d735775ab576c0dafc152a1d033d..bfc8e94cc601f7cdac2efc71f63070f472ac5102 100644 --- a/satella/__init__.py +++ b/satella/__init__.py @@ -1 +1 @@ -__version__ = '2.15.6a1' +__version__ = '2.15.6' diff --git a/satella/coding/optionals.py b/satella/coding/optionals.py index 893a16f9f45d66160c422fb3ebc1b5debb100d82..596fe9841f7eff841302155f2467bba3acdf2db4 100644 --- a/satella/coding/optionals.py +++ b/satella/coding/optionals.py @@ -54,12 +54,32 @@ class Optional(Proxy): * getattr * getitem/setitem/delitem * testing for truth + * comparison (with nonexistent elements always comparing false) + * membership test (with nonexistent elements always returning false) + + .. warning:: Returned objects via getattr and getitem are NOT wrapped in an + Optional. You need to do it by hand or just file an issue. I'll add that when I + need it. + + :param obj: object to wrap """ __slots__ = () def __init__(self, obj): super().__init__(obj) + def __contains__(self, item) -> bool: + me = getattr(self, '_Proxy__obj') + if me is None: + return False + return item in me + + def __eq__(self, other) -> bool: + me = getattr(self, '_Proxy__obj') + if me is None: + return False + return me == other + def __getattr__(self, item): if getattr(self, '_Proxy__obj') is None: return EMPTY_OPTIONAL diff --git a/tests/test_coding/test_optionals.py b/tests/test_coding/test_optionals.py index fc7e7be86f2568fda08941f7b93b4c0790e054f3..34e75ce9e0c5280f142ef9e7e49504edf270c9e0 100644 --- a/tests/test_coding/test_optionals.py +++ b/tests/test_coding/test_optionals.py @@ -15,6 +15,17 @@ class TestOptionals(unittest.TestCase): self.assertFalse(c) self.assertTrue(b) + def test_optional_eq(self): + class Opt: + a = 5 + b = [2] + + a = Opt() + self.assertEqual(Optional(a).a, 5) + self.assertIn(2, Optional(a).b) + self.assertNotEqual(Optional(None).a, 5) + self.assertNotIn(2, Optional(None).b) + def test_optional(self): self.assertIsNone(call_if_nnone(None)) b = call_if_nnone(lambda y: y, 5)