New submission from Serhiy Storchaka <storchaka+cpyt...@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 <rep...@bugs.python.org>
<https://bugs.python.org/issue40098>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to