Skip to content

attr.evolve no longer supports setting an attr object as attribute #804

Closed

Description

@progval

Hi,

I don't know if this is an intentional side-effect of #759, but attr.evolve no longer works in the non-recursive recursive case if the argument is an attr class.

Here is a snippet to reproduce it:

import attr

@attr.s
class Cls1:
    param1 = attr.ib()


@attr.s
class Cls2:
    param2 = attr.ib()


obj2a = Cls2(param2="a")
obj2b = Cls2(param2="b")

obj1a = Cls1(param1=obj2a)
obj1b = attr.evolve(obj1a, param1=obj2b)

print(obj1b)

Before fe6eb31, it printed this: Cls1(param1=Cls2(param2='b'))

But after this commit, it raises this error:

Traceback (most recent call last):
  File "test.py", line 17, in <module>
    obj1b = attr.evolve(obj1a, param1=obj2b)
  File "/home/dev/.local/lib/python3.7/site-packages/attrs-21.2.0.dev0-py3.7.egg/attr/_funcs.py", line 347, in evolve
    changes[init_name] = evolve(value, **changes[init_name])
TypeError: evolve() argument after ** must be a mapping, not Cls2

Thanks!

Activity

  1. changed the title [-]`attr.evolve` no longer supports setting an attr class as attribute[/-] [+]`attr.evolve` no longer supports setting an attr object as attribute[/+] on May 6, 2021
  2. staaam commented on May 6, 2021

    @staaam

    same here. Issue is in attr._funcs.evolve at:

        for a in attrs:
            ...
            elif has(value):
                # Evolve nested attrs classes
                changes[init_name] = evolve(value, **changes[init_name])
    

    value - is old value (param1 from example above)
    changes[init_name] - is new value (obj2b from above)
    but for recursive evolve it should be dict
    probably the best way to make it backward compatible will be to check
    elif has(value) and isinstance(changes[init_name], Mapping):

  3. hynek commented on May 6, 2021

    @hynek
    Member

    Yeah, we'll have to revert #759 and push out 21.2.

    I'm gonna wait a bit with the release to see if there's other breakages that should be fixed.

  4. added a commit that references this issue on May 6, 2021
  5. hynek commented on May 7, 2021

    @hynek
    Member

    21.2 with the fix is on PyPI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions