[Jython-checkins] jython: Add sys.getsizeof by intertally using java-size.jar extlib (Apache2 license),
darjus.loktevic
jython-checkins at python.org
Sun Jan 3 20:47:56 EST 2016
https://hg.python.org/jython/rev/c01bab7025e4
changeset: 7846:c01bab7025e4
user: Darjus Loktevic <darjus at gmail.com>
date: Mon Jan 04 12:47:40 2016 +1100
summary:
Add sys.getsizeof by intertally using java-size.jar extlib (Apache2 license), and add gc.get_objects by returning the monitoredObjects list (not quite CPython behaviour but close) to support muppy #2450
files:
Lib/test/test_support.py | 2 +-
Lib/test/test_sys.py | 76 ++++++++++++-
build.xml | 2 +
extlibs/java-sizeof-0.0.5.jar | Bin
src/org/python/core/PySystemState.java | 11 +-
src/org/python/modules/gc.java | 23 ++-
6 files changed, 104 insertions(+), 10 deletions(-)
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -1000,7 +1000,7 @@
gc.collect()
-_header = '2P'
+_header = '1P'
if hasattr(sys, "gettotalrefcount"):
_header = '2P' + _header
_vheader = _header + 'P'
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1,6 +1,8 @@
# -*- coding: iso-8859-1 -*-
import unittest, test.test_support
import sys, cStringIO
+import struct
+
class SysModuleTest(unittest.TestCase):
@@ -273,12 +275,84 @@
self.assertEqual(out, '?')
+class SizeofTest(unittest.TestCase):
+ """Jython modified version of getsizeof"""
+
+ def setUp(self):
+ self.P = struct.calcsize('P')
+ self.longdigit = sys.long_info.sizeof_digit
+ self.file = open(test.test_support.TESTFN, 'wb')
+
+ def tearDown(self):
+ self.file.close()
+ test.test_support.unlink(test.test_support.TESTFN)
+
+ check_sizeof = test.test_support.check_sizeof
+
+ def test_default(self):
+ size = test.test_support.calcobjsize
+ self.assertEqual(sys.getsizeof(True, -1), size('l'))
+
+ def test_objecttypes(self):
+ # check all types defined in Objects/
+ size = test.test_support.calcobjsize
+ vsize = test.test_support.calcvobjsize
+ check = self.check_sizeof
+ # bool
+ check(True, size('l'))
+ # buffer
+ with test.test_support.check_py3k_warnings():
+ check(buffer(''), size('1P2Pil'))
+ # builtin_function_or_method
+ check(len, size('3P'))
+ # bytearray_iterator
+ check(iter(bytearray()), size('2PP'))
+ # cell
+ def get_cell():
+ x = 42
+ def inner():
+ return x
+ return inner
+ check(get_cell().func_closure[0], size('2P'))
+ # classobj (old-style class)
+ class class_oldstyle():
+ def method():
+ pass
+ check(class_oldstyle, size('6P'))
+ # instance (old-style class)
+ check(class_oldstyle(), size('3P'))
+ # instancemethod (old-style class)
+ check(class_oldstyle().method, size('3P'))
+ # complex
+ check(complex(0,1), size('2P2d'))
+ # code
+ check(get_cell().func_code, size('4i3Pi3P'))
+ # BaseException
+ check(BaseException(), size('3P'))
+
+ def test_pythontypes(self):
+ # check all types defined in Python/
+ size = test.test_support.calcobjsize
+ vsize = test.test_support.calcvobjsize
+ check = self.check_sizeof
+ # imp.NullImporter
+ import imp
+ check(imp.NullImporter(self.file.name), size('3P'))
+ try:
+ raise TypeError
+ except TypeError:
+ tb = sys.exc_info()[2]
+ # traceback
+ if tb != None:
+ check(tb, size('2P2i'))
+
+
def test_main():
if test.test_support.is_jython:
del SysModuleTest.test_lost_displayhook
del SysModuleTest.test_refcount
del SysModuleTest.test_setcheckinterval
- test.test_support.run_unittest(SysModuleTest)
+ test.test_support.run_unittest(SysModuleTest, SizeofTest)
if __name__ == "__main__":
test_main()
diff --git a/build.xml b/build.xml
--- a/build.xml
+++ b/build.xml
@@ -155,6 +155,7 @@
<pathelement path="${extlibs.dir}/guava-19.0.jar" />
<pathelement path="${extlibs.dir}/icu4j-56.1.jar" />
<pathelement path="${extlibs.dir}/jffi-1.2.10.jar"/>
+ <pathelement path="${extlibs.dir}/java-sizeof-0.0.5.jar"/>
<pathelement path="${extlibs.dir}/jnr-ffi-2.0.7.jar"/>
<pathelement path="${extlibs.dir}/jnr-netdb-1.1.5.jar"/>
<pathelement path="${extlibs.dir}/jnr-posix-3.0.23.jar"/>
@@ -604,6 +605,7 @@
<zipfileset src="extlibs/jffi-x86_64-Windows.jar"/>
<!-- remainder of JNR, JFFI -->
<zipfileset src="extlibs/jffi-1.2.10.jar"/>
+ <zipfileset src="${extlibs.dir}/java-sizeof-0.0.5.jar"/>
<zipfileset src="${extlibs.dir}/jnr-ffi-2.0.7.jar"/>
<zipfileset src="${extlibs.dir}/jnr-netdb-1.1.5.jar"/>
<zipfileset src="${extlibs.dir}/jnr-posix-3.0.23.jar"/>
diff --git a/extlibs/java-sizeof-0.0.5.jar b/extlibs/java-sizeof-0.0.5.jar
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..23c555cc17af37962ea51431caf3755b1e85fb20
GIT binary patch
[stripped]
diff --git a/src/org/python/core/PySystemState.java b/src/org/python/core/PySystemState.java
--- a/src/org/python/core/PySystemState.java
+++ b/src/org/python/core/PySystemState.java
@@ -31,8 +31,8 @@
import java.util.concurrent.locks.ReentrantLock;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
-
import jnr.posix.util.Platform;
+import com.carrotsearch.sizeof.RamUsageEstimator;
import org.python.Version;
import org.python.core.adapter.ClassicPyObjectAdapter;
@@ -432,6 +432,15 @@
return recursionlimit;
}
+ @SuppressWarnings("unused")
+ public long getsizeof(Object obj, long defaultVal) {
+ return getsizeof(obj);
+ }
+
+ public long getsizeof(Object obj) {
+ return RamUsageEstimator.shallowSizeOf(obj);
+ }
+
public void setrecursionlimit(int recursionlimit) {
if (recursionlimit <= 0) {
throw Py.ValueError("Recursion limit must be positive");
diff --git a/src/org/python/modules/gc.java b/src/org/python/modules/gc.java
--- a/src/org/python/modules/gc.java
+++ b/src/org/python/modules/gc.java
@@ -1,10 +1,6 @@
package org.python.modules;
-import java.util.Set;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.IdentityHashMap;
-import java.util.HashSet;
+import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
@@ -2558,13 +2554,26 @@
}
/**
- * Not supported by Jython.
+ * Only works reliably if {@code monitorGlobal} is active, as it depends on
+ * monitored objects to search for referrers. It only finds referrers that
+ * properly implement the traverseproc mechanism (unless reflection-based
+ * traversion is activated and works stable).
* Throws {@link org.python.core.Py#NotImplementedError}.
*
* @throws org.python.core.Py.NotImplementedError
*/
public static PyObject get_objects() {
- throw Py.NotImplementedError("not applicable to Java GC");
+ if (!isMonitoring()) {
+ throw Py.NotImplementedError(
+ "not applicable in Jython if gc module is not monitoring PyObjects");
+ }
+ LinkedList<PyObject> resultList = new LinkedList<>();
+ synchronized (monitoredObjects) {
+ for (WeakReferenceGC src: monitoredObjects) {
+ resultList.add((PyObject) src.get());
+ }
+ }
+ return new PyList(resultList);
}
/**
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list