(continuing from https://github.com/python-attrs/attrs/issues/170 which I don't want to derail)
I have a class like this:
@attr.s(frozen=True, auto_attribs=True)
class Status:
weight: int = attr.ib(cmp=True)
message: str = attr.ib(
cmp=False,
converter=lambda value: str() if value is None else value,
)
code: str = attr.ib(
cmp=False,
converter=lambda value: str() if value is None else value,
)
@classmethod
def Debug(cls, message=None, code=None):
return cls(weight=0, message=message, code=code)
[...]
@classmethod
def Error(cls, message=None, code=None):
return cls(weight=6, message=message, code=code)
It can be instantiated like this: Status.Error("This and that is wrong etc.", code="mismatched-something"). However, instantiating it like Status.Error() should result in Status(weight=6, message="", code=""), i.e. I want to avoid None objects. Python unfortunately makes it more tedious than it should be to give out non-None default arguments.
@hynek noted that I may want to use default="" and use attr.NOTHING as the default argument in the constructors, however:
In [1]: import attr
...: @attr.s
...: class Status:
...: a = attr.ib(default="")
...: @classmethod
...: def aaa(cls, a=attr.NOTHING):
...: return cls(a)
...:
In [2]: Status.aaa()
Out[2]: Status(a=NOTHING)
In [3]: Status.aaa("")
Out[3]: Status(a='')
In [4]: import attr
...: @attr.s
...: class Status:
...: a = attr.ib(default="")
...: @classmethod
...: def aaa(cls, a=None):
...: return cls(a=a or attr.NOTHING)
In [5]: Status.aaa()
Out[5]: Status(a=NOTHING)
(I suppose I can use def aaa(cls, a=""): here because strings are immutable, but I'd like to know about a more general approach.)
Ugh right the NOTHING way doesn鈥檛 work because attrs uses literal "" as default parameters if possible.
I guess what could be done is some kind of attr.converters.default_if_none(default=NOTHING, factory=None) so you could write attr.converters.default_if_none(default="") or attr.converters.default_if_none(factory=list). I think I had uses for that too before. 馃
Most helpful comment
I guess what could be done is some kind of
attr.converters.default_if_none(default=NOTHING, factory=None)so you could writeattr.converters.default_if_none(default="")orattr.converters.default_if_none(factory=list). I think I had uses for that too before. 馃