-
-
Notifications
You must be signed in to change notification settings - Fork 31.4k
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
bpo-32214: Implement PEP 557: Data Classes #4704
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.
I didn't follow the discussion about dataclasses, so there are mostly just style comments.
self._field_type = None | ||
|
||
def __repr__(self): | ||
return ('Field(' |
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.
I think it would look better if add the f prefix to the first and the las chunks.
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.
I'm not so concerned about this, and I'll probably rewrite the whole thing, anyway.
|
||
def __repr__(self): | ||
return ('Field(' | ||
f'name={self.name!r},' |
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.
I think with spaces after commas it would look better.
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.
True.
return ('Field(' | ||
f'name={self.name!r},' | ||
f'type={self.type},' | ||
f'default={self.default},' |
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.
If default
can be of arbitrary type, it is better to use a repr. In general case it is safer to use !r
unless the value is a string and should formatted as a raw string. And this is faster.
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.
Thanks.
self._field_type = None | ||
|
||
def __repr__(self): | ||
return ('Field(' |
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.
I think the repr would look better if omit the optional parameters if they equal to the default value.
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.
Good idea.
if len(fields) == 0: | ||
return '()' | ||
# Note the trailing comma, needed if this turns out to be a 1-tuple. | ||
return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)' |
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 would look clearer if extract the internal expression as a variable. With space after comma the result would conform PEP 8. The trailing comma is needed only for a 1-tuple.
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.
I'm not so concerned about this. It's generated code, and I don't particularly care how the generated code looks, as long as it's correct.
|
||
# Include InitVars and regular fields (so, not ClassVars). | ||
_set_attribute(cls, '__init__', | ||
_init_fn(list(filter(lambda f: f._field_type |
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.
Could you please extract the lambda as a local function? This code is too complex.
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.
I'll consider it. These expressions started out much simpler, and grew over time.
|
||
# Get the fields as a list, and include only real fields. This is | ||
# used in all of the following methods. | ||
field_list = list(filter(lambda f: f._field_type is _FIELD, |
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.
Wouldn't the code look clearer if use a list comprehension?
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.
Probably so.
|
||
if repr: | ||
_set_attribute(cls, '__repr__', | ||
_repr_fn(list(filter(lambda f: f.repr, field_list)))) |
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.
The same as above.
generate_hash = hash | ||
if generate_hash: | ||
_set_attribute(cls, '__hash__', | ||
_hash_fn(list(filter(lambda f: f.compare |
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.
Could you please refactor this?
# Error if this field is specified in changes. | ||
if f.name in changes: | ||
raise ValueError(f'field {f.name} is declared with ' | ||
'init=False, it cannot be specified with ' |
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.
f?
Thanks for the comments. I'll review the code with these in mind. |
https://bugs.python.org/issue32214