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

bpo-32214: Implement PEP 557: Data Classes #4704

Merged
merged 4 commits into from
Dec 4, 2017

Conversation

ericvsmith
Copy link
Member

@ericvsmith ericvsmith commented Dec 4, 2017

@ericvsmith ericvsmith changed the title Implement PEP 557: Data Classes bpo-32214 Implement PEP 557: Data Classes Dec 4, 2017
@ericvsmith ericvsmith changed the title bpo-32214 Implement PEP 557: Data Classes bpo-32214: Implement PEP 557: Data Classes Dec 4, 2017
@ericvsmith ericvsmith merged commit f0db54a into python:master Dec 4, 2017
@ericvsmith ericvsmith deleted the bpo-32214-data-classes branch December 4, 2017 21:59
Copy link
Member

@serhiy-storchaka serhiy-storchaka left a 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('
Copy link
Member

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.

Copy link
Member Author

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},'
Copy link
Member

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.

Copy link
Member Author

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},'
Copy link
Member

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.

Copy link
Member Author

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('
Copy link
Member

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.

Copy link
Member Author

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])},)'
Copy link
Member

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.

Copy link
Member Author

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
Copy link
Member

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.

Copy link
Member Author

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,
Copy link
Member

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?

Copy link
Member Author

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))))
Copy link
Member

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
Copy link
Member

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 '
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f?

@ericvsmith
Copy link
Member Author

Thanks for the comments. I'll review the code with these in mind.

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

Successfully merging this pull request may close these issues.

4 participants