Search code examples
pythonpython-3.xpython-attrs

attr.ib ignores value parameter


attr.ib takes a repr argument that may be a bool or callable.

To override how the attribute value is formatted, pass a callable that takes a single value and returns a string. Note that the resulting string is used as-is, i.e. it will be used directly instead of calling repr() (the default).

That does not appear to be the case when passing datetime.datetime.fromisoformat():

import datetime
import attr

@attr.s
class Test(object):
    foo: str = attr.ib()
    dt: datetime.datetime = attr.ib(repr=datetime.datetime.isoformat)

Result:

>>> t = Test(foo='bar', dt=datetime.datetime.utcnow())                                                                                                                                                                                                       
>>> t                                                                                                                                                                                                                                                        
Test(foo='bar', dt=datetime.datetime(2019, 10, 31, 17, 59, 34, 603971))

Expected:

Test(foo='bar', dt='2019-10-31T17:59:34.603971')

In fact, it looks like any parameter is ignored. Here is a slight modification of the example from the attr docs:

>>> @attr.s 
... class C(object): 
...     user = attr.ib() 
...     password = attr.ib(repr=lambda value: value[:2]) 
...                                                                                                                                                                                                                                                          
>>> C("me", "s3kr3t")                                                                                                                                                                                                                                        
C(user='me', password='s3kr3t')

What am I missing here?


Solution

  • Your attrs installation must be too old. Your code works perfectly with attrs 19.3:

    >>> import datetime
    >>> import attr
    >>>
    >>> @attr.s
    ... class Test(object):
    ...     foo: str = attr.ib()
    ...     dt: datetime.datetime = attr.ib(repr=datetime.datetime.isoformat)
    ...
    >>> Test(foo='bar', dt=datetime.datetime.utcnow())
    Test(foo='bar', dt=2019-11-01T05:40:59.745157)
    

    You can check you attrs's version using:

    >>> attr.__version__
    '19.3.0'
    

    The repr feature has been added in 19.2.0 that was released only a month ago on 2019-10-01.