-
-
Notifications
You must be signed in to change notification settings - Fork 457
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
Include model base subclasses in plugin base class hook condition #1670
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.
Let's add a test case, maybe?
Yeah, I just don't know how I could write a reasonable test here. Perhaps just |
I would go with a realistic example (solving metaclass conflicts): class CustomMeta(type): ...
class CustomBase(metaclass=CustomMeta): ...
class ModelCustomMeta(modes.ModelBase, CustomMeta): ...
class MyModel(models.Model, CustomBase, metaclass=ModelCustomMeta): ... I've seen code like this in the wild. Do you agree? |
Great, I'll add that case! Probably would've taken me ages to come up with that. Not very familiar with metaclass subclassing.. |
Hm, it's not a breaking case though. Since the metaclass is still Then I'm not even sure if you could subclass metaclasses? |
You sure can :) |
I can't come up with a reasonable case that doesn't use |
Sorry, I am confused. Why do you think that my case in #1670 (comment) is not realistic? I've used it several times when I mixed two metaclasses.
Why? :) In my example, I am using So, the metaclass would be not I think that I might be missing something obvious :) |
I'm not saying it isn't realistic. It's just not a case that covers for subclassing of the metaclass in our hook condition. We're looking at the metaclass of the bases. Which means in your case the hook condition instantly look at |
Yeap, as I said, I was missing something obvious :) Here's how for base_expr in defn.base_type_exprs:
base_name = self.get_fullname_for_hook(base_expr)
if base_name:
hook = self.plugin.get_base_class_hook(base_name)
if hook:
hook(ClassDefContext(defn, base_expr, self)) Given this example: - case: test_custom_model_base_metaclass
main: |
from myapp.models import MyModel
m1 = MyModel(field=1)
reveal_type(m1.pk)
reveal_type(m1.field)
m2 = MyModel(field=None)
reveal_type(m2.pk)
reveal_type(m2.field)
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from django.db import models
from django.db.models.base import ModelBase
class CustomMeta(type): ...
class CustomBase(metaclass=CustomMeta): ...
class ModelCustomMeta(ModelBase, CustomMeta): ...
class MyModel(models.Model, CustomBase, metaclass=ModelCustomMeta):
field = models.IntegerField()
The
And not Thanks a lot, @flaeppe, for bearing with me! |
👍 Yeah, lets close this off for now. |
I have made things!
We now also trigger the base class hook for subclasses of
ModelBase
.Not at all sure how or if we should incorporate this into our test suite.
Related issues
Refs: #1668 (comment)