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

Make evolve 1st arg positional-only #1109

Closed
ikonst opened this issue Mar 2, 2023 · 4 comments · Fixed by #1117
Closed

Make evolve 1st arg positional-only #1109

ikonst opened this issue Mar 2, 2023 · 4 comments · Fixed by #1117
Labels

Comments

@ikonst
Copy link

ikonst commented Mar 2, 2023

It's arbitrary that the 1st argument is named inst and could conflict with a field.

Since PEP-570 positional-only arguments require Python 3.8 and next major version will be ≥ Python 3.7, we can do it the old-fashion way in the next breaking version (as this is an API change), i.e.

def evolve(*args, **changes):
  (inst,) = args
  ...
@hynek hynek assigned hynek and unassigned hynek Mar 11, 2023
@hynek hynek added the Feature label Mar 11, 2023
@hynek
Copy link
Member

hynek commented Mar 11, 2023

Wow that's gross :D – I wonder if that's possible to express for typing? It would probably break some people who passed it as keyword arguments… 🤔

@ikonst
Copy link
Author

ikonst commented Mar 11, 2023

attrs has type stubs so the way it looks to typing can be modern w/PEP-570.

Also, recently I've merged python/mypy#14526 where you can provide the instance only positionally, so in attrs it will be positional only from the next release due to plugin code.

@ikonst
Copy link
Author

ikonst commented Mar 11, 2023

Dataclasses did something similar, albeit with warning and not a breaking change. Maybe we want to do the same: https://bugs.python.org/issue37163

@hynek
Copy link
Member

hynek commented Mar 30, 2023

FWIW, they did break later as announced in the issue:

In [2]: dataclasses.replace?
Signature: dataclasses.replace(obj, /, **changes)
Docstring:
Return a new object replacing specified fields with new values.

This is especially useful for frozen classes.  Example usage::

  @dataclass(frozen=True)
  class C:
      x: int
      y: int

  c = C(1, 2)
  c1 = replace(c, x=3)
  assert c1.x == 3 and c1.y == 2
File:      /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py
Type:      function

guess we could warn now and break in a year.

hynek added a commit that referenced this issue Apr 5, 2023
…1117)

* Raise a deprecation warning when evolve receives insta as a kw arg

Fixes #1109

* Add news fragment

* Raise a better error

* Handle too many pos args

* Lazy import

* Trim traceback

* Add test evolving a field named inst

* Spelling

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

Successfully merging a pull request may close this issue.

2 participants