diff options
author | Matt McDonald <mmcdonald@google.com> | 2020-10-22 08:09:22 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2020-10-22 08:09:45 -0700 |
commit | 065fbf8b97b55e7498a33f445f2f8296d46ca73b (patch) | |
tree | ce7b8df6151ee743a033bab2d201f3381f5712b7 /absl/flags | |
parent | 9a0552c6743d387df6ab565f8ccb9878dd14ece4 (diff) | |
download | absl-py-065fbf8b97b55e7498a33f445f2f8296d46ca73b.tar.gz |
Surface inappropriate usage of a `FlagHolder` object as a runtime error
With the aim of steering users away from potential pitfalls in usage of the `FlagHolder` API, this change introduces implementation overrides for the class `__eq__` and `__bool__` methods which turn any such usage into a `TypeError` at runtime.
This is to help avoid situations where a user neglects to use the `FlagHolder.value` property in cases where they intended to, e.g.,
```
>>> SOME_FLAG = flags.DEFINE_boolean(...)
>>> if SOME_FLAG: do_something()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bool() not supported for instances of type 'FlagHolder' (did you mean to use 'FlagHolder.value' instead?)
```
PiperOrigin-RevId: 338473759
Change-Id: If3b6505a3bdca03db6d96ec7cc28e7214cb1a5e7
Diffstat (limited to 'absl/flags')
-rw-r--r-- | absl/flags/_flagvalues.py | 14 | ||||
-rw-r--r-- | absl/flags/tests/_flagvalues_test.py | 12 |
2 files changed, 26 insertions, 0 deletions
diff --git a/absl/flags/_flagvalues.py b/absl/flags/_flagvalues.py index c6a209f..2a13927 100644 --- a/absl/flags/_flagvalues.py +++ b/absl/flags/_flagvalues.py @@ -1357,6 +1357,20 @@ class FlagHolder(_Base): # This allows future use of this for "required flags with None default" self._ensure_non_none_value = ensure_non_none_value + def __eq__(self, other): + raise TypeError( + "unsupported operand type(s) for ==: '{0}' and '{1}' " + "(did you mean to use '{0}.value' instead?)".format( + type(self).__name__, type(other).__name__)) + + def __bool__(self): + raise TypeError( + "bool() not supported for instances of type '{0}' " + "(did you mean to use '{0}.value' instead?)".format( + type(self).__name__)) + + __nonzero__ = __bool__ + @property def name(self): return self._name diff --git a/absl/flags/tests/_flagvalues_test.py b/absl/flags/tests/_flagvalues_test.py index ed446f8..8d3df2a 100644 --- a/absl/flags/tests/_flagvalues_test.py +++ b/absl/flags/tests/_flagvalues_test.py @@ -914,6 +914,18 @@ class FlagHolderTest(absltest.TestCase): self.assertEqual(3, first.value) self.assertEqual(3, second.value) + def test_eq(self): + with self.assertRaises(TypeError): + self.name_flag == 'value' # pylint: disable=pointless-statement + + def test_eq_reflection(self): + with self.assertRaises(TypeError): + 'value' == self.name_flag # pylint: disable=pointless-statement + + def test_bool(self): + with self.assertRaises(TypeError): + bool(self.name_flag) + if __name__ == '__main__': absltest.main() |