#25068: Metaclass conflict when doing createmigrations in ModelState.render
-------------------------------------+-------------------------------------
     Reporter:  kosz85               |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Migrations           |                  Version:  1.8
     Severity:  Normal               |               Resolution:
     Keywords:  metaclass conflict   |             Triage Stage:  Accepted
  createmigrations                   |
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by kosz85):

 That's not smth to be scared of. I can explain what is happening there:

 Each class has metaclass, which default is `type`. It's class of class.
 You can change it and made your own type declaring metaclass. What new
 migrations did, is bad assumption that class would be created only using
 `type`, and that there would be only simple conflicts.
 First take a note that `Model` metaclass is already set to `BaseModel`.

 Assume such situation:
 class cA with metaclass mA
 class cB with metaclass mB
 class cC(cA, cB) -> metaclass mC

 Python has no problem with standard metaclasses.
 When mA and mB eguals default `type` then python knows that mC is also
 `type`.
 Also when mA or mB equals default `type` and the other not (for example
 `BaseModel`) then he can easily solve conflict because every metaclass is
 derived from `type` so Python is using the other one so mC would be
 `BaseModel`.
 But when mA is custom and mB is custom, he don't know what to do, and
 there are even worse scenarios, there may be 3 or more bases to inherit
 from. Then standard response is to manually build mC that inherit from mA
 and mB (like in normal class inheritance).

 So what is doing this patch is reacting to that `TypeError`, and
 constructing (it's normal factory) such custom metaclass from metaclasses
 that are used in bases of this class. That new metaclass is used then to
 create object, instead of standard type. So no magic ;) The only magic is
 factory and populating metaclasses from bases.

--
Ticket URL: <https://code.djangoproject.com/ticket/25068#comment:21>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/064.509ba19e5a7edf0173b347cd46219fbf%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to