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
51df0647
Commit
51df0647
authored
Jun 01, 2008
by
Robert Schuppenies
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
parent
6495c8da
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
271 additions
and
2 deletions
+271
-2
Doc/library/sys.rst
Doc/library/sys.rst
+10
-0
Lib/test/test_sys.py
Lib/test/test_sys.py
+149
-2
Misc/NEWS
Misc/NEWS
+2
-0
Objects/bytesobject.c
Objects/bytesobject.c
+13
-0
Objects/dictobject.c
Objects/dictobject.c
+15
-0
Objects/listobject.c
Objects/listobject.c
+12
-0
Objects/longobject.c
Objects/longobject.c
+13
-0
Objects/typeobject.c
Objects/typeobject.c
+16
-0
Python/sysmodule.c
Python/sysmodule.c
+41
-0
No files found.
Doc/library/sys.rst
View file @
51df0647
...
...
@@ -409,6 +409,16 @@ always available.
:func:`setrecursionlimit`.
.. function:: getsizeof(object)
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
specific.
.. versionadded:: 2.6
.. function:: _getframe([depth])
Return a frame object from the call stack. If optional integer *depth* is
...
...
Lib/test/test_sys.py
View file @
51df0647
# -*- coding: iso-8859-1 -*-
import
unittest
,
test
.
test_support
import
sys
,
cStringIO
import
sys
,
cStringIO
,
os
class
SysModuleTest
(
unittest
.
TestCase
):
...
...
@@ -405,8 +405,155 @@ class SysModuleTest(unittest.TestCase):
self
.
assertEqual
(
out
,
'?'
)
class
SizeofTest
(
unittest
.
TestCase
):
def
setUp
(
self
):
import
struct
self
.
i
=
len
(
struct
.
pack
(
'i'
,
0
))
self
.
l
=
len
(
struct
.
pack
(
'l'
,
0
))
self
.
p
=
len
(
struct
.
pack
(
'P'
,
0
))
self
.
headersize
=
self
.
l
+
self
.
p
if
hasattr
(
sys
,
"gettotalrefcount"
):
self
.
headersize
+=
2
*
self
.
p
self
.
file
=
open
(
test
.
test_support
.
TESTFN
,
'wb'
)
def
tearDown
(
self
):
self
.
file
.
close
()
os
.
remove
(
test
.
test_support
.
TESTFN
)
def
check_sizeof
(
self
,
o
,
size
):
result
=
sys
.
getsizeof
(
o
)
msg
=
'wrong size for %s: got %d, expected %d'
\
%
(
type
(
o
),
result
,
size
)
self
.
assertEqual
(
result
,
size
,
msg
)
def
align
(
self
,
value
):
mod
=
value
%
self
.
p
if
mod
!=
0
:
return
value
-
mod
+
self
.
p
else
:
return
value
def
test_align
(
self
):
self
.
assertTrue
(
(
self
.
align
(
0
)
%
self
.
p
)
==
0
)
self
.
assertTrue
(
(
self
.
align
(
1
)
%
self
.
p
)
==
0
)
self
.
assertTrue
(
(
self
.
align
(
3
)
%
self
.
p
)
==
0
)
self
.
assertTrue
(
(
self
.
align
(
4
)
%
self
.
p
)
==
0
)
self
.
assertTrue
(
(
self
.
align
(
7
)
%
self
.
p
)
==
0
)
self
.
assertTrue
(
(
self
.
align
(
8
)
%
self
.
p
)
==
0
)
self
.
assertTrue
(
(
self
.
align
(
9
)
%
self
.
p
)
==
0
)
def
test_standardtypes
(
self
):
i
=
self
.
i
l
=
self
.
l
p
=
self
.
p
h
=
self
.
headersize
# bool
self
.
check_sizeof
(
True
,
h
+
l
)
# buffer
self
.
check_sizeof
(
buffer
(
''
),
h
+
2
*
p
+
2
*
l
+
self
.
align
(
i
)
+
l
)
# bytearray
self
.
check_sizeof
(
bytes
(),
h
+
self
.
align
(
i
)
+
l
+
p
)
# cell
def
get_cell
():
x
=
42
def
inner
():
return
x
return
inner
self
.
check_sizeof
(
get_cell
().
func_closure
[
0
],
h
+
p
)
# old-style class
class
class_oldstyle
():
def
method
():
pass
self
.
check_sizeof
(
class_oldstyle
,
h
+
6
*
p
)
# instance
self
.
check_sizeof
(
class_oldstyle
(),
h
+
3
*
p
)
# method
self
.
check_sizeof
(
class_oldstyle
().
method
,
h
+
4
*
p
)
# code
self
.
check_sizeof
(
get_cell
().
func_code
,
h
+
self
.
align
(
4
*
i
)
+
8
*
p
+
\
self
.
align
(
i
)
+
2
*
p
)
# complex
self
.
check_sizeof
(
complex
(
0
,
1
),
h
+
2
*
8
)
# enumerate
self
.
check_sizeof
(
enumerate
([]),
h
+
l
+
3
*
p
)
# reverse
self
.
check_sizeof
(
reversed
(
''
),
h
+
l
+
p
)
# file
self
.
check_sizeof
(
self
.
file
,
h
+
4
*
p
+
self
.
align
(
2
*
i
)
+
4
*
p
+
\
self
.
align
(
3
*
i
)
+
3
*
p
+
self
.
align
(
i
))
# float
self
.
check_sizeof
(
float
(
0
),
h
+
8
)
# function
def
func
():
pass
self
.
check_sizeof
(
func
,
h
+
9
*
l
)
class
c
():
@
staticmethod
def
foo
():
pass
@
classmethod
def
bar
(
cls
):
pass
# staticmethod
self
.
check_sizeof
(
foo
,
h
+
l
)
# classmethod
self
.
check_sizeof
(
bar
,
h
+
l
)
# generator
def
get_gen
():
yield
1
self
.
check_sizeof
(
get_gen
(),
h
+
p
+
self
.
align
(
i
)
+
2
*
p
)
# integer
self
.
check_sizeof
(
1
,
h
+
l
)
# builtin_function_or_method
self
.
check_sizeof
(
abs
,
h
+
3
*
p
)
# module
self
.
check_sizeof
(
unittest
,
h
+
p
)
# xange
self
.
check_sizeof
(
xrange
(
1
),
h
+
3
*
p
)
# slice
self
.
check_sizeof
(
slice
(
0
),
h
+
3
*
p
)
h
+=
l
# new-style class
class
class_newstyle
(
object
):
def
method
():
pass
# type (PyTypeObject + PyNumberMethods + PyMappingMethods +
# PySequenceMethods + PyBufferProcs)
len_typeobject
=
p
+
2
*
l
+
15
*
p
+
l
+
4
*
p
+
l
+
9
*
p
+
l
+
11
*
p
self
.
check_sizeof
(
class_newstyle
,
h
+
\
len_typeobject
+
42
*
p
+
10
*
p
+
3
*
p
+
6
*
p
)
def
test_specialtypes
(
self
):
i
=
self
.
i
l
=
self
.
l
p
=
self
.
p
h
=
self
.
headersize
# dict
self
.
check_sizeof
({},
h
+
3
*
l
+
3
*
p
+
8
*
(
l
+
2
*
p
))
longdict
=
{
1
:
1
,
2
:
2
,
3
:
3
,
4
:
4
,
5
:
5
,
6
:
6
,
7
:
7
,
8
:
8
}
self
.
check_sizeof
(
longdict
,
h
+
3
*
l
+
3
*
p
+
8
*
(
l
+
2
*
p
)
+
16
*
(
l
+
2
*
p
))
# list
self
.
check_sizeof
([],
h
+
l
+
p
+
l
)
self
.
check_sizeof
([
1
,
2
,
3
],
h
+
l
+
p
+
l
+
3
*
l
)
h
+=
l
# long
self
.
check_sizeof
(
0L
,
h
+
self
.
align
(
2
))
self
.
check_sizeof
(
1L
,
h
+
self
.
align
(
2
))
self
.
check_sizeof
(
-
1L
,
h
+
self
.
align
(
2
))
self
.
check_sizeof
(
32768L
,
h
+
self
.
align
(
2
)
+
2
)
self
.
check_sizeof
(
32768L
*
32768L
-
1
,
h
+
self
.
align
(
2
)
+
2
)
self
.
check_sizeof
(
32768L
*
32768L
,
h
+
self
.
align
(
2
)
+
4
)
# string
self
.
check_sizeof
(
''
,
h
+
l
+
self
.
align
(
i
+
1
))
self
.
check_sizeof
(
'abc'
,
h
+
l
+
self
.
align
(
i
+
1
)
+
3
)
def
test_main
():
test
.
test_support
.
run_unittest
(
SysModuleTest
)
test_classes
=
(
SysModuleTest
,
SizeofTest
)
test
.
test_support
.
run_unittest
(
*
test_classes
)
if
__name__
==
"__main__"
:
test_main
()
Misc/NEWS
View file @
51df0647
...
...
@@ -12,6 +12,8 @@ What's New in Python 2.6 beta 1?
Core and Builtins
-----------------
- Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
- New environment variable PYTHONIOENCODING.
- Patch #2488: Add sys.maxsize.
...
...
Objects/bytesobject.c
View file @
51df0647
...
...
@@ -3917,6 +3917,17 @@ string_splitlines(PyBytesObject *self, PyObject *args)
return
NULL
;
}
PyDoc_STRVAR
(
sizeof__doc__
,
"S.__sizeof__() -> size of S in bytes"
);
static
PyObject
*
string_sizeof
(
PyBytesObject
*
v
)
{
Py_ssize_t
res
;
res
=
sizeof
(
PyBytesObject
)
+
v
->
ob_size
*
v
->
ob_type
->
tp_itemsize
;
return
PyInt_FromSsize_t
(
res
);
}
#undef SPLIT_APPEND
#undef SPLIT_ADD
#undef MAX_PREALLOC
...
...
@@ -4024,6 +4035,8 @@ string_methods[] = {
expandtabs__doc__
},
{
"splitlines"
,
(
PyCFunction
)
string_splitlines
,
METH_VARARGS
,
splitlines__doc__
},
{
"__sizeof__"
,
(
PyCFunction
)
string_sizeof
,
METH_NOARGS
,
sizeof__doc__
},
{
"__getnewargs__"
,
(
PyCFunction
)
string_getnewargs
,
METH_NOARGS
},
{
NULL
,
NULL
}
/* sentinel */
};
...
...
Objects/dictobject.c
View file @
51df0647
...
...
@@ -2032,6 +2032,16 @@ dict_iteritems(PyDictObject *dict)
return
dictiter_new
(
dict
,
&
PyDictIterItem_Type
);
}
static
PyObject
*
dict_sizeof
(
PyDictObject
*
mp
)
{
Py_ssize_t
res
;
res
=
sizeof
(
PyDictObject
)
+
sizeof
(
mp
->
ma_table
);
if
(
mp
->
ma_table
!=
mp
->
ma_smalltable
)
res
=
res
+
(
mp
->
ma_mask
+
1
)
*
sizeof
(
PyDictEntry
);
return
PyInt_FromSsize_t
(
res
);
}
PyDoc_STRVAR
(
has_key__doc__
,
"D.has_key(k) -> True if D has a key k, else False"
);
...
...
@@ -2041,6 +2051,9 @@ PyDoc_STRVAR(contains__doc__,
PyDoc_STRVAR
(
getitem__doc__
,
"x.__getitem__(y) <==> x[y]"
);
PyDoc_STRVAR
(
sizeof__doc__
,
"D.__sizeof__() -> size of D in bytes"
);
PyDoc_STRVAR
(
get__doc__
,
"D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None."
);
...
...
@@ -2092,6 +2105,8 @@ static PyMethodDef mapp_methods[] = {
contains__doc__
},
{
"__getitem__"
,
(
PyCFunction
)
dict_subscript
,
METH_O
|
METH_COEXIST
,
getitem__doc__
},
{
"__sizeof__"
,
(
PyCFunction
)
dict_sizeof
,
METH_NOARGS
,
sizeof__doc__
},
{
"has_key"
,
(
PyCFunction
)
dict_has_key
,
METH_O
,
has_key__doc__
},
{
"get"
,
(
PyCFunction
)
dict_get
,
METH_VARARGS
,
...
...
Objects/listobject.c
View file @
51df0647
...
...
@@ -2420,6 +2420,15 @@ list_init(PyListObject *self, PyObject *args, PyObject *kw)
return
0
;
}
static
PyObject
*
list_sizeof
(
PyListObject
*
self
)
{
Py_ssize_t
res
;
res
=
sizeof
(
PyListObject
)
+
self
->
allocated
*
sizeof
(
void
*
);
return
PyInt_FromSsize_t
(
res
);
}
static
PyObject
*
list_iter
(
PyObject
*
seq
);
static
PyObject
*
list_reversed
(
PyListObject
*
seq
,
PyObject
*
unused
);
...
...
@@ -2427,6 +2436,8 @@ PyDoc_STRVAR(getitem_doc,
"x.__getitem__(y) <==> x[y]"
);
PyDoc_STRVAR
(
reversed_doc
,
"L.__reversed__() -- return a reverse iterator over the list"
);
PyDoc_STRVAR
(
sizeof_doc
,
"L.__sizeof__() -- size of L in bytes"
);
PyDoc_STRVAR
(
append_doc
,
"L.append(object) -- append object to end"
);
PyDoc_STRVAR
(
extend_doc
,
...
...
@@ -2452,6 +2463,7 @@ static PyObject *list_subscript(PyListObject*, PyObject*);
static
PyMethodDef
list_methods
[]
=
{
{
"__getitem__"
,
(
PyCFunction
)
list_subscript
,
METH_O
|
METH_COEXIST
,
getitem_doc
},
{
"__reversed__"
,(
PyCFunction
)
list_reversed
,
METH_NOARGS
,
reversed_doc
},
{
"__sizeof__"
,
(
PyCFunction
)
list_sizeof
,
METH_NOARGS
,
sizeof_doc
},
{
"append"
,
(
PyCFunction
)
listappend
,
METH_O
,
append_doc
},
{
"insert"
,
(
PyCFunction
)
listinsert
,
METH_VARARGS
,
insert_doc
},
{
"extend"
,
(
PyCFunction
)
listextend
,
METH_O
,
extend_doc
},
...
...
Objects/longobject.c
View file @
51df0647
...
...
@@ -3436,6 +3436,17 @@ long__format__(PyObject *self, PyObject *args)
return
NULL
;
}
static
PyObject
*
long_sizeof
(
PyLongObject
*
v
)
{
Py_ssize_t
res
;
res
=
sizeof
(
PyLongObject
)
+
abs
(
v
->
ob_size
)
*
sizeof
(
digit
);
if
(
v
->
ob_size
!=
0
)
res
-=
sizeof
(
digit
);
return
PyInt_FromSsize_t
(
res
);
}
#if 0
static PyObject *
long_is_finite(PyObject *v)
...
...
@@ -3455,6 +3466,8 @@ static PyMethodDef long_methods[] = {
"Truncating an Integral returns itself."
},
{
"__getnewargs__"
,
(
PyCFunction
)
long_getnewargs
,
METH_NOARGS
},
{
"__format__"
,
(
PyCFunction
)
long__format__
,
METH_VARARGS
},
{
"__sizeof__"
,
(
PyCFunction
)
long_sizeof
,
METH_NOARGS
,
"Returns size in bytes"
},
{
NULL
,
NULL
}
/* sentinel */
};
...
...
Objects/typeobject.c
View file @
51df0647
...
...
@@ -3397,6 +3397,20 @@ object_format(PyObject *self, PyObject *args)
return
result
;
}
static
PyObject
*
object_sizeof
(
PyObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
res
,
isize
;
res
=
0
;
isize
=
self
->
ob_type
->
tp_itemsize
;
if
(
isize
>
0
)
res
=
self
->
ob_type
->
ob_size
*
isize
;
res
+=
self
->
ob_type
->
tp_basicsize
;
return
PyInt_FromSsize_t
(
res
);
}
static
PyMethodDef
object_methods
[]
=
{
{
"__reduce_ex__"
,
object_reduce_ex
,
METH_VARARGS
,
PyDoc_STR
(
"helper for pickle"
)},
...
...
@@ -3406,6 +3420,8 @@ static PyMethodDef object_methods[] = {
object_subclasshook_doc
},
{
"__format__"
,
object_format
,
METH_VARARGS
,
PyDoc_STR
(
"default object formatter"
)},
{
"__sizeof__"
,
object_sizeof
,
METH_NOARGS
,
PyDoc_STR
(
"__sizeof__() -> size of object in bytes"
)},
{
0
}
};
...
...
Python/sysmodule.c
View file @
51df0647
...
...
@@ -639,6 +639,45 @@ sys_mdebug(PyObject *self, PyObject *args)
}
#endif
/* USE_MALLOPT */
static
PyObject
*
sys_getsizeof
(
PyObject
*
self
,
PyObject
*
args
)
{
static
PyObject
*
str__sizeof__
=
NULL
;
/* Initialize static variable needed by _PyType_Lookup */
if
(
str__sizeof__
==
NULL
)
{
str__sizeof__
=
PyString_InternFromString
(
"__sizeof__"
);
if
(
str__sizeof__
==
NULL
)
return
NULL
;
}
/* Type objects */
if
(
PyType_Check
(
args
)){
PyObject
*
method
=
_PyType_Lookup
(
Py_TYPE
(
args
),
str__sizeof__
);
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
);
}
/* Instance of old-style classes */
else
if
(
PyInstance_Check
(
args
))
return
PyInt_FromSsize_t
(
PyInstance_Type
.
tp_basicsize
);
/* Old-style class */
else
if
(
PyClass_Check
(
args
))
return
PyInt_FromSsize_t
(
PyClass_Type
.
tp_basicsize
);
else
return
PyObject_CallMethod
(
args
,
"__sizeof__"
,
NULL
);
}
PyDoc_STRVAR
(
getsizeof_doc
,
"getsizeof(object) -> int
\n
\
\n
\
Return the size of object in bytes."
);
static
PyObject
*
sys_getrefcount
(
PyObject
*
self
,
PyObject
*
arg
)
{
...
...
@@ -850,6 +889,7 @@ 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
},
{
"_getframe"
,
sys_getframe
,
METH_VARARGS
,
getframe_doc
},
#ifdef MS_WINDOWS
{
"getwindowsversion"
,
(
PyCFunction
)
sys_getwindowsversion
,
METH_NOARGS
,
...
...
@@ -1031,6 +1071,7 @@ getdlopenflags() -- returns flags to be used for dlopen() calls\n\
getprofile() -- get the global profiling function
\n
\
getrefcount() -- return the reference count for an object (plus one :-)
\n
\
getrecursionlimit() -- return the max recursion depth for the interpreter
\n
\
getsizeof() -- return the size of an object in bytes
\n
\
gettrace() -- get the global debug tracing function
\n
\
setcheckinterval() -- control how often the interpreter checks for events
\n
\
setdlopenflags() -- set the flags to be used for dlopen() calls
\n
\
...
...
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