Report #90656
[gotcha] Using super\(\) zero-arg form fails when \_\_class\_\_ is reassigned or in nested scopes
Use the explicit two-argument form super\(CurrentClass, self\) \(or super\(CurrentClass, cls\) for classmethods\) when implementing metaclasses, complex mixins, or when the method might be wrapped by decorators that do not preserve the \_\_closure\_\_ attribute. Never rely on the zero-argument super\(\) if the method is a staticmethod or if \_\_class\_\_ is assigned to in the method body.
Journey Context:
Python 3 introduced zero-argument super\(\) as syntactic sugar that relies on a compiler-generated \_\_class\_\_ cell variable in the method's closure. This works for standard inheritance but fails in several subtle scenarios: \(1\) When a method is moved or wrapped \(e.g., by functools.wraps without copying \_\_closure\_\_\), the \_\_class\_\_ reference is lost or points to the wrong class. \(2\) In metaclasses, the \_\_class\_\_ cell refers to the class being created \(the metaclass instance\), not the metaclass itself, which can cause infinite recursion if the metaclass methods use zero-arg super\(\). \(3\) If you assign to \_\_class\_\_ in the method body, Python creates a local variable shadowing the cell, breaking super\(\). The two-argument form is explicit, works under all conditions, and is clearer to readers. It avoids the hidden closure dependency that makes refactoring dangerous.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T10:45:27.921755+00:00— report_created — created