Skip to content

MRO vs. inherited attributes #428

@galcik

Description

@galcik

The way how attributes are collected from super classes is different comparing to how attributes and methods are searched by getattr (based on MRO for new-style classes).

Example:

@attr.s
class A(object):

    x = attr.ib(10)

    def xx(self):
        return 10


@attr.s
class B(A):
    y = attr.ib(20)


@attr.s
class C(A):
    x = attr.ib(50)

    def xx(self):
        return 50


class D(B, C):
    pass


d = D()
print(d.x)  # prints 10
print(d.xx())  # prints 50

I think it would be great to the use the same approach for collecting attributes as used for searching methods and attributes.

The difference is caused by the fact that the function _transform_attrs in attrs/_make.py considers all attributes (own+inherited stored in __attrs_attrs__) and not only own attributes of super classes:

attrs/src/attr/_make.py

Lines 367 to 368 in 6a07b03

for super_cls in cls.__mro__[1:-1]:
sub_attrs = getattr(super_cls, "__attrs_attrs__", None)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions