[New-bugs-announce] [issue40098] dir() does not return the list of valid attributes for the object

Serhiy Storchaka report at bugs.python.org
Sat Mar 28 15:47:28 EDT 2020


New submission from Serhiy Storchaka <storchaka+cpython at gmail.com>:

Due to the difference in the code of __getattr__ and __dir__ for object and type dir() does not return the list of valid attributes for the object. It can return a name which is not a valid attribute and miss a name of the valid attribute.

1. It does not support metaclasses.

class M(type):
    x = 1

class A(metaclass=M):
    pass

assert hasattr(A, 'x')
assert 'x' not in dir(A)

2. It does not use __mro__, but uses __bases__ recursively.

class M(type):
    def mro(cls):
        if cls.__name__ == 'A':
            return cls, B
        return cls,

class B(metaclass=M):
    x = 1

class A(metaclass=M):
    pass

assert hasattr(A, 'x')
assert 'x' not in dir(A)

3. It uses the __dict__ attribute instead of the instance dict (they can be different).

class A:
    @property
    def __dict__(self):
        return {'x': 1}

assert not hasattr(A(), 'x')
assert 'x' in dir(A())

4. It uses the __class__ attribute instead of type().

class B:
    y = 2

class A:
    x = 1
    @property
    def __class__(self):
        return B

assert hasattr(A, 'x')
assert not hasattr(A, 'y')
assert hasattr(A(), 'x')
assert not hasattr(A(), 'y')
assert 'x' in dir(A)
assert 'y' not in dir(A)
assert 'x' not in dir(A())
assert 'y' in dir(A())

4.1. As a side effect dir() creates an instance dictionary if it was not initialized yet (for memory saving).

It is possible to make these implementations of __dir__() returning exactly what the corresponding __getattr__() accepts, not more and not less. The code will even be much simpler. But is it what we want?

----------
components: Interpreter Core
messages: 365227
nosy: gvanrossum, serhiy.storchaka, tim.peters
priority: normal
severity: normal
status: open
title: dir() does not return the list of valid attributes for the object
type: behavior

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue40098>
_______________________________________


More information about the New-bugs-announce mailing list