1

I have this function that I want to test:

def get_django_model(django_model):
    try:
        app_config = apps.get_app_config("myapp")
        model = app_config.get_model(django_model)
        return model
    except Exception:
        raise DjangoModelMissing(f"Missing django model: {django_model}")

And here is my test:

class ModelInstanceTest(TestCase):
    def test_get_django_model(self):
        model_class = get_djagno_model("Foo")
        self.assertIsInstance(model_class, models.Foo) 

The above test fails, saying AssertionError: <class 'models.Foo'> is not an instance of <class 'models.Foo'>.

However if I replace assertIsInstance with assertIs the test passes.

Can someone explain what is going on here?

This post is related, but doesn't really explain the different results: Python test to check instance type.

2
  • 2
    A class is indeed not an instance of that class. Commented Dec 19, 2019 at 13:02
  • 1
    You also have a typo in your test get_djagno_model (django) Commented Dec 19, 2019 at 13:03

1 Answer 1

2

Your get_django_model function returns a reference to the class, not an object (instance) of that class. So it does not return a Foo object, it returns a reference to the Foo class.

Therefore the model_class is indeed equal to models.Foo, but not an instance of models.Foo. It is however an instance of type, so you can check that:

class ModelInstanceTest(TestCase):

    def test_get_django_model(self):
        model_class = get_djagno_model('Foo')
        self.assertIsInstance(model_class, type)
        self.assertEqual(model_class, models.Foo)
Sign up to request clarification or add additional context in comments.

4 Comments

When you say it returns a reference to the class, is that the same thing as saying it returns a metaclass?
@dwvldg: well the type of a class is a meta-class. So yes, you can say that model_class is an object of a meta-class.
So is type and meta-class the same thing? In other words, is self.assertIsInstance(model_class, type) just saying that model_class is an instance of a meta-class? Is there another way to test if something is an instance of a meta-class?
@dwvldg: but there is no clear distinction, since in Python everything is an object. The type of type is type, etc. so you can say that the "meta-hierarchy" goes on until infinity.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.