Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
47629029
Commit
47629029
authored
Jul 10, 2008
by
Robert Schuppenies
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added garbage collector overhead and optional default return value to
sys.getsizeof.
parent
5930d8f0
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
79 additions
and
15 deletions
+79
-15
Doc/library/sys.rst
Doc/library/sys.rst
+9
-2
Lib/test/test_sys.py
Lib/test/test_sys.py
+23
-0
Modules/_testcapimodule.c
Modules/_testcapimodule.c
+1
-0
Python/sysmodule.c
Python/sysmodule.c
+46
-13
No files found.
Doc/library/sys.rst
View file @
47629029
...
...
@@ -393,13 +393,20 @@ always available.
:func:`setrecursionlimit`.
.. function:: getsizeof(object)
.. function:: getsizeof(object
[, default]
)
Return the size of an object in bytes. The object can be any type of
object. All built-in objects will return correct results, but this
does not have to hold true for third-party extensions as it is implementation
does not have to hold true for third-party extensions as it is implementation
specific.
The *default* argument allows to define a value which will be returned
if the object type does not provide means to retrieve the size and would
cause a `TypeError`.
func:`getsizeof` calls the object's __sizeof__ method and adds an additional
garbage collector overhead if the object is managed by the garbage collector.
.. versionadded:: 2.6
...
...
Lib/test/test_sys.py
View file @
47629029
...
...
@@ -389,6 +389,9 @@ class SysModuleTest(unittest.TestCase):
class
SizeofTest
(
unittest
.
TestCase
):
TPFLAGS_HAVE_GC
=
1
<<
14
TPFLAGS_HEAPTYPE
=
1L
<<
9
def
setUp
(
self
):
self
.
c
=
len
(
struct
.
pack
(
'c'
,
' '
))
self
.
H
=
len
(
struct
.
pack
(
'H'
,
0
))
...
...
@@ -402,6 +405,8 @@ class SizeofTest(unittest.TestCase):
if
hasattr
(
sys
,
"gettotalrefcount"
):
self
.
header
+=
'2P'
self
.
vheader
+=
'2P'
import
_testcapi
self
.
gc_headsize
=
_testcapi
.
SIZEOF_PYGC_HEAD
self
.
file
=
open
(
test
.
test_support
.
TESTFN
,
'wb'
)
def
tearDown
(
self
):
...
...
@@ -410,6 +415,9 @@ class SizeofTest(unittest.TestCase):
def
check_sizeof
(
self
,
o
,
size
):
result
=
sys
.
getsizeof
(
o
)
if
((
type
(
o
)
==
type
)
and
(
o
.
__flags__
&
self
.
TPFLAGS_HEAPTYPE
)
or
\
((
type
(
o
)
!=
type
)
and
(
type
(
o
).
__flags__
&
self
.
TPFLAGS_HAVE_GC
))):
size
+=
self
.
gc_headsize
msg
=
'wrong size for %s: got %d, expected %d'
\
%
(
type
(
o
),
result
,
size
)
self
.
assertEqual
(
result
,
size
,
msg
)
...
...
@@ -423,6 +431,21 @@ class SizeofTest(unittest.TestCase):
"""
return
struct
.
calcsize
(
fmt
+
'0P'
)
def
test_gc_head_size
(
self
):
# Check that the gc header size is added to objects tracked by the gc.
h
=
self
.
header
size
=
self
.
calcsize
gc_header_size
=
self
.
gc_headsize
# bool objects are not gc tracked
self
.
assertEqual
(
sys
.
getsizeof
(
True
),
size
(
h
+
'l'
))
# but lists are
self
.
assertEqual
(
sys
.
getsizeof
([]),
size
(
h
+
'P PP'
)
+
gc_header_size
)
def
test_default
(
self
):
h
=
self
.
header
size
=
self
.
calcsize
self
.
assertEqual
(
sys
.
getsizeof
(
True
,
-
1
),
size
(
h
+
'l'
))
def
test_objecttypes
(
self
):
# check all types defined in Objects/
h
=
self
.
header
...
...
Modules/_testcapimodule.c
View file @
47629029
...
...
@@ -967,6 +967,7 @@ init_testcapi(void)
PyModule_AddObject
(
m
,
"ULLONG_MAX"
,
PyLong_FromUnsignedLongLong
(
PY_ULLONG_MAX
));
PyModule_AddObject
(
m
,
"PY_SSIZE_T_MAX"
,
PyInt_FromSsize_t
(
PY_SSIZE_T_MAX
));
PyModule_AddObject
(
m
,
"PY_SSIZE_T_MIN"
,
PyInt_FromSsize_t
(
PY_SSIZE_T_MIN
));
PyModule_AddObject
(
m
,
"SIZEOF_PYGC_HEAD"
,
PyInt_FromSsize_t
(
sizeof
(
PyGC_Head
)));
TestError
=
PyErr_NewException
(
"_testcapi.error"
,
NULL
,
NULL
);
Py_INCREF
(
TestError
);
...
...
Python/sysmodule.c
View file @
47629029
...
...
@@ -640,9 +640,16 @@ sys_mdebug(PyObject *self, PyObject *args)
#endif
/* USE_MALLOPT */
static
PyObject
*
sys_getsizeof
(
PyObject
*
self
,
PyObject
*
args
)
sys_getsizeof
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kwds
)
{
static
PyObject
*
str__sizeof__
=
NULL
;
PyObject
*
res
=
NULL
;
static
PyObject
*
str__sizeof__
,
*
gc_head_size
=
NULL
;
static
char
*
kwlist
[]
=
{
"object"
,
"default"
,
0
};
PyObject
*
o
,
*
dflt
=
NULL
;
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwds
,
"O|O:getsizeof"
,
kwlist
,
&
o
,
&
dflt
))
return
NULL
;
/* Initialize static variable needed by _PyType_Lookup */
if
(
str__sizeof__
==
NULL
)
{
...
...
@@ -651,29 +658,54 @@ sys_getsizeof(PyObject *self, PyObject *args)
return
NULL
;
}
/* Initialize static variable for GC head size */
if
(
gc_head_size
==
NULL
)
{
gc_head_size
=
PyInt_FromSsize_t
(
sizeof
(
PyGC_Head
));
if
(
gc_head_size
==
NULL
)
return
NULL
;
}
/* Make sure the type is initialized. float gets initialized late */
if
(
PyType_Ready
(
Py_TYPE
(
args
))
<
0
)
if
(
PyType_Ready
(
Py_TYPE
(
o
))
<
0
)
return
NULL
;
/* Instance of old-style class */
if
(
PyInstance_Check
(
args
))
re
turn
PyInt_FromSsize_t
(
PyInstance_Type
.
tp_basicsize
);
if
(
PyInstance_Check
(
o
))
re
s
=
PyInt_FromSsize_t
(
PyInstance_Type
.
tp_basicsize
);
/* all other objects */
else
{
PyObject
*
method
=
_PyType_Lookup
(
Py_TYPE
(
args
),
PyObject
*
method
=
_PyType_Lookup
(
Py_TYPE
(
o
),
str__sizeof__
);
if
(
method
==
NULL
)
{
if
(
method
==
NULL
)
PyErr_Format
(
PyExc_TypeError
,
"Type %.100s doesn't define __sizeof__"
,
Py_TYPE
(
args
)
->
tp_name
);
return
NULL
;
}
return
PyObject_CallFunctionObjArgs
(
method
,
args
,
NULL
);
Py_TYPE
(
o
)
->
tp_name
);
else
res
=
PyObject_CallFunctionObjArgs
(
method
,
o
,
NULL
);
}
/* Has a default value been given? */
if
((
res
==
NULL
)
&&
(
dflt
!=
NULL
)
&&
PyErr_ExceptionMatches
(
PyExc_TypeError
))
{
PyErr_Clear
();
Py_INCREF
(
dflt
);
return
dflt
;
}
else
if
(
res
==
NULL
)
return
res
;
/* add gc_head size */
if
(
PyObject_IS_GC
(
o
))
{
PyObject
*
tmp
=
res
;
res
=
PyNumber_Add
(
tmp
,
gc_head_size
);
Py_DECREF
(
tmp
);
}
return
res
;
}
PyDoc_STRVAR
(
getsizeof_doc
,
"getsizeof(object) -> int
\n
\
"getsizeof(object
, default
) -> int
\n
\
\n
\
Return the size of object in bytes."
);
...
...
@@ -868,7 +900,8 @@ static PyMethodDef sys_methods[] = {
{
"getrefcount"
,
(
PyCFunction
)
sys_getrefcount
,
METH_O
,
getrefcount_doc
},
{
"getrecursionlimit"
,
(
PyCFunction
)
sys_getrecursionlimit
,
METH_NOARGS
,
getrecursionlimit_doc
},
{
"getsizeof"
,
sys_getsizeof
,
METH_O
,
getsizeof_doc
},
{
"getsizeof"
,
(
PyCFunction
)
sys_getsizeof
,
METH_VARARGS
|
METH_KEYWORDS
,
getsizeof_doc
},
{
"_getframe"
,
sys_getframe
,
METH_VARARGS
,
getframe_doc
},
#ifdef MS_WINDOWS
{
"getwindowsversion"
,
(
PyCFunction
)
sys_getwindowsversion
,
METH_NOARGS
,
...
...
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