[Python-3000] Confused about getattr() and special methods
Thomas Heller
theller at ctypes.org
Tue Sep 4 11:34:46 CEST 2007
I was looking into the Lib\test\test_uuid on Windows, which fails with this traceback:
test test_uuid failed -- Traceback (most recent call last):
File "C:\buildbot\work\3.0.heller-windows\build\lib\test\test_uuid.py", line 323, in test_ipconfig_getnode
node = uuid._ipconfig_getnode()
File "C:\buildbot\work\3.0.heller-windows\build\lib\uuid.py", line 376, in _ipconfig_getnode
for line in pipe:
TypeError: '_wrap_close' object is not iterable
The test can be fixed with this little patch:
Index: Lib/os.py
===================================================================
--- Lib/os.py (revision 57827)
+++ Lib/os.py (working copy)
@@ -664,6 +664,8 @@
return self._proc.wait() << 8 # Shift left to match old behavior
def __getattr__(self, name):
return getattr(self._stream, name)
+ def __iter__(self):
+ return iter(self._stream)
# Supply os.fdopen() (used by subprocess!)
def fdopen(fd, mode="r", buffering=-1):
However, looking further into this I'm getting confused.
Shouldn't the __getattr__ implementation find the __iter__ method
of the _stream instance variable?
Consider this code:
<code>
##__metaclass__ = type
class X:
def __str__(self):
return "foo"
def __len__(self):
return 42
def __iter__(self):
return iter([1, 2, 3])
class proxy:
def __init__(self):
self.x = X()
def __getattr__(self, name):
return getattr(self.x, name)
p = proxy()
print(len(p))
print(str(p))
print(iter(p))
<code/>
In Python2.5 and trunk, all the calls len(p), str(p), and iter(p) return the attributes
of the X class instance. Uncommenting the '__metaclass__ = type' line makes the code fail.
IIUC, in py3k, classic classes do not exist any longer, so the __metaclass__ line
has no effect anyway. Is this behaviour intended?
Thomas
More information about the Python-3000
mailing list