-
-
Notifications
You must be signed in to change notification settings - Fork 374
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
Added support for keyword-only arguments on Python 3+ [rebase] #411
Conversation
closes python-attrs#38 (Rebases python-attrs#281) Co-authored-by: Alex Ford <[email protected]>
Thanks for reviving this! I’ll be at EuroPython for the rest of the week but will take a look once I have the time. You’ve Got a typo in the stubs btw: kw_onlly or something like that (on phone sorry). Other reviewers are invited to pick up my slack of course. ;) |
Great, thanks! Before I start covering my tracks, is |
It’s your repo, do whatever the hell pleases you. We’ll squash at the end anyway. |
Add `kw_only` flag to `attr.s` decorator, indicating that all class attributes should be keyword-only in __init__. Minor updates to internal interface of `Attribute` to support evolution of attributes to `kw_only` in class factory. Expand examples with `attr.s` level kw_only.
Hear ye, hear ye. A duplicate PR is born.
Fixed |
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.
Overall this looks pretty good! I have a bunch of minor things and one major question. :)
docs/examples.rst
Outdated
>>> A(a=1) | ||
A(a=1) | ||
|
||
`kw_only` may also be specified at via ``attr.s``, and will apply to all attributes: |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
docs/examples.rst
Outdated
|
||
|
||
|
||
If you create an attribute with ``init=False``, ``kw_only`` argument is simply ignored. |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
docs/examples.rst
Outdated
... | ||
TypeError: B() missing 1 required keyword-only argument: 'b' | ||
|
||
If you omit ``kw_only`` or specify ``kw_only=False``, then you'll get an error: |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
@@ -206,6 +212,7 @@ def attrib( | |||
converter=converter, | |||
metadata=metadata, | |||
type=type, | |||
kw_only=kw_only, |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/attr/_make.py
Outdated
@@ -736,6 +760,10 @@ def attrs( | |||
Attributes annotated as :data:`typing.ClassVar` are **ignored**. | |||
|
|||
.. _`PEP 526`: https://www.python.org/dev/peps/pep-0526/ | |||
:param bool kw_only: Make all attributes keyword-only (Python 3+) | |||
in the generated ``__init__`` (if ``init`` is ``False``, this | |||
parameter is simply ignored). |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
x = attr.ib(default=None) | ||
y = attr.ib() | ||
|
||
attrs, super_attrs, _ = _transform_attrs(C, None, False, True) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
x = attr.ib(init=False, default=0, kw_only=True) | ||
y = attr.ib() | ||
|
||
c = C(1) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
y = attr.ib() | ||
|
||
with pytest.raises(ValueError) as e: | ||
_transform_attrs(C, None, False, False) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
with pytest.raises(TypeError): | ||
C(0, y=1) | ||
|
||
c = C(x=0, y=1) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
with pytest.raises(TypeError): | ||
C(1) | ||
|
||
c = C(x=0, y=1) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
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.
We’re getting there!
src/attr/_make.py
Outdated
@@ -1558,6 +1613,17 @@ def from_counting_attr(cls, name, ca, type=None): | |||
**inst_dict | |||
) | |||
|
|||
# Don't use attr.evolve since fields(Attribute) doesn't work | |||
def _evolve(self, **changes): |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
if kw_only_args: | ||
if PY2: | ||
raise PythonTooOldError( | ||
"Keyword-only arguments only work on Python 3 and later." |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
class PythonTooOldError(RuntimeError): | ||
""" | ||
An ``attrs`` feature requiring a more recent python version has been used. |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
@attr.s(kw_only=True) | ||
class ClassLevel(object): | ||
a = attr.ib() | ||
|
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
@attr.s() | ||
class AttrLevel(object): | ||
a = attr.ib(kw_only=True) | ||
|
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Thanks everyone! |
this is awesome! thanks @asford for pushing this through! |
This is a rebase-and-extension of pull #281. @malinoff (& @hynek), I'm happy to handle this as a sub-pull of that request or merge independently.
Closes #335, closes #106, closes #38.
Pull Request Check List
This is just a reminder about the most common mistakes. Please make sure that you tick all appropriate boxes. But please read our contribution guide at least once, it will save you unnecessary review cycles!
New features have been added to our Hypothesis testing strategy..pyi
)..rst
files is written using semantic newlines.versionadded
,versionchanged
, ordeprecated
directives.changelog.d
.If you have any questions to any of the points above, just submit and ask! This checklist is here to help you, not to deter you from contributing!