Skip to content

Commit 82b46ee

Browse files
Issue #22193: Added private function _PySys_GetSizeOf() needed to implement
some __sizeof__() methods.
1 parent f16f1a2 commit 82b46ee

2 files changed

Lines changed: 46 additions & 33 deletions

File tree

Include/sysmodule.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ PyAPI_FUNC(void) PySys_ResetWarnOptions(void);
2323
PyAPI_FUNC(void) PySys_AddWarnOption(char *);
2424
PyAPI_FUNC(int) PySys_HasWarnOptions(void);
2525

26+
#ifndef Py_LIMITED_API
27+
PyAPI_DATA(size_t) _PySys_GetSizeOf(PyObject *);
28+
#endif
29+
2630
#ifdef __cplusplus
2731
}
2832
#endif

Python/sysmodule.c

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -684,32 +684,20 @@ sys_mdebug(PyObject *self, PyObject *args)
684684
}
685685
#endif /* USE_MALLOPT */
686686

687-
static PyObject *
688-
sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
687+
size_t
688+
_PySys_GetSizeOf(PyObject *o)
689689
{
690+
static PyObject *str__sizeof__ = NULL;
690691
PyObject *res = NULL;
691-
static PyObject *str__sizeof__ = NULL, *gc_head_size = NULL;
692-
static char *kwlist[] = {"object", "default", 0};
693-
PyObject *o, *dflt = NULL;
694-
695-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
696-
kwlist, &o, &dflt))
697-
return NULL;
698-
699-
/* Initialize static variable for GC head size */
700-
if (gc_head_size == NULL) {
701-
gc_head_size = PyInt_FromSsize_t(sizeof(PyGC_Head));
702-
if (gc_head_size == NULL)
703-
return NULL;
704-
}
692+
size_t size;
705693

706694
/* Make sure the type is initialized. float gets initialized late */
707695
if (PyType_Ready(Py_TYPE(o)) < 0)
708-
return NULL;
696+
return (size_t)-1;
709697

710698
/* Instance of old-style class */
711699
if (PyInstance_Check(o))
712-
res = PyInt_FromSsize_t(PyInstance_Type.tp_basicsize);
700+
size = PyInstance_Type.tp_basicsize;
713701
/* all other objects */
714702
else {
715703
PyObject *method = _PyObject_LookupSpecial(o, "__sizeof__",
@@ -724,26 +712,47 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
724712
res = PyObject_CallFunctionObjArgs(method, NULL);
725713
Py_DECREF(method);
726714
}
727-
}
728715

729-
/* Has a default value been given? */
730-
if ((res == NULL) && (dflt != NULL) &&
731-
PyErr_ExceptionMatches(PyExc_TypeError))
732-
{
733-
PyErr_Clear();
734-
Py_INCREF(dflt);
735-
return dflt;
716+
if (res == NULL)
717+
return (size_t)-1;
718+
719+
size = (size_t)PyInt_AsSsize_t(res);
720+
Py_DECREF(res);
721+
if (size == (size_t)-1 && PyErr_Occurred())
722+
return (size_t)-1;
736723
}
737-
else if (res == NULL)
738-
return res;
739724

740725
/* add gc_head size */
741-
if (PyObject_IS_GC(o)) {
742-
PyObject *tmp = res;
743-
res = PyNumber_Add(tmp, gc_head_size);
744-
Py_DECREF(tmp);
726+
if (PyObject_IS_GC(o))
727+
size += sizeof(PyGC_Head);
728+
return size;
729+
}
730+
731+
static PyObject *
732+
sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
733+
{
734+
static char *kwlist[] = {"object", "default", 0};
735+
size_t size;
736+
PyObject *o, *dflt = NULL;
737+
738+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
739+
kwlist, &o, &dflt))
740+
return NULL;
741+
742+
size = _PySys_GetSizeOf(o);
743+
744+
if (size == (size_t)-1 && PyErr_Occurred()) {
745+
/* Has a default value been given */
746+
if (dflt != NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
747+
PyErr_Clear();
748+
Py_INCREF(dflt);
749+
return dflt;
750+
}
751+
else
752+
return NULL;
745753
}
746-
return res;
754+
755+
return PyInt_FromSize_t(size);
747756
}
748757

749758
PyDoc_STRVAR(getsizeof_doc,

0 commit comments

Comments
 (0)