Skip to content
/ django Public

Fixed #28198 -- Prevented model attributes from overriding deferred fields.#9126

Closed
denys-tarykin wants to merge 1 commit intodjango:masterfrom
denys-tarykin:fixed_dublicated_attributes
Closed

Fixed #28198 -- Prevented model attributes from overriding deferred fields.#9126
denys-tarykin wants to merge 1 commit intodjango:masterfrom
denys-tarykin:fixed_dublicated_attributes

Conversation

@denys-tarykin
Copy link
Copy Markdown

Attributes from parent classes will not overload attributes in child classes. During model creation process, attributes which are dublicated in parent and child classes will be removed. That attributes will restored for all parent classes after model creation process

@denys-tarykin
Copy link
Copy Markdown
Author

Hi. Can you help me with checking of my pull request? Most of tests are failed. But in the logs I see that unit tests are was not started because of jgit exception

@timgraham
Copy link
Copy Markdown
Member

If you amend your commit and push it to the branch, it should trigger the build again. You'll need to add a regression test anyway.

@ryanhiebert
Copy link
Copy Markdown
Contributor

ryanhiebert commented Sep 26, 2017

How will this affect methods in subclassed models? For example, if Parent has a method, and Child overrides it and calls super(), what will happen?

@denys-tarykin
Copy link
Copy Markdown
Author

This fix is not affect to methods and override only fields. Regarding your example, it possible to execute method of parent class in overridden method of child model

@scorpp
Copy link
Copy Markdown

scorpp commented Oct 18, 2017

any updates on this? who can decide if we accept it?

Copy link
Copy Markdown
Contributor

@ryanhiebert ryanhiebert left a comment

Choose a reason for hiding this comment

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

LGTM. The example issue I mentioned on the ticket looks to be resolved, and the test seems to be a sufficient coverage to avoid regression.

@ryanhiebert
Copy link
Copy Markdown
Contributor

Is there a committer willing to look at this patch? The tests pass, the bug is fixed, and a regression test is added. Thanks!

Copy link
Copy Markdown
Member

@timgraham timgraham left a comment

Choose a reason for hiding this comment

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

Please squash commits when updating and try to follow the commit message format.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We generally try to describe the issue sufficient so that a ticket reference isn't needed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The comment needs improvement. I don't know what "duplicate public attributes" means.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use hanging indent as described in Python coding style.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This condition could use a comment with an explanation. '__' might be replaced with LOOKUP_SEP if that's what it's checking.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

isn't it checking for name mangling and/or dunder methods?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, the comment isn't really clear to me.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use assertIs(..., False) to check for boolean attributes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think a docstring would be useful to explain the expected behavior. See Python coding style for docstring guidelines.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

if attr_per_parent: is simpler -- does the current implementation have an advantage over that? (It looks like it requires more computation.) Same comment below.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think you could edit some existing models rather than adding three new models. We try to avoid adding new models since it decreases the runtime of the tests.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not sure that a separate test class is needed.

@timgraham timgraham changed the title Bug#28198. Fixed model attributes. Fixed #28198 -- Prevented model attributes from overriding deferred fields. Nov 4, 2017
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this doesn't look right

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

it looks like you've merged too much stuff into this branch. you probably want to rebase on top of master, rather than merge. use git rebase --interactive to select only your commits when you do so, to avoid pulling in these other changes.

@denys-tarykin denys-tarykin force-pushed the fixed_dublicated_attributes branch 9 times, most recently from 0cb453a to 3a9e5c2 Compare November 9, 2017 09:03
@denys-tarykin
Copy link
Copy Markdown
Author

I've updated my commit. But I did not update tests models. Because any changes in existing models will affect on existing test, and in this case my commit will contains updates which are not related to issue

@ryanhiebert
Copy link
Copy Markdown
Contributor

@denys-tarykin : It looks like there are a couple comments, even without the model changes requested, that have not been addressed. Would you like some assistance addressing those? If so I might be able to make a PR to your branch.

from parent classes

Implemented logic that update the model creating process.
The bases  in `super_new(cls, name, bases, new_attrs)` can contain
the implementation for a attributes which also provided in
'new_attrs'.Before model creating this implementations are removing
from parent classes. This fix is necessary because during defer reading
of field the result object will not  contain implementation from parent
class
@denys-tarykin denys-tarykin force-pushed the fixed_dublicated_attributes branch from 1cfe955 to 307a82f Compare November 17, 2017 12:39
@denys-tarykin
Copy link
Copy Markdown
Author

I've updated the code that is related to your comments

Copy link
Copy Markdown
Member

@carltongibson carltongibson left a comment

Choose a reason for hiding this comment

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

I'm not, as yet, convinced by this.

The root cause of the issue here comes from Field.contribute_to_class():

# Don't override classmethods with the descriptor. This means that
# if you have a classmethod and a field with the same name, then
# such fields can't be deferred (we don't have a check for this).
if not getattr(cls, self.attname, None):
setattr(cls, self.attname, DeferredAttribute(self.attname, cls))

It would be nice to address it there, rather than in ModelBase.__new__().

If we're going to remove and then replace attributes on parent classes,
we need tests to ensure that logic is correct.

I suggest extracting two methods, or helper functions, to encapsulate the logic
in the two added blocks.

Each of these can then have test cases demonstrating the expected behaviour, and
that it's correct. The two can also be tested together to demonstrate that the
replacement always works as expected.

In general, rather than actually removing/replacing attributes, could we merely
generate a list that could be checked against in Field.contribute_to_class()?

@carltongibson carltongibson self-requested a review June 21, 2019 14:06
@carltongibson carltongibson self-assigned this Jan 22, 2020
Copy link
Copy Markdown
Member

@carltongibson carltongibson left a comment

Choose a reason for hiding this comment

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

I'm going to close this in favor of pursuing the fix in Field.contribute_to_class() that's being worked on in #11337.

IMO, only if a fix there is unavailable should we consider anything along these lines in ModelBase.__new__().

Thanks for the effort @denys-tarykin.

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.

7 participants