Commits (5)
[bumpversion]
current_version = 0.1.0
current_version = 0.1.1
commit = True
tag = True
......
......@@ -15,9 +15,9 @@ frequently needs.
```python
from class_tools.decorators import has_property
@has_property("name", default="Bob", doc="The dog's name")
@has_property("toy", default="ball")
@has_property("sharp_teeth", default=4, type=int)
@has_property("name", default=lambda: "Bob", doc="The dog's name")
@has_property("toy", default=lambda: "ball")
@has_property("sharp_teeth", default=lambda: 4, type=int)
class Dog:
pass
......@@ -86,7 +86,7 @@ from class_tools.decorators import has_property
@has_property("name")
@has_property("height", type=float)
@has_property("friends", type=list, default=[])
@has_property("friends", type=list, default=list)
class Giraffe(PropertyObject):
pass
......@@ -96,13 +96,13 @@ gunther = Giraffe(name="Gunther")
gunther.friends.append(matt)
gunther
# Giraffe(
# friends = [Giraffe(
# friends = [...],
# height = 3.0,
# name = 'Matt'
# )],
# height = None,
# name = 'Gunther'
# friends=[Giraffe(
# friends=[],
# height=3.0,
# name='Matt'
# )],
# height=None,
# name='Gunther'
# )
```
......
......@@ -2,6 +2,7 @@
import textwrap
import warnings
import functools
import re
# internal modules
from class_tools.utils import *
......@@ -36,8 +37,8 @@ def has_property(
name,
type=None,
type_doc=None,
default=None,
set_default=False,
default=lambda: None,
set_default=True,
prefix="_",
doc=None,
):
......@@ -50,12 +51,11 @@ def has_property(
type (callable, optional): method to transform given values in the
setter with. The default is to just pass the given value.
type_doc (str, optional): the documentation of the property's type
default (object, optional): the default value for the property. Default
is ``None``.
default (callable, optional): Callable returning the default value
for the property. The default just returns ``None``.
set_default (bool, optional): whether to set the underlying attribute
default to the default if necessary. The default is ``False`` which
means to return the default without setting the attribute if
requested.
default to the default if necessary. The default is ``True`` which
means to do so.
prefix (str, optional): the prefix for the underlying attribute
Returns:
......@@ -71,10 +71,10 @@ def has_property(
try:
return getattr(self, attr)
except AttributeError:
setattr(self, attr, default)
setattr(self, attr, default())
return getattr(self, attr)
else:
return getattr(self, attr, default)
return getattr(self, attr, default())
proptype = (lambda x: x) if type is None else type
......@@ -106,12 +106,12 @@ def has_property(
getter=(
"If no value was set yet, "
"set it to ``{default}`` and return it."
).format(default=repr(default))
).format(default=repr(default()))
if set_default
else (
"If a value was set yet, return it. "
" Otherwise return the default value ``{default}``."
).format(default=repr(default)),
).format(default=repr(default())),
setter=("Convert the given value with ``{type_doc}``").format(
type_doc=type_doc_str
),
......@@ -194,8 +194,13 @@ def with_repr_like_init_from_properties(indent=" " * 4, full_path=False):
map(
functools.partial(textwrap.indent, prefix=indent),
map(
lambda p: "{p} = {{{p}}}".format(p=p),
sorted(properties),
lambda pv: "{p}={v}".format(
p=pv[0],
v=re.sub(
"\n", indent + "\n", repr(pv[1].fget(self))
),
),
sorted(properties.items()),
),
)
)
......
__version__ = "0.1.0"
__version__ = "0.1.1"
......@@ -52,7 +52,7 @@ class HasPropertyDecoratorTest(unittest.TestCase):
for name, prefix, default, set_default in itertools.product(
("prop", "_otherprop"),
("_", "__", "asdf"),
(5, "asdf", None),
(lambda: 5, lambda: "asdf", lambda: None, str, int, list),
(True, False),
):
with self.subTest(
......@@ -81,10 +81,12 @@ class HasPropertyDecoratorTest(unittest.TestCase):
v = getattr(obj, name)
self.assertEqual(
v,
default,
default(),
"Instead of the default value {}, "
"the property returns {}".format(repr(default), repr(v)),
"the property returns {}".format(repr(default()), repr(v)),
)
if default is list:
self.assertIsNot(v, default())
(self.assertTrue if set_default else self.assertFalse)(
hasattr(obj, attr),
"despite set_default={}, "
......