Skip to content

Commit 547d3bc

Browse files
Issue python#22193: Added private function _PySys_GetSizeOf() needed to implement
some __sizeof__() methods.
1 parent 143fe05 commit 547d3bc

File tree

2 files changed

+44
-32
lines changed

2 files changed

+44
-32
lines changed

Include/sysmodule.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ PyAPI_FUNC(int) PySys_HasWarnOptions(void);
3333
PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *);
3434
PyAPI_FUNC(PyObject *) PySys_GetXOptions(void);
3535

36+
#ifndef Py_LIMITED_API
37+
PyAPI_DATA(size_t) _PySys_GetSizeOf(PyObject *);
38+
#endif
39+
3640
#ifdef __cplusplus
3741
}
3842
#endif

Python/sysmodule.c

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -863,29 +863,16 @@ sys_mdebug(PyObject *self, PyObject *args)
863863
}
864864
#endif /* USE_MALLOPT */
865865

866-
static PyObject *
867-
sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
866+
size_t
867+
_PySys_GetSizeOf(PyObject *o)
868868
{
869869
PyObject *res = NULL;
870-
static PyObject *gc_head_size = NULL;
871-
static char *kwlist[] = {"object", "default", 0};
872-
PyObject *o, *dflt = NULL;
873870
PyObject *method;
874-
875-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
876-
kwlist, &o, &dflt))
877-
return NULL;
878-
879-
/* Initialize static variable for GC head size */
880-
if (gc_head_size == NULL) {
881-
gc_head_size = PyLong_FromSsize_t(sizeof(PyGC_Head));
882-
if (gc_head_size == NULL)
883-
return NULL;
884-
}
871+
size_t size;
885872

886873
/* Make sure the type is initialized. float gets initialized late */
887874
if (PyType_Ready(Py_TYPE(o)) < 0)
888-
return NULL;
875+
return (size_t)-1;
889876

890877
method = _PyObject_LookupSpecial(o, &PyId___sizeof__);
891878
if (method == NULL) {
@@ -899,24 +886,45 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
899886
Py_DECREF(method);
900887
}
901888

902-
/* Has a default value been given */
903-
if ((res == NULL) && (dflt != NULL) &&
904-
PyErr_ExceptionMatches(PyExc_TypeError))
905-
{
906-
PyErr_Clear();
907-
Py_INCREF(dflt);
908-
return dflt;
909-
}
910-
else if (res == NULL)
911-
return res;
889+
if (res == NULL)
890+
return (size_t)-1;
891+
892+
size = PyLong_AsSize_t(res);
893+
Py_DECREF(res);
894+
if (size == (size_t)-1 && PyErr_Occurred())
895+
return (size_t)-1;
912896

913897
/* add gc_head size */
914-
if (PyObject_IS_GC(o)) {
915-
PyObject *tmp = res;
916-
res = PyNumber_Add(tmp, gc_head_size);
917-
Py_DECREF(tmp);
898+
if (PyObject_IS_GC(o))
899+
size += sizeof(PyGC_Head);
900+
return size;
901+
}
902+
903+
static PyObject *
904+
sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
905+
{
906+
static char *kwlist[] = {"object", "default", 0};
907+
size_t size;
908+
PyObject *o, *dflt = NULL;
909+
910+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
911+
kwlist, &o, &dflt))
912+
return NULL;
913+
914+
size = _PySys_GetSizeOf(o);
915+
916+
if (size == (size_t)-1 && PyErr_Occurred()) {
917+
/* Has a default value been given */
918+
if (dflt != NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
919+
PyErr_Clear();
920+
Py_INCREF(dflt);
921+
return dflt;
922+
}
923+
else
924+
return NULL;
918925
}
919-
return res;
926+
927+
return PyLong_FromSize_t(size);
920928
}
921929

922930
PyDoc_STRVAR(getsizeof_doc,

0 commit comments

Comments
 (0)