Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

evolve() and attr.ib(init=False, default="foo") #251

Open
hynek opened this issue Sep 25, 2017 · 1 comment
Open

evolve() and attr.ib(init=False, default="foo") #251

hynek opened this issue Sep 25, 2017 · 1 comment
Labels

Comments

@hynek
Copy link
Member

hynek commented Sep 25, 2017

As pointed out in ericvsmith/dataclasses#42 (comment) attr.evolve() behaves rather weird if an attribute has

  1. init=False,
  2. a default/__attrs_post_init__, and
  3. attribute(s) are modified on the instance.

The new resulting object will always have the default value.

I think I can live with that limitation if we document it and it's probably a good reason to resolve #207 with sticking assoc around with a better name?


Giving it further thought, the raison d'être for evolve are immutable objects…so I think it's fine to just document this edge case and leave it be?

@wsanchez wsanchez added the Bug label Sep 11, 2019
@ljluestc
Copy link

import attr

@attr.s
class MyDataClass:
init_value: int = attr.ib(init=False)
default_value: int = attr.ib(default=0)

def __attrs_post_init__(self):
    self.init_value = 42  # Modifying an attribute in __attrs_post_init__

def evolve_example():
original_instance = MyDataClass()
evolved_instance = attr.evolve(original_instance, init_value=100)

return evolved_instance

Documentation for the edge case

print("""
As pointed out in ericvsmith/dataclasses#42 (comment), attr.evolve() behaves in a specific way when an attribute has:

  1. init=False,
  2. a default/attrs_post_init, and
  3. attribute(s) are modified on the instance.

The new resulting object will always have the default value for that attribute. This behavior is because evolve is primarily designed for immutable objects.

Given the nature of evolve and its purpose for immutable objects, it is acceptable to document this edge case and leave it as is.
""")

Example usage of attr.evolve()

evolved_obj = evolve_example()
print(f"Evolved object: {evolved_obj}")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants