📄 object.c
字号:
goto error;
if (merge_class_dict(masterdict, arg) < 0)
goto error;
}
/* Else look at its dict, and the attrs reachable from its class. */
else {
PyObject *itsclass;
/* Create a dict to start with. CAUTION: Not everything
responding to __dict__ returns a dict! */
masterdict = PyObject_GetAttrString(arg, "__dict__");
if (masterdict == NULL) {
PyErr_Clear();
masterdict = PyDict_New();
}
else if (!PyDict_Check(masterdict)) {
Py_DECREF(masterdict);
masterdict = PyDict_New();
}
else {
/* The object may have returned a reference to its
dict, so copy it to avoid mutating it. */
PyObject *temp = PyDict_Copy(masterdict);
Py_DECREF(masterdict);
masterdict = temp;
}
if (masterdict == NULL)
goto error;
/* Merge in __members__ and __methods__ (if any).
XXX Would like this to go away someday; for now, it's
XXX needed to get at im_self etc of method objects. */
if (merge_list_attr(masterdict, arg, "__members__") < 0)
goto error;
if (merge_list_attr(masterdict, arg, "__methods__") < 0)
goto error;
/* Merge in attrs reachable from its class.
CAUTION: Not all objects have a __class__ attr. */
itsclass = PyObject_GetAttrString(arg, "__class__");
if (itsclass == NULL)
PyErr_Clear();
else {
int status = merge_class_dict(masterdict, itsclass);
Py_DECREF(itsclass);
if (status < 0)
goto error;
}
}
assert((result == NULL) ^ (masterdict == NULL));
if (masterdict != NULL) {
/* The result comes from its keys. */
assert(result == NULL);
result = PyDict_Keys(masterdict);
if (result == NULL)
goto error;
}
assert(result);
if (PyList_Sort(result) != 0)
goto error;
else
goto normal_return;
error:
Py_XDECREF(result);
result = NULL;
/* fall through */
normal_return:
Py_XDECREF(masterdict);
return result;
}
/*
NoObject is usable as a non-NULL undefined value, used by the macro None.
There is (and should be!) no way to create other objects of this type,
so there is exactly one (which is indestructible, by the way).
(XXX This type and the type of NotImplemented below should be unified.)
*/
/* ARGSUSED */
static PyObject *
none_repr(PyObject *op)
{
return PyString_FromString("None");
}
/* ARGUSED */
static void
none_dealloc(PyObject* ignore)
{
/* This should never get called, but we also don't want to SEGV if
* we accidently decref None out of existance.
*/
abort();
}
#ifndef SYMBIAN
static PyTypeObject PyNone_Type = {
PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_PyNone_Type = {
PyObject_HEAD_INIT(NULL)
#endif
0,
"NoneType",
0,
0,
(destructor)none_dealloc, /*tp_dealloc*/ /*never called*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)none_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
};
#ifndef SYMBIAN
PyObject _Py_NoneStruct = {
PyObject_HEAD_INIT(&PyNone_Type)
};
#else
extern void _Py_None_Init()
{
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#ifdef Py_TRACE_REFS
(pyglobals->_Py_NoneStruct)._ob_next = 0;
(pyglobals->_Py_NoneStruct)._ob_prev = 0;
#endif
(pyglobals->_Py_NoneStruct).ob_refcnt = 1;
(pyglobals->_Py_NoneStruct).ob_type = &PyNone_Type;
return;
}
#endif /* SYMBIAN */
/* NotImplemented is an object that can be used to signal that an
operation is not implemented for the given type combination. */
static PyObject *
NotImplemented_repr(PyObject *op)
{
return PyString_FromString("NotImplemented");
}
#ifndef SYMBIAN
static PyTypeObject PyNotImplemented_Type = {
PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_PyNotImplemented_Type = {
PyObject_HEAD_INIT(NULL)
#endif
0,
"NotImplementedType",
0,
0,
(destructor)none_dealloc, /*tp_dealloc*/ /*never called*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)NotImplemented_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
};
#ifndef SYMBIAN
PyObject _Py_NotImplementedStruct = {
PyObject_HEAD_INIT(&PyNotImplemented_Type)
};
#else
extern void _Py_NotImplemented_Init()
{
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#ifdef Py_TRACE_REFS
(pyglobals->_Py_NotImplementedStruct)._ob_next = 0;
(pyglobals->_Py_NotImplementedStruct)._ob_prev = 0;
#endif
(pyglobals->_Py_NotImplementedStruct).ob_refcnt = 1;
(pyglobals->_Py_NotImplementedStruct).ob_type = &PyNotImplemented_Type;
return;
}
#endif /* SYMBIAN */
DL_EXPORT(void)
_Py_ReadyTypes(void)
{
if (PyType_Ready(&PyType_Type) < 0)
Py_FatalError("Can't initialize 'type'");
if (PyType_Ready(&PyList_Type) < 0)
Py_FatalError("Can't initialize 'list'");
if (PyType_Ready(&PyNone_Type) < 0)
Py_FatalError("Can't initialize type(None)");
if (PyType_Ready(&PyNotImplemented_Type) < 0)
Py_FatalError("Can't initialize type(NotImplemented)");
}
#ifdef Py_TRACE_REFS
const static PyObject refchain = {&refchain, &refchain};
DL_EXPORT(void)
_Py_ResetReferences(void)
{
refchain._ob_prev = refchain._ob_next = &refchain;
_Py_RefTotal = 0;
}
DL_EXPORT(void)
_Py_NewReference(PyObject *op)
{
_Py_RefTotal++;
op->ob_refcnt = 1;
op->_ob_next = refchain._ob_next;
op->_ob_prev = &refchain;
refchain._ob_next->_ob_prev = op;
refchain._ob_next = op;
#ifdef COUNT_ALLOCS
inc_count(op->ob_type);
#endif
}
DL_EXPORT(void)
_Py_ForgetReference(register PyObject *op)
{
#ifdef SLOW_UNREF_CHECK
register PyObject *p;
#endif
if (op->ob_refcnt < 0)
Py_FatalError("UNREF negative refcnt");
if (op == &refchain ||
op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op)
Py_FatalError("UNREF invalid object");
#ifdef SLOW_UNREF_CHECK
for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
if (p == op)
break;
}
if (p == &refchain) /* Not found */
Py_FatalError("UNREF unknown object");
#endif
op->_ob_next->_ob_prev = op->_ob_prev;
op->_ob_prev->_ob_next = op->_ob_next;
op->_ob_next = op->_ob_prev = NULL;
#ifdef COUNT_ALLOCS
op->ob_type->tp_frees++;
#endif
}
DL_EXPORT(void)
_Py_Dealloc(PyObject *op)
{
destructor dealloc = op->ob_type->tp_dealloc;
_Py_ForgetReference(op);
(*dealloc)(op);
}
DL_EXPORT(void)
_Py_PrintReferences(FILE *fp)
{
PyObject *op;
fprintf(fp, "Remaining objects:\n");
for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
fprintf(fp, "[%d] ", op->ob_refcnt);
if (PyObject_Print(op, fp, 0) != 0)
PyErr_Clear();
putc('\n', fp);
}
}
DL_EXPORT(PyObject *)
_Py_GetObjects(PyObject *self, PyObject *args)
{
int i, n;
PyObject *t = NULL;
PyObject *res, *op;
if (!PyArg_ParseTuple(args, "i|O", &n, &t))
return NULL;
op = refchain._ob_next;
res = PyList_New(0);
if (res == NULL)
return NULL;
for (i = 0; (n == 0 || i < n) && op != &refchain; i++) {
while (op == self || op == args || op == res || op == t ||
(t != NULL && op->ob_type != (PyTypeObject *) t)) {
op = op->_ob_next;
if (op == &refchain)
return res;
}
if (PyList_Append(res, op) < 0) {
Py_DECREF(res);
return NULL;
}
op = op->_ob_next;
}
return res;
}
#endif
/* Hack to force loading of cobject.o */
#ifndef SYMBIAN
const PyTypeObject *_Py_cobject_hack = &PyCObject_Type;
#endif
/* Hack to force loading of abstract.o */
#ifndef SYMBIAN
const int (*_Py_abstract_hack)(PyObject *) = PyObject_Size;
#endif
/* Python's malloc wrappers (see pymem.h) */
DL_EXPORT(void *)
PyMem_Malloc(size_t nbytes)
{
#if _PyMem_EXTRA > 0
if (nbytes == 0)
nbytes = _PyMem_EXTRA;
#endif
return PyMem_MALLOC(nbytes);
}
DL_EXPORT(void *)
PyMem_Realloc(void *p, size_t nbytes)
{
/* See comment near MALLOC_ZERO_RETURNS_NULL in pyport.h. */
return PyMem_REALLOC(p, nbytes ? nbytes : 1);
}
DL_EXPORT(void)
PyMem_Free(void *p)
{
PyMem_FREE(p);
}
/* Python's object malloc wrappers (see objimpl.h) */
DL_EXPORT(void *)
PyObject_Malloc(size_t nbytes)
{
return PyObject_MALLOC(nbytes);
}
DL_EXPORT(void *)
PyObject_Realloc(void *p, size_t nbytes)
{
return PyObject_REALLOC(p, nbytes);
}
DL_EXPORT(void)
PyObject_Free(void *p)
{
PyObject_FREE(p);
}
/* These methods are used to control infinite recursion in repr, str, print,
etc. Container objects that may recursively contain themselves,
e.g. builtin dictionaries and lists, should used Py_ReprEnter() and
Py_ReprLeave() to avoid infinite recursion.
Py_ReprEnter() returns 0 the first time it is called for a particular
object and 1 every time thereafter. It returns -1 if an exception
occurred. Py_ReprLeave() has no return value.
See dictobject.c and listobject.c for examples of use.
*/
#define KEY "Py_Repr"
DL_EXPORT(int)
Py_ReprEnter(PyObject *obj)
{
PyObject *dict;
PyObject *list;
int i;
dict = PyThreadState_GetDict();
if (dict == NULL)
return -1;
list = PyDict_GetItemString(dict, KEY);
if (list == NULL) {
list = PyList_New(0);
if (list == NULL)
return -1;
if (PyDict_SetItemString(dict, KEY, list) < 0)
return -1;
Py_DECREF(list);
}
i = PyList_GET_SIZE(list);
while (--i >= 0) {
if (PyList_GET_ITEM(list, i) == obj)
return 1;
}
PyList_Append(list, obj);
return 0;
}
DL_EXPORT(void)
Py_ReprLeave(PyObject *obj)
{
PyObject *dict;
PyObject *list;
int i;
dict = PyThreadState_GetDict();
if (dict == NULL)
return;
list = PyDict_GetItemString(dict, KEY);
if (list == NULL || !PyList_Check(list))
return;
i = PyList_GET_SIZE(list);
/* Count backwards because we always expect obj to be list[-1] */
while (--i >= 0) {
if (PyList_GET_ITEM(list, i) == obj) {
PyList_SetSlice(list, i, i + 1, NULL);
break;
}
}
}
/*
trashcan
CT 2k0130
non-recursively destroy nested objects
CT 2k0223
everything is now done in a macro.
CT 2k0305
modified to use functions, after Tim Peter's suggestion.
CT 2k0309
modified to restore a possible error.
CT 2k0325
added better safe than sorry check for threadstate
CT 2k0422
complete rewrite. We now build a chain via ob_type
and save the limited number of types in ob_refcnt.
This is perfect since we don't need any memory.
A patch for free-threading would need just a lock.
*/
#define Py_TRASHCAN_TUPLE 1
#define Py_TRASHCAN_LIST 2
#define Py_TRASHCAN_DICT 3
#define Py_TRASHCAN_FRAME 4
#define Py_TRASHCAN_TRACEBACK 5
/* extend here if other objects want protection */
#ifndef SYMBIAN
int _PyTrash_delete_nesting = 0;
PyObject * _PyTrash_delete_later = NULL;
#else
#define _PyTrash_delete_nesting (pyglobals->_PyTrash_delete_nesting)
#define _PyTrash_delete_later (pyglobals->_PyTrash_delete_later)
#endif
DL_EXPORT(void)
_PyTrash_deposit_object(PyObject *op)
{
int typecode;
#ifdef SYMBIAN
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#endif
if (PyTuple_Check(op))
typecode = Py_TRASHCAN_TUPLE;
else if (PyList_Check(op))
typecode = Py_TRASHCAN_LIST;
else if (PyDict_Check(op))
typecode = Py_TRASHCAN_DICT;
else if (PyFrame_Check(op))
typecode = Py_TRASHCAN_FRAME;
else if (PyTraceBack_Check(op))
typecode = Py_TRASHCAN_TRACEBACK;
else /* We have a bug here -- those are the only types in GC */ {
Py_FatalError("Type not supported in GC -- internal bug");
return; /* pacify compiler -- execution never here */
}
op->ob_refcnt = typecode;
op->ob_type = (PyTypeObject*)_PyTrash_delete_later;
_PyTrash_delete_later = op;
}
DL_EXPORT(void)
_PyTrash_destroy_chain(void)
{
#ifdef SYMBIAN
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#endif
while (_PyTrash_delete_later) {
PyObject *shredder = _PyTrash_delete_later;
_PyTrash_delete_later = (PyObject*) shredder->ob_type;
switch (shredder->ob_refcnt) {
case Py_TRASHCAN_TUPLE:
shredder->ob_type = &PyTuple_Type;
break;
case Py_TRASHCAN_LIST:
shredder->ob_type = &PyList_Type;
break;
case Py_TRASHCAN_DICT:
shredder->ob_type = &PyDict_Type;
break;
case Py_TRASHCAN_FRAME:
shredder->ob_type = &PyFrame_Type;
break;
case Py_TRASHCAN_TRACEBACK:
shredder->ob_type = &PyTraceBack_Type;
break;
}
_Py_NewReference(shredder);
++_PyTrash_delete_nesting;
Py_DECREF(shredder);
--_PyTrash_delete_nesting;
}
}
#ifdef WITH_PYMALLOC
#include "obmalloc.c"
#endif /* WITH_PYMALLOC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -