[pypy-issue] Issue #1835: py3.3: dir(None) gives TypeError (pypy/pypy)
Martin Matusiak
issues-reply at bitbucket.org
Sat Aug 2 19:11:46 CEST 2014
New issue 1835: py3.3: dir(None) gives TypeError
https://bitbucket.org/pypy/pypy/issue/1835/py33-dir-none-gives-typeerror
Martin Matusiak:
As seen here (even though the cause is not obvious from the output):
http://buildbot.pypy.org/summary/longrepr?testname=unmodified&builder=pypy-c-app-level-linux-x86-64&build=2379&mod=lib-python.3.test.test_unittest
First, a couple of checks:
```
#!python
>>>> isinstance(None, object)
True
>>>> None.__dir__()
['__str__', '__getattribute__', '__lt__', '__init__', '__setattr__', '__reduce_ex__', '__new__', '__format__', '__class__', '__doc__', '__ne__', '__reduce__', '__subclasshook__', '__gt__', '__bool__', '__eq__', '__dir__', '__delattr__', '__le__', '__repr__', '__hash__', '__ge__']
>>>> object.__dir__()
Traceback (application-level):
File "<inline>", line 1 in <module>
object.__dir__()
TypeError: __dir__() takes exactly 1 argument (0 given)
>>>> dir(None)
Traceback (application-level):
File "<inline>", line 1 in <module>
dir(None)
TypeError: __dir__() takes exactly 1 argument (0 given)
```
Ok, so calling __dir__ directly on None works, but when called through dir() it has the effect of calling object.__dir__ without arguments.
The incantation looks like this:
```
#!python
dir_meth = lookup_special(obj, "__dir__")
if dir_meth is not None:
result = dir_meth()
# object: <bound method type.__dir__ of <class 'object'>>
# None: <function __dir__ at 0xb61a9aec>
```
When called on object, dir_meth is a bound method. When called on None, it's just a function, why is that?
lookup_special:
```
#!python
w_descr = space.lookup(w_obj, meth)
if w_descr is None:
return space.w_None
return space.get(w_descr, w_obj)
```
So: use the wrapped object to find the descriptor, then use the descriptor to get a method.
More information about the pypy-issue
mailing list