# Using `super()`

The idiomatic way to call methods on a superclass is using the `super()` object to resolve methods in a super class:

    class MyObject(NSObject):
        def init(self):
            self = super().init()
            if self is None:
                return None

            ...
            return self

Because of the way PyObjC is implemented you cannot use the builtin `super` for this, but must use PyObjC’s reimplementation of this builtin:

    from objc import super

You must use this exact pattern to use the argumentless version of `super`, using `objc.super()` in a method body will result in runtime errors due to the way the argumentless super fetches the defining class of the method.

Using this pattern is safe to use in modules that contain a mix of Python and Cocoa classes, PyObjC’s `super` reimplements the builtin `super` with some additions to support PyObjC.

## Background

PyObjC lazily fills a class `__dict__` for two reasons:

1. Correctness: Cocoa classes can change at runtime by way of using categories loaded from dynamic libraries. Because of this eagerly scanning classes for methods can result in an incomplete `__dict__`. Furthermore the Objective-C runtime does not have way to effiencly detect changes to a class.

2. Performance: Cocoa contains a large number of classes with an even larger number of methods. Eagerly scanning classes has a significant overhead when importing framework bindings.

In itself a lazily filled does not cause a problem because the attribute gets filled as needed. But this is a problem with the builtin `super` because that walks the MRO and directly peeks in the class `__dict__` without a way to intercept this. Because of this `objc.super` is a reimplementation of `builtin.super` with special behaviour for Cocoa classes.