Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
82b00c1d
Kaydet (Commit)
82b00c1d
authored
May 24, 2011
tarafından
Benjamin Peterson
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
move specialized dir implementations into __dir__ methods (closes #12166)
üst
9bcfacd4
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
178 additions
and
178 deletions
+178
-178
test_descrtut.py
Lib/test/test_descrtut.py
+1
-0
NEWS
Misc/NEWS
+3
-0
moduleobject.c
Objects/moduleobject.c
+29
-1
object.c
Objects/object.c
+18
-177
typeobject.c
Objects/typeobject.c
+127
-0
No files found.
Lib/test/test_descrtut.py
Dosyayı görüntüle @
82b00c1d
...
@@ -170,6 +170,7 @@ You can get the information from the list type:
...
@@ -170,6 +170,7 @@ You can get the information from the list type:
'__contains__',
'__contains__',
'__delattr__',
'__delattr__',
'__delitem__',
'__delitem__',
'__dir__',
'__doc__',
'__doc__',
'__eq__',
'__eq__',
'__format__',
'__format__',
...
...
Misc/NEWS
Dosyayı görüntüle @
82b00c1d
...
@@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
...
@@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
Core and Builtins
Core and Builtins
-----------------
-----------------
- Issue #12166: Move implementations of dir() specialized for various types into
the __dir__() methods of those types.
- Correct lookup of __dir__ on objects. Among other things, this causes errors
- Correct lookup of __dir__ on objects. Among other things, this causes errors
besides AttributeError found on lookup to be propagated.
besides AttributeError found on lookup to be propagated.
...
...
Objects/moduleobject.c
Dosyayı görüntüle @
82b00c1d
...
@@ -413,6 +413,34 @@ module_clear(PyModuleObject *m)
...
@@ -413,6 +413,34 @@ module_clear(PyModuleObject *m)
return
0
;
return
0
;
}
}
static
PyObject
*
module_dir
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
result
=
NULL
;
PyObject
*
dict
=
PyObject_GetAttrString
(
self
,
"__dict__"
);
if
(
dict
!=
NULL
)
{
if
(
PyDict_Check
(
dict
))
result
=
PyDict_Keys
(
dict
);
else
{
const
char
*
name
=
PyModule_GetName
(
self
);
if
(
name
)
PyErr_Format
(
PyExc_TypeError
,
"%.200s.__dict__ is not a dictionary"
,
name
);
}
}
Py_XDECREF
(
dict
);
return
result
;
}
static
PyMethodDef
module_methods
[]
=
{
{
"__dir__"
,
module_dir
,
METH_NOARGS
,
PyDoc_STR
(
"__dir__() -> specialized dir() implementation"
)},
{
0
}
};
PyDoc_STRVAR
(
module_doc
,
PyDoc_STRVAR
(
module_doc
,
"module(name[, doc])
\n
\
"module(name[, doc])
\n
\
...
@@ -449,7 +477,7 @@ PyTypeObject PyModule_Type = {
...
@@ -449,7 +477,7 @@ PyTypeObject PyModule_Type = {
0
,
/* tp_weaklistoffset */
0
,
/* tp_weaklistoffset */
0
,
/* tp_iter */
0
,
/* tp_iter */
0
,
/* tp_iternext */
0
,
/* tp_iternext */
0
,
/* tp_methods */
module_methods
,
/* tp_methods */
module_members
,
/* tp_members */
module_members
,
/* tp_members */
0
,
/* tp_getset */
0
,
/* tp_getset */
0
,
/* tp_base */
0
,
/* tp_base */
...
...
Objects/object.c
Dosyayı görüntüle @
82b00c1d
...
@@ -1182,66 +1182,6 @@ PyCallable_Check(PyObject *x)
...
@@ -1182,66 +1182,6 @@ PyCallable_Check(PyObject *x)
return
x
->
ob_type
->
tp_call
!=
NULL
;
return
x
->
ob_type
->
tp_call
!=
NULL
;
}
}
/* ------------------------- PyObject_Dir() helpers ------------------------- */
/* Helper for PyObject_Dir.
Merge the __dict__ of aclass into dict, and recursively also all
the __dict__s of aclass's base classes. The order of merging isn't
defined, as it's expected that only the final set of dict keys is
interesting.
Return 0 on success, -1 on error.
*/
static
int
merge_class_dict
(
PyObject
*
dict
,
PyObject
*
aclass
)
{
PyObject
*
classdict
;
PyObject
*
bases
;
assert
(
PyDict_Check
(
dict
));
assert
(
aclass
);
/* Merge in the type's dict (if any). */
classdict
=
PyObject_GetAttrString
(
aclass
,
"__dict__"
);
if
(
classdict
==
NULL
)
PyErr_Clear
();
else
{
int
status
=
PyDict_Update
(
dict
,
classdict
);
Py_DECREF
(
classdict
);
if
(
status
<
0
)
return
-
1
;
}
/* Recursively merge in the base types' (if any) dicts. */
bases
=
PyObject_GetAttrString
(
aclass
,
"__bases__"
);
if
(
bases
==
NULL
)
PyErr_Clear
();
else
{
/* We have no guarantee that bases is a real tuple */
Py_ssize_t
i
,
n
;
n
=
PySequence_Size
(
bases
);
/* This better be right */
if
(
n
<
0
)
PyErr_Clear
();
else
{
for
(
i
=
0
;
i
<
n
;
i
++
)
{
int
status
;
PyObject
*
base
=
PySequence_GetItem
(
bases
,
i
);
if
(
base
==
NULL
)
{
Py_DECREF
(
bases
);
return
-
1
;
}
status
=
merge_class_dict
(
dict
,
base
);
Py_DECREF
(
base
);
if
(
status
<
0
)
{
Py_DECREF
(
bases
);
return
-
1
;
}
}
}
Py_DECREF
(
bases
);
}
return
0
;
}
/* Helper for PyObject_Dir without arguments: returns the local scope. */
/* Helper for PyObject_Dir without arguments: returns the local scope. */
static
PyObject
*
static
PyObject
*
...
@@ -1269,133 +1209,34 @@ _dir_locals(void)
...
@@ -1269,133 +1209,34 @@ _dir_locals(void)
return
names
;
return
names
;
}
}
/* Helper for PyObject_Dir of type objects: returns __dict__ and __bases__.
/* Helper for PyObject_Dir: object introspection. */
We deliberately don't suck up its __class__, as methods belonging to the
metaclass would probably be more confusing than helpful.
*/
static
PyObject
*
_specialized_dir_type
(
PyObject
*
obj
)
{
PyObject
*
result
=
NULL
;
PyObject
*
dict
=
PyDict_New
();
if
(
dict
!=
NULL
&&
merge_class_dict
(
dict
,
obj
)
==
0
)
result
=
PyDict_Keys
(
dict
);
Py_XDECREF
(
dict
);
return
result
;
}
/* Helper for PyObject_Dir of module objects: returns the module's __dict__. */
static
PyObject
*
_specialized_dir_module
(
PyObject
*
obj
)
{
PyObject
*
result
=
NULL
;
PyObject
*
dict
=
PyObject_GetAttrString
(
obj
,
"__dict__"
);
if
(
dict
!=
NULL
)
{
if
(
PyDict_Check
(
dict
))
result
=
PyDict_Keys
(
dict
);
else
{
const
char
*
name
=
PyModule_GetName
(
obj
);
if
(
name
)
PyErr_Format
(
PyExc_TypeError
,
"%.200s.__dict__ is not a dictionary"
,
name
);
}
}
Py_XDECREF
(
dict
);
return
result
;
}
/* Helper for PyObject_Dir of generic objects: returns __dict__, __class__,
and recursively up the __class__.__bases__ chain.
*/
static
PyObject
*
_generic_dir
(
PyObject
*
obj
)
{
PyObject
*
result
=
NULL
;
PyObject
*
dict
=
NULL
;
PyObject
*
itsclass
=
NULL
;
/* Get __dict__ (which may or may not be a real dict...) */
dict
=
PyObject_GetAttrString
(
obj
,
"__dict__"
);
if
(
dict
==
NULL
)
{
PyErr_Clear
();
dict
=
PyDict_New
();
}
else
if
(
!
PyDict_Check
(
dict
))
{
Py_DECREF
(
dict
);
dict
=
PyDict_New
();
}
else
{
/* Copy __dict__ to avoid mutating it. */
PyObject
*
temp
=
PyDict_Copy
(
dict
);
Py_DECREF
(
dict
);
dict
=
temp
;
}
if
(
dict
==
NULL
)
goto
error
;
/* Merge in attrs reachable from its class. */
itsclass
=
PyObject_GetAttrString
(
obj
,
"__class__"
);
if
(
itsclass
==
NULL
)
/* XXX(tomer): Perhaps fall back to obj->ob_type if no
__class__ exists? */
PyErr_Clear
();
else
{
if
(
merge_class_dict
(
dict
,
itsclass
)
!=
0
)
goto
error
;
}
result
=
PyDict_Keys
(
dict
);
/* fall through */
error:
Py_XDECREF
(
itsclass
);
Py_XDECREF
(
dict
);
return
result
;
}
/* Helper for PyObject_Dir: object introspection.
This calls one of the above specialized versions if no __dir__ method
exists. */
static
PyObject
*
static
PyObject
*
_dir_object
(
PyObject
*
obj
)
_dir_object
(
PyObject
*
obj
)
{
{
PyObject
*
result
=
NULL
;
PyObject
*
result
;
static
PyObject
*
dir_str
=
NULL
;
static
PyObject
*
dir_str
=
NULL
;
PyObject
*
dirfunc
=
_PyObject_LookupSpecial
(
obj
,
"__dir__"
,
&
dir_str
);
PyObject
*
dirfunc
=
_PyObject_LookupSpecial
(
obj
,
"__dir__"
,
&
dir_str
);
assert
(
obj
);
assert
(
obj
);
if
(
dirfunc
==
NULL
)
{
if
(
dirfunc
==
NULL
)
{
if
(
PyErr_Occurred
())
if
(
!
PyErr_Occurred
())
return
NULL
;
PyErr_SetString
(
PyExc_TypeError
,
"object does not provide __dir__"
);
/* use default implementation */
return
NULL
;
if
(
PyModule_Check
(
obj
))
result
=
_specialized_dir_module
(
obj
);
else
if
(
PyType_Check
(
obj
))
result
=
_specialized_dir_type
(
obj
);
else
result
=
_generic_dir
(
obj
);
}
}
else
{
/* use __dir__ */
/* use __dir__ */
result
=
PyObject_CallFunctionObjArgs
(
dirfunc
,
NULL
);
result
=
PyObject_CallFunctionObjArgs
(
dirfunc
,
NULL
);
Py_DECREF
(
dirfunc
);
Py_DECREF
(
dirfunc
);
if
(
result
==
NULL
)
if
(
result
==
NULL
)
return
NULL
;
return
NULL
;
/* result must be a list */
/* result must be a list */
/* XXX(gbrandl): could also check if all items are strings */
/* XXX(gbrandl): could also check if all items are strings */
if
(
!
PyList_Check
(
result
))
{
if
(
!
PyList_Check
(
result
))
{
PyErr_Format
(
PyExc_TypeError
,
PyErr_Format
(
PyExc_TypeError
,
"__dir__() must return a list, not %.200s"
,
"__dir__() must return a list, not %.200s"
,
Py_TYPE
(
result
)
->
tp_name
);
Py_TYPE
(
result
)
->
tp_name
);
Py_DECREF
(
result
);
Py_DECREF
(
result
);
result
=
NULL
;
result
=
NULL
;
}
}
}
return
result
;
return
result
;
...
...
Objects/typeobject.c
Dosyayı görüntüle @
82b00c1d
...
@@ -2572,6 +2572,82 @@ type_prepare(PyObject *self, PyObject *args, PyObject *kwds)
...
@@ -2572,6 +2572,82 @@ type_prepare(PyObject *self, PyObject *args, PyObject *kwds)
return
PyDict_New
();
return
PyDict_New
();
}
}
/*
Merge the __dict__ of aclass into dict, and recursively also all
the __dict__s of aclass's base classes. The order of merging isn't
defined, as it's expected that only the final set of dict keys is
interesting.
Return 0 on success, -1 on error.
*/
static
int
merge_class_dict
(
PyObject
*
dict
,
PyObject
*
aclass
)
{
PyObject
*
classdict
;
PyObject
*
bases
;
assert
(
PyDict_Check
(
dict
));
assert
(
aclass
);
/* Merge in the type's dict (if any). */
classdict
=
PyObject_GetAttrString
(
aclass
,
"__dict__"
);
if
(
classdict
==
NULL
)
PyErr_Clear
();
else
{
int
status
=
PyDict_Update
(
dict
,
classdict
);
Py_DECREF
(
classdict
);
if
(
status
<
0
)
return
-
1
;
}
/* Recursively merge in the base types' (if any) dicts. */
bases
=
PyObject_GetAttrString
(
aclass
,
"__bases__"
);
if
(
bases
==
NULL
)
PyErr_Clear
();
else
{
/* We have no guarantee that bases is a real tuple */
Py_ssize_t
i
,
n
;
n
=
PySequence_Size
(
bases
);
/* This better be right */
if
(
n
<
0
)
PyErr_Clear
();
else
{
for
(
i
=
0
;
i
<
n
;
i
++
)
{
int
status
;
PyObject
*
base
=
PySequence_GetItem
(
bases
,
i
);
if
(
base
==
NULL
)
{
Py_DECREF
(
bases
);
return
-
1
;
}
status
=
merge_class_dict
(
dict
,
base
);
Py_DECREF
(
base
);
if
(
status
<
0
)
{
Py_DECREF
(
bases
);
return
-
1
;
}
}
}
Py_DECREF
(
bases
);
}
return
0
;
}
/* __dir__ for type objects: returns __dict__ and __bases__.
We deliberately don't suck up its __class__, as methods belonging to the
metaclass would probably be more confusing than helpful.
*/
static
PyObject
*
type_dir
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
result
=
NULL
;
PyObject
*
dict
=
PyDict_New
();
if
(
dict
!=
NULL
&&
merge_class_dict
(
dict
,
self
)
==
0
)
result
=
PyDict_Keys
(
dict
);
Py_XDECREF
(
dict
);
return
result
;
}
static
PyMethodDef
type_methods
[]
=
{
static
PyMethodDef
type_methods
[]
=
{
{
"mro"
,
(
PyCFunction
)
mro_external
,
METH_NOARGS
,
{
"mro"
,
(
PyCFunction
)
mro_external
,
METH_NOARGS
,
PyDoc_STR
(
"mro() -> list
\n
return a type's method resolution order"
)},
PyDoc_STR
(
"mro() -> list
\n
return a type's method resolution order"
)},
...
@@ -2585,6 +2661,8 @@ static PyMethodDef type_methods[] = {
...
@@ -2585,6 +2661,8 @@ static PyMethodDef type_methods[] = {
PyDoc_STR
(
"__instancecheck__() -> check if an object is an instance"
)},
PyDoc_STR
(
"__instancecheck__() -> check if an object is an instance"
)},
{
"__subclasscheck__"
,
type___subclasscheck__
,
METH_O
,
{
"__subclasscheck__"
,
type___subclasscheck__
,
METH_O
,
PyDoc_STR
(
"__subclasscheck__() -> check if a class is a subclass"
)},
PyDoc_STR
(
"__subclasscheck__() -> check if a class is a subclass"
)},
{
"__dir__"
,
type_dir
,
METH_NOARGS
,
PyDoc_STR
(
"__dir__() -> specialized __dir__ implementation for types"
)},
{
0
}
{
0
}
};
};
...
@@ -3438,6 +3516,53 @@ object_sizeof(PyObject *self, PyObject *args)
...
@@ -3438,6 +3516,53 @@ object_sizeof(PyObject *self, PyObject *args)
return
PyLong_FromSsize_t
(
res
);
return
PyLong_FromSsize_t
(
res
);
}
}
/* __dir__ for generic objects: returns __dict__, __class__,
and recursively up the __class__.__bases__ chain.
*/
static
PyObject
*
object_dir
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
result
=
NULL
;
PyObject
*
dict
=
NULL
;
PyObject
*
itsclass
=
NULL
;
/* Get __dict__ (which may or may not be a real dict...) */
dict
=
PyObject_GetAttrString
(
self
,
"__dict__"
);
if
(
dict
==
NULL
)
{
PyErr_Clear
();
dict
=
PyDict_New
();
}
else
if
(
!
PyDict_Check
(
dict
))
{
Py_DECREF
(
dict
);
dict
=
PyDict_New
();
}
else
{
/* Copy __dict__ to avoid mutating it. */
PyObject
*
temp
=
PyDict_Copy
(
dict
);
Py_DECREF
(
dict
);
dict
=
temp
;
}
if
(
dict
==
NULL
)
goto
error
;
/* Merge in attrs reachable from its class. */
itsclass
=
PyObject_GetAttrString
(
self
,
"__class__"
);
if
(
itsclass
==
NULL
)
/* XXX(tomer): Perhaps fall back to obj->ob_type if no
__class__ exists? */
PyErr_Clear
();
else
if
(
merge_class_dict
(
dict
,
itsclass
)
!=
0
)
goto
error
;
result
=
PyDict_Keys
(
dict
);
/* fall through */
error:
Py_XDECREF
(
itsclass
);
Py_XDECREF
(
dict
);
return
result
;
}
static
PyMethodDef
object_methods
[]
=
{
static
PyMethodDef
object_methods
[]
=
{
{
"__reduce_ex__"
,
object_reduce_ex
,
METH_VARARGS
,
{
"__reduce_ex__"
,
object_reduce_ex
,
METH_VARARGS
,
PyDoc_STR
(
"helper for pickle"
)},
PyDoc_STR
(
"helper for pickle"
)},
...
@@ -3449,6 +3574,8 @@ static PyMethodDef object_methods[] = {
...
@@ -3449,6 +3574,8 @@ static PyMethodDef object_methods[] = {
PyDoc_STR
(
"default object formatter"
)},
PyDoc_STR
(
"default object formatter"
)},
{
"__sizeof__"
,
object_sizeof
,
METH_NOARGS
,
{
"__sizeof__"
,
object_sizeof
,
METH_NOARGS
,
PyDoc_STR
(
"__sizeof__() -> size of object in memory, in bytes"
)},
PyDoc_STR
(
"__sizeof__() -> size of object in memory, in bytes"
)},
{
"__dir__"
,
object_dir
,
METH_NOARGS
,
PyDoc_STR
(
"__dir__() -> default dir() implementation"
)},
{
0
}
{
0
}
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment