mirror of
https://github.com/python/cpython.git
synced 2025-12-04 08:34:25 +00:00
Fix for SF bug #472940: can't getattr() attribute shown by dir()
There really isn't a good reason for instance method objects to have their own __dict__, __doc__ and __name__ properties that just delegate the request to the function (callable); the default attribute behavior already does this. The test suite had to be fixed because the error changes from TypeError to AttributeError.
This commit is contained in:
parent
51c18166bb
commit
56ff387a7e
2 changed files with 6 additions and 33 deletions
|
|
@ -108,8 +108,8 @@ if f1.a.myclass is not f2.a.myclass or \
|
||||||
# try setting __dict__
|
# try setting __dict__
|
||||||
try:
|
try:
|
||||||
F.a.__dict__ = (1, 2, 3)
|
F.a.__dict__ = (1, 2, 3)
|
||||||
except TypeError: pass
|
except (AttributeError, TypeError): pass
|
||||||
else: raise TestFailed, 'expected TypeError'
|
else: raise TestFailed, 'expected TypeError or AttributeError'
|
||||||
|
|
||||||
F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33}
|
F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33}
|
||||||
|
|
||||||
|
|
@ -121,7 +121,7 @@ d = UserDict({'four': 44, 'five': 55})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
F.a.__dict__ = d
|
F.a.__dict__ = d
|
||||||
except TypeError: pass
|
except (AttributeError, TypeError): pass
|
||||||
else: raise TestFailed
|
else: raise TestFailed
|
||||||
|
|
||||||
if f2.a.one <> f1.a.one <> F.a.one <> 11:
|
if f2.a.one <> f1.a.one <> F.a.one <> 11:
|
||||||
|
|
@ -218,13 +218,13 @@ def cantset(obj, name, value):
|
||||||
verify(hasattr(obj, name)) # Otherwise it's probably a typo
|
verify(hasattr(obj, name)) # Otherwise it's probably a typo
|
||||||
try:
|
try:
|
||||||
setattr(obj, name, value)
|
setattr(obj, name, value)
|
||||||
except TypeError:
|
except (AttributeError, TypeError):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise TestFailed, "shouldn't be able to set %s to %r" % (name, value)
|
raise TestFailed, "shouldn't be able to set %s to %r" % (name, value)
|
||||||
try:
|
try:
|
||||||
delattr(obj, name)
|
delattr(obj, name)
|
||||||
except TypeError:
|
except (AttributeError, TypeError):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise TestFailed, "shouldn't be able to del %s" % name
|
raise TestFailed, "shouldn't be able to del %s" % name
|
||||||
|
|
|
||||||
|
|
@ -2019,33 +2019,6 @@ static PyMemberDef instancemethod_memberlist[] = {
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* __dict__, __doc__ and __name__ are retrieved from im_func */
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
im_get_dict(PyMethodObject *im)
|
|
||||||
{
|
|
||||||
return PyObject_GetAttrString(im->im_func, "__dict__");
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
im_get_doc(PyMethodObject *im)
|
|
||||||
{
|
|
||||||
return PyObject_GetAttrString(im->im_func, "__doc__");
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
im_get_name(PyMethodObject *im)
|
|
||||||
{
|
|
||||||
return PyObject_GetAttrString(im->im_func, "__name__");
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyGetSetDef instancemethod_getsetlist[] = {
|
|
||||||
{"__dict__", (getter)im_get_dict, NULL, "same as im_func.__dict__"},
|
|
||||||
{"__doc__", (getter)im_get_doc, NULL, "same as im_func.__doc__"},
|
|
||||||
{"__name__", (getter)im_get_name, NULL, "same as im_func.__name__"},
|
|
||||||
{NULL} /* Sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The getattr() implementation for PyMethod objects is similar to
|
/* The getattr() implementation for PyMethod objects is similar to
|
||||||
PyObject_GenericGetAttr(), but instead of looking in __dict__ it
|
PyObject_GenericGetAttr(), but instead of looking in __dict__ it
|
||||||
asks im_self for the attribute. Then the error handling is a bit
|
asks im_self for the attribute. Then the error handling is a bit
|
||||||
|
|
@ -2350,7 +2323,7 @@ PyTypeObject PyMethod_Type = {
|
||||||
0, /* tp_iternext */
|
0, /* tp_iternext */
|
||||||
0, /* tp_methods */
|
0, /* tp_methods */
|
||||||
instancemethod_memberlist, /* tp_members */
|
instancemethod_memberlist, /* tp_members */
|
||||||
instancemethod_getsetlist, /* tp_getset */
|
0, /* tp_getset */
|
||||||
0, /* tp_base */
|
0, /* tp_base */
|
||||||
0, /* tp_dict */
|
0, /* tp_dict */
|
||||||
instancemethod_descr_get, /* tp_descr_get */
|
instancemethod_descr_get, /* tp_descr_get */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue