[Django]-Python private inheritance? How to trick isinstance()?

6đź‘Ť

So I have a way to do it, but its via “monkey patching.” You can’t use ABCMeta because that requires you override your base class’s metaclass.

You could “change” isinstance as follows. It is important that “patches” only gets imported once, and I would only do this if is no other way.

patches.py

import django.models
import mymodel
import __builtin__
def _isinstance(instance, clz):
    if clz is models.AutoField and isinstance_orig(instance, MyAutoField):
        return False
    return isinstance_orig(instance, clz)
__builtin__.isinstance_orig = __builtin__.isinstance
__builtin__.isinstance = _isinstance

Then your test program:

class MyAutoField(models.AutoField): pass

x = MyAutoField()
print(isinstance(x, models.AutoField))
print(isinstance(x, models.MyAutoField))

Introducing Abstract Base Classes: PEP-3119 . Below is an abstract example…

class ABCMeta(type):

  def __instancecheck__(cls, inst):
    """Implement isinstance(inst, cls)."""
    return any(cls.__subclasscheck__(c)
               for c in {type(inst), inst.__class__})

  def __subclasscheck__(cls, sub):
    """Implement issubclass(sub, cls)."""
    candidates = cls.__dict__.get("__subclass__", set()) | {cls}
    return any(c in candidates for c in sub.mro())
👤Nix

Leave a comment