-
-
Notifications
You must be signed in to change notification settings - Fork 367
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
Add Attribute.alias #950
Add Attribute.alias #950
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks all very good and thorough, just a bunch of questions and nits.
it also needs a newsfragment. make it sounds excited. :)
sorry for taking so long…whenever Attribute changes the diffs make me wann hide under the bed.
Anything you need from my end? 😇 |
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My turn to apologize for the slow turnaround.
I've applied the review comments, and believe this is ready for a final pass.
w00t! Thanks for coming back! I'll try to be faster this time! :) |
Really appreciate your work on attrs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nailed it a tiny nit aside!
Thank you so much for coming back, I know how difficult it is to pick up something like this after a long time.
Cool. Cattrs will be no problem, I can just bump the dependency to the latest version of attrs and implement it. Mypy will be a bigger issue I think. |
given alias is a dataclass transform feature, shouldn't it work OOB? |
Unsure, Mypy has a custom attrs plugin so I don't know if the dataclass_transform code path is in charge of this. |
Yeah, yeah. But we'd need to release attrs first. |
yeah, it's super overdue too. i'll try to get #1003 in ASAP (it's just an alias, so it should be just busywork) and push it out RSN. |
Since the attrs version release, pub tests have begun failing with the error "TypeError: keywords must be strings". Attrs have added an "alias" parameter to each attribute[1], which is used in the attrs's "evolve" method to construct a new instance. This causes issues with the attribute "from", which has some special logic implemented in order to be usable at all[2]. The attribute "from" is generated from "from_", copying all its parameters. Since "alias" is a new parameter, it isn't copied and thus its value is set no "None". attrs's "evolve" method uses **kwargs to create a new instance, and it sets one of the keys in **kwargs to "None" (from alias). Keys in **kwargs must be strings, which causes the TypeError. It can be fixed by also setting "alias" in the newly created "from" attribute. In case of "from_", it has the same value as "name" parameter ("from_"), which is why we don't want to copy it from the old attribute, but explicitly set it to "from" (otherwise it would be "from_"). The change should be backwards compatible with older versions of attrs. [1] python-attrs/attrs#950 [2] release-engineering#108
Since new attrs version release, pub tests have begun failing with the error "TypeError: keywords must be strings". Attrs have added an "alias" parameter to each attribute[1], which is used in the attrs's "evolve" method to construct a new instance. This causes issues with the attribute "from", which has some special logic implemented in order to be usable at all[2]. The attribute "from" is generated from "from_", copying all its parameters. Since "alias" is a new parameter, it isn't copied and thus its value is set no "None". attrs's "evolve" method uses **kwargs to create a new instance, and it sets one of the keys in **kwargs to "None" (from alias). Keys in **kwargs must be strings, which causes the TypeError. It can be fixed by also setting "alias" in the newly created "from" attribute. In case of "from_", it has the same value as "name" parameter ("from_"), which is why we don't want to copy it from the old attribute, but explicitly set it to "from" (otherwise it would be "from_"). The change should be backwards compatible with older versions of attrs. [1] python-attrs/attrs#950 [2] release-engineering#108
Since new attrs version release, pub tests have begun failing with the error "TypeError: keywords must be strings". Attrs have added an "alias" parameter to each attribute[1], which is used in the attrs's "evolve" method to construct a new instance. This causes issues with the attribute "from", which has some special logic implemented in order to be usable at all[2]. The attribute "from" is generated from "from_", copying all its parameters. Since "alias" is a new parameter, it isn't copied and thus its value is set no "None". attrs's "evolve" method uses **kwargs to create a new instance, and it sets one of the keys in **kwargs to "None" (from alias). Keys in **kwargs must be strings, which causes the TypeError. It can be fixed by also setting "alias" in the newly created "from" attribute. In case of "from_", it has the same value as "name" parameter ("from_"), which is why we don't want to copy it from the old attribute, but explicitly set it to "from" (otherwise it would be "from_"). The change should be backwards compatible with older versions of attrs. [1] python-attrs/attrs#950 [2] release-engineering#108
Summary
PEP681 introduces an optional
alias
parameter to field descriptors, which specifies an alternative__init__
name for the member. This is not implemented in dataclasses, but is implemented in pydantic.Add an explicit & overridable per-attribute
alias
in attrs, mirroring the behavior described in the PEP anddataclass_transform
specification. This allows users to directly address the single largest incompatibility noted in the specification,attrs
private attributes handling, which strips leading underscores from member names, discussed in #795.This feature unblocks implementation of a shim layer to support
attrs
/dataclass
interop, discussed in:closes: #945
closes: #572
Goals:
attrs
not usingalias
. Libraries building onattrs
may usealias
to detect both existing private-name init aliases and user-supplied aliases.alias : Optional[str]
parameter toattr.ib
et al and property toAttribute
.name.lstrip("_")
) into_ClassBuilder
so thatalias
is always populated with the field's__init__
parameter name, regardless of whether an explicit alias is provided, during__init__
rendering andattr.fields
introspection.Attribute.alias
asNone
if not explicitly specified, so thatfield_transformer
implementations can (a) create attributes without needing to be aware ofalias
and optionally providealias
overrides beforeattrs
.attr.evolve
to useAttribute.alias
rather than re-implemented name-mangling.alias
parameter.alias
can be used to inform type checkers of private-name renaming behavior.attrs
noting the inconsistency between documentation and behavior. Dunder-methods are still affected by attr.ibs that will be __name-mangled should be attrs-init-mangled to <name> not ClassName_<name> #619, butevolve
failures in pathological cases are resolved.cattrs
to accessAttribute.alias
during codegen iff available inattrs
: UseAttribute.alias
for init argument names if attrs>= 2022.2 cattrs#322Non-goals:
Pull Request Check List
Our CI fails if coverage is not 100%.
.pyi
).tests/typing_example.py
.attr/__init__.pyi
, they've also been re-imported inattrs/__init__.pyi
.docs/api.rst
by hand.@attr.s()
have to be added by hand too.versionadded
,versionchanged
, ordeprecated
directives.Find the appropriate next version in our
__init__.py
file..rst
files is written using semantic newlines.changelog.d
.