Skip to content

Instantiating Module inherited from abc.ABC returns __class__ assignment error on older versions #1246

Description

@rabbott999

This is an issue that only affects older versions, but the error message is quite cryptic and I haven't been able to find any references to the issue, so it might be helpful to others who are also running older versions.

The issue arises in code that follows this pattern:

import abc
import equinox as eqx

class Foo(abc.ABC, eqx.Module):

    def __init__(self):
        ...

class Bar(Foo):
    def __init__(self):
        ...

Bar()

Running the above on v0.12.2 returns the error

Traceback (most recent call last):
  File "/path/to/main.py", line 13, in <module>
    Bar()
  File "/path/to/equinox/equinox/_module.py", line 617, in __call__
    object.__setattr__(self, "__class__", cls)
TypeError: __class__ assignment: 'Bar' object layout differs from 'Bar'

From some bisection, the issue we introduced in 804d82e, and the issue disappeared in 2c3fbae, which rewrote much of the module system.

I haven't been able to nail down the specifics of the issue, but it does seem to be related to the internal details of inheritance. In particular, the method resolution order shows some weirdness, which is presumably why type(self) != cls:

(Pdb) p type(self).mro()
[<class '__main__.Bar'>, <class 'equinox._module._Initable'>, <class '__main__.Bar'>, <class '__main__.Foo'>, <class 'abc.ABC'>, <class 'equinox._module.Module'>, <class 'object'>]
(Pdb) p cls.mro()
[<class '__main__.Bar'>, <class '__main__.Foo'>, <class 'abc.ABC'>, <class 'equinox._module.Module'>, <class 'object'>]

There are 3 possible fixes here:

  1. Upgrade to equinox>=0.13.0
  2. Flip the order of the inheritance, so the declaration of Foo becomes
class Foo(eqx.Module, abc.ABC):
	...
  1. Don't inherit from abc.ABC at all:
class Foo(eqx.Module):
	...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions