Skip to content

Instantly share code, notes, and snippets.

@banesullivan
Created June 7, 2022 19:46
Show Gist options
  • Save banesullivan/c247f7654f9ad5eb9aeefeb5269b24d1 to your computer and use it in GitHub Desktop.
Save banesullivan/c247f7654f9ad5eb9aeefeb5269b24d1 to your computer and use it in GitHub Desktop.
CallableValue: transition a method to a `property` and preserve backward compatibility
import warnings
def CallableValue(value):
typ = type(value)
if typ is bool:
# For bools, we must subclass int
# https://stackoverflow.com/questions/2172189/why-i-cant-extend-bool-in-python
_typ = int
else:
_typ = typ
class _CallableValue(_typ):
"""Value that can be called.
Implemented for backwards compatibility where some methods were
converted to properties.
"""
def __new__(cls, value):
"""Use new instead of __init__."""
if typ is bool:
value = bool(value)
return _typ.__new__(cls, value)
def __call__(self):
"""Return the value of self."""
warnings.warn(
"This is a property and does not need ()",
DeprecationWarning,
)
if typ is bool:
return bool(self)
return self
def __repr__(self):
if typ is bool:
return bool.__repr__(bool(self))
return super().__repr__()
return _CallableValue(value)
from callablevalue import CallableValue
class Foo:
@property
def bool(self):
return CallableValue(True)
@property
def int(self):
return CallableValue(3)
@property
def string(self):
return CallableValue("foo")
@property
def tuple(self):
return CallableValue(("foo", 3))
f = Foo()
assert f.bool == f.bool()
assert f.int == f.int()
assert f.string == f.string()
assert f.tuple == f.tuple()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment