[Jython-checkins] jython: Shortened and improved API for easy construction of Python-backed Java objects.
stefan.richthofer
jython-checkins at python.org
Sat Oct 31 01:39:19 EDT 2015
https://hg.python.org/jython/rev/b9c2c8001034
changeset: 7785:b9c2c8001034
user: Stefan Richthofer <stefan.richthofer at gmx.de>
date: Sat Oct 31 06:39:07 2015 +0100
summary:
Shortened and improved API for easy construction of Python-backed Java objects.
files:
src/org/python/core/JyAttribute.java | 12 +-
src/org/python/core/Py.java | 84 ++++++++-------
src/org/python/core/PyModule.java | 42 ++++++++
3 files changed, 97 insertions(+), 41 deletions(-)
diff --git a/src/org/python/core/JyAttribute.java b/src/org/python/core/JyAttribute.java
--- a/src/org/python/core/JyAttribute.java
+++ b/src/org/python/core/JyAttribute.java
@@ -69,23 +69,29 @@
public static final byte WEAKREF_PENDING_GET_ATTR = 3;
/**
+ * Only used internally by
+ * {@linkorg.python.core.Py#javaPyClass(PyObject, Class<?>)}
+ */
+ public static final byte PYCLASS_PY2JY_CACHE_ATTR = 4;
+
+ /**
* Used by {@link org.python.modules.gc}-module to mark cyclic
* trash. Searching for cyclic trash is usually not required
* by Jython. It is only done if gc-features are enabled that
* mimic CPython behavior.
*/
- public static final byte GC_CYCLE_MARK_ATTR = 4;
+ public static final byte GC_CYCLE_MARK_ATTR = 5;
/**
* Used by {@link org.python.modules.gc}-module to mark
* finalizable objects that might have been resurrected
* during a delayed finalization process.
*/
- public static final byte GC_DELAYED_FINALIZE_CRITICAL_MARK_ATTR = 5;
+ public static final byte GC_DELAYED_FINALIZE_CRITICAL_MARK_ATTR = 6;
public static final byte FINALIZE_TRIGGER_ATTR = Byte.MAX_VALUE;
private static byte nonBuiltinAttrTypeOffset = Byte.MIN_VALUE+1;
- private static byte nonBuiltinTransientAttrTypeOffset = 6;
+ private static byte nonBuiltinTransientAttrTypeOffset = 7;
/**
* Reserves and returns a new non-transient attr type for custom use.
diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java
--- a/src/org/python/core/Py.java
+++ b/src/org/python/core/Py.java
@@ -15,6 +15,7 @@
import java.io.StreamCorruptedException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.ref.WeakReference;
import java.net.URL;
import java.net.URLDecoder;
import java.sql.Date;
@@ -22,9 +23,7 @@
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import com.google.common.base.CharMatcher;
@@ -2503,8 +2502,6 @@
}
}
- protected static Map<PyObject, py2JyClassCacheItem> py2JyClassCache = new HashMap<>();
-
protected static PyObject ensureInterface(PyObject cls, Class<?> interfce) {
PyObject pjc = PyType.fromClass(interfce);
if (Py.isSubClass(cls, pjc)) {
@@ -2523,13 +2520,14 @@
*
* @return a Python-class that extends {@code cls} and {@code interfce}
*/
- public static PyObject javaPyClass(PyObject cls, Class<?> interfce) {
- py2JyClassCacheItem cacheItem = py2JyClassCache.get(cls);
+ public static synchronized PyObject javaPyClass(PyObject cls, Class<?> interfce) {
+ py2JyClassCacheItem cacheItem = (py2JyClassCacheItem)
+ JyAttribute.getAttr(cls, JyAttribute.PYCLASS_PY2JY_CACHE_ATTR);
PyObject result;
if (cacheItem == null) {
result = ensureInterface(cls, interfce);
cacheItem = new py2JyClassCacheItem(interfce, result);
- py2JyClassCache.put(cls, cacheItem);
+ JyAttribute.setAttr(cls, JyAttribute.PYCLASS_PY2JY_CACHE_ATTR, cacheItem);
} else {
result = cacheItem.get(interfce);
if (result == null) {
@@ -2549,12 +2547,14 @@
* class on the fly.<br>
* It automatically converts {@code args} to {@link org.python.core.PyObject}s.<br>
* For keyword-support use
- * {@link #newJavaObject(PyObject, Class, String[], Object...)}.
+ * {@link #newJ(PyObject, Class, String[], Object...)}.
*
- * {@see #newJavaObject(PyObject, Class, PyObject[], String[])}
- * {@see #newJavaObject(PyObject, Class, String[], Object...)}
- * {@see #newJavaObject(PyModule, Class, Object...)}
- * {@see #newJavaObject(PyModule, Class, String[], Object...)}
+ * {@see #newJ(PyObject, Class, PyObject[], String[])}
+ * {@see #newJ(PyObject, Class, String[], Object...)}
+ * {@see #newJ(PyModule, Class, Object...)}
+ * {@see #newJ(PyModule, Class, String[], Object...)}
+ * {@see org.python.core.PyModule#newJ(Class, Object...)}
+ * {@see org.python.core.PyModule#newJ(Class, String[], Object...)}
*
* @param cls - the class to be instanciated
* @param jcls - the Java-type to be returned
@@ -2562,7 +2562,7 @@
* @return an instance of cls in form of the interface jcls
*/
@SuppressWarnings("unchecked")
- public static <T> T newJavaObject(PyObject cls, Class<T> jcls, Object... args) {
+ public static <T> T newJ(PyObject cls, Class<T> jcls, Object... args) {
PyObject cls2 = javaPyClass(cls, jcls);
PyObject resultPy = cls2.__call__(Py.javas2pys(args));
return (T) resultPy.__tojava__(jcls);
@@ -2577,10 +2577,12 @@
* class on the fly.<br>
* {@code keywordss} are applied to the last {@code args} in the list.
*
- * {@see #newJavaObject(PyObject, Class, Object...)}
- * {@see #newJavaObject(PyObject, Class, String[], Object...)}
- * {@see #newJavaObject(PyModule, Class, Object...)}
- * {@see #newJavaObject(PyModule, Class, String[], Object...)}
+ * {@see #newJ(PyObject, Class, Object...)}
+ * {@see #newJ(PyObject, Class, String[], Object...)}
+ * {@see #newJ(PyModule, Class, Object...)}
+ * {@see #newJ(PyModule, Class, String[], Object...)}
+ * {@see org.python.core.PyModule#newJ(Class, Object...)}
+ * {@see org.python.core.PyModule#newJ(Class, String[], Object...)}
*
* @param cls - the class to be instanciated
* @param jcls - the Java-type to be returned
@@ -2589,7 +2591,7 @@
* @return an instance of cls in form of the interface jcls
*/
@SuppressWarnings("unchecked")
- public static <T> T newJavaObject(PyObject cls, Class<T> jcls, PyObject[] args, String[] keywords) {
+ public static <T> T newJ(PyObject cls, Class<T> jcls, PyObject[] args, String[] keywords) {
PyObject cls2 = javaPyClass(cls, jcls);
PyObject resultPy = cls2.__call__(args, keywords);
return (T) resultPy.__tojava__(jcls);
@@ -2605,10 +2607,12 @@
* It automatically converts {@code args} to {@link org.python.core.PyObject}s.<br>
* {@code keywordss} are applied to the last {@code args} in the list.
*
- * {@see #newJavaObject(PyObject, Class, PyObject[], String[])}
- * {@see #newJavaObject(PyObject, Class, Object...)}
- * {@see #newJavaObject(PyModule, Class, Object...)}
- * {@see #newJavaObject(PyModule, Class, String[], Object...)}
+ * {@see #newJ(PyObject, Class, PyObject[], String[])}
+ * {@see #newJ(PyObject, Class, Object...)}
+ * {@see #newJ(PyModule, Class, Object...)}
+ * {@see #newJ(PyModule, Class, String[], Object...)}
+ * {@see org.python.core.PyModule#newJ(Class, Object...)}
+ * {@see org.python.core.PyModule#newJ(Class, String[], Object...)}
*
* @param cls - the class to be instanciated
* @param jcls - the Java-type to be returned
@@ -2617,22 +2621,24 @@
* @return an instance of cls in form of the interface jcls
*/
@SuppressWarnings("unchecked")
- public static <T> T newJavaObject(PyObject cls, Class<T> jcls, String[] keywords, Object... args) {
+ public static <T> T newJ(PyObject cls, Class<T> jcls, String[] keywords, Object... args) {
PyObject cls2 = javaPyClass(cls, jcls);
PyObject resultPy = cls2.__call__(Py.javas2pys(args), keywords);
return (T) resultPy.__tojava__(jcls);
}
/**
- * Works like {@link #newJavaObject(PyObject, Class, Object...)}, but looks
+ * Works like {@link #newJ(PyObject, Class, Object...)}, but looks
* up the Python-class in the module-dict using the interface-name, i.e.
* {@code jcls.getSimpleName()}.<br>
- * For keywords-support use {@link #newJavaObject(PyModule, Class, String[], Object...)}.
+ * For keywords-support use {@link #newJ(PyModule, Class, String[], Object...)}.
*
- * {@see #newJavaObject(PyModule, Class, String[], Object...)}
- * {@see #newJavaObject(PyObject, Class, PyObject[], String[])}
- * {@see #newJavaObject(PyObject, Class, Object...)}
- * {@see #newJavaObject(PyObject, Class, String[], Object...)}
+ * {@see #newJ(PyModule, Class, String[], Object...)}
+ * {@see #newJ(PyObject, Class, PyObject[], String[])}
+ * {@see #newJ(PyObject, Class, Object...)}
+ * {@see #newJ(PyObject, Class, String[], Object...)}
+ * {@see org.python.core.PyModule#newJ(Class, Object...)}
+ * {@see org.python.core.PyModule#newJ(Class, String[], Object...)}
*
* @param module the module containing the desired class
* @param jcls Java-type of the desired clas, must have the same name
@@ -2640,21 +2646,23 @@
* @return a new instance of the desired class
*/
@SuppressWarnings("unchecked")
- public static <T> T newJavaObject(PyModule module, Class<T> jcls, Object... args) {
+ public static <T> T newJ(PyModule module, Class<T> jcls, Object... args) {
PyObject cls = module.__getattr__(jcls.getSimpleName().intern());
- return newJavaObject(cls, jcls, args);
+ return newJ(cls, jcls, args);
}
/**
- * Works like {@link #newJavaObject(PyObject, Class, String[], Object...)}, but looks
+ * Works like {@link #newJ(PyObject, Class, String[], Object...)}, but looks
* up the Python-class in the module-dict using the interface-name, i.e.
* {@code jcls.getSimpleName()}.<br>
* {@code keywordss} are applied to the last {@code args} in the list.
*
- * {@see #newJavaObject(PyModule, Class, Object...)}
- * {@see #newJavaObject(PyObject, Class, PyObject[], String[])}
- * {@see #newJavaObject(PyObject, Class, Object...)}
- * {@see #newJavaObject(PyObject, Class, String[], Object...)}
+ * {@see #newJ(PyModule, Class, Object...)}
+ * {@see #newJ(PyObject, Class, PyObject[], String[])}
+ * {@see #newJ(PyObject, Class, Object...)}
+ * {@see #newJ(PyObject, Class, String[], Object...)}
+ * {@see org.python.core.PyModule#newJ(Class, Object...)}
+ * {@see org.python.core.PyModule#newJ(Class, String[], Object...)}
*
* @param module the module containing the desired class
* @param jcls Java-type of the desired class, must have the same name
@@ -2663,9 +2671,9 @@
* @return a new instance of the desired class
*/
@SuppressWarnings("unchecked")
- public static <T> T newJavaObject(PyModule module, Class<T> jcls, String[] keywords, Object... args) {
+ public static <T> T newJ(PyModule module, Class<T> jcls, String[] keywords, Object... args) {
PyObject cls = module.__getattr__(jcls.getSimpleName().intern());
- return newJavaObject(cls, jcls, keywords, args);
+ return newJ(cls, jcls, keywords, args);
}
//----------------end of constructor-section------------------
}
diff --git a/src/org/python/core/PyModule.java b/src/org/python/core/PyModule.java
--- a/src/org/python/core/PyModule.java
+++ b/src/org/python/core/PyModule.java
@@ -205,6 +205,48 @@
}
}
+ /**
+ * Delegates to {@link #newJ(PyModule, Class, Object...)}, .<br>
+ * For keywords-support use {@link #newJ(Class, String[], Object...)}.
+ *
+ * {@see #newJ(Class, String[], Object...)}
+ * {@see org.python.core.Py#newJ(PyModule, Class, Object...)}
+ * {@see org.python.core.Py#newJ(PyModule, Class, String[], Object...)}
+ * {@see org.python.core.Py#newJ(PyObject, Class, PyObject[], String[])}
+ * {@see org.python.core.Py#newJ(PyObject, Class, Object...)}
+ * {@see org.python.core.Py#newJ(PyObject, Class, String[], Object...)}
+ *
+ * @param module the module containing the desired class
+ * @param jcls Java-type of the desired clas, must have the same name
+ * @param args constructor-arguments
+ * @return a new instance of the desired class
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T newJ(Class<T> jcls, Object... args) {
+ return Py.newJ(this, jcls, args);
+ }
+
+ /**
+ * Delgates to {@link org.python.core.Py#newJ(PyModule, Class, String[], Object...)}.<br>
+ * {@code keywordss} are applied to the last {@code args} in the list.
+ *
+ * {@see #newJ(Class, Object...)}
+ * {@see org.python.core.Py#newJ(PyModule, Class, Object...)}
+ * {@see org.python.core.Py#newJ(PyModule, Class, String[], Object...)}
+ * {@see org.python.core.Py#newJ(PyObject, Class, PyObject[], String[])}
+ * {@see org.python.core.Py#newJ(PyObject, Class, Object...)}
+ * {@see org.python.core.Py#newJ(PyObject, Class, String[], Object...)}
+ *
+ * @param jcls Java-type of the desired class, must have the same name
+ * @param keywords are applied to the last {@code args} in the list
+ * @param args constructor-arguments
+ * @return a new instance of the desired class
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T newJ(Class<T> jcls, String[] keywords, Object... args) {
+ return Py.newJ(this, jcls, keywords, args);
+ }
+
/* Traverseproc implementation */
@Override
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list