mirror of https://github.com/kivy/pyjnius.git
First pass at a nicer signatures API with tests
This commit is contained in:
parent
9f9d61618f
commit
176dc70919
|
@ -0,0 +1,72 @@
|
|||
'''
|
||||
signatures.py
|
||||
=============
|
||||
|
||||
A handy API for writing JNI signatures easily
|
||||
|
||||
Author: chrisjrn
|
||||
|
||||
'''
|
||||
|
||||
__version__ = '0.0.1'
|
||||
|
||||
from . import JavaClass
|
||||
from . import java_method
|
||||
|
||||
|
||||
''' Type specifiers for primitives '''
|
||||
|
||||
class _SignaturePrimitive(object):
|
||||
_spec = ""
|
||||
|
||||
def _MakeSignaturePrimitive(name, spec):
|
||||
class __Primitive(_SignaturePrimitive):
|
||||
''' PyJnius signature for Java %s type ''' % name
|
||||
_name = name
|
||||
_spec = spec
|
||||
__name__ = "j" + name
|
||||
return __Primitive
|
||||
|
||||
jboolean = _MakeSignaturePrimitive("boolean", "Z")
|
||||
jbyte = _MakeSignaturePrimitive("byte", "B")
|
||||
jchar = _MakeSignaturePrimitive("char", "C")
|
||||
jdouble = _MakeSignaturePrimitive("double", "D")
|
||||
jfloat = _MakeSignaturePrimitive("float", "F")
|
||||
jint = _MakeSignaturePrimitive("int", "I")
|
||||
jlong = _MakeSignaturePrimitive("long", "J")
|
||||
jshort = _MakeSignaturePrimitive("short", "S")
|
||||
jvoid = _MakeSignaturePrimitive("void", "V")
|
||||
|
||||
def JArray(of_type):
|
||||
''' Marks that this is an array of the given Primitive of JavaClass
|
||||
type specified. '''
|
||||
|
||||
spec = "[" + _jni_type_spec(of_type)
|
||||
return _MakeSignaturePrimitive("array", spec)
|
||||
|
||||
def java_signature(returns, takes):
|
||||
''' Alternative version of @java_method that takes JavaClass
|
||||
objects to produce the method signature. '''
|
||||
|
||||
sig = _produce_sig(returns, takes)
|
||||
return java_method(sig)
|
||||
|
||||
def _produce_sig(returns, takes):
|
||||
''' Produces a JNI method signature. '''
|
||||
out_takes = []
|
||||
for arg in takes:
|
||||
out_takes.append(_jni_type_spec(arg))
|
||||
|
||||
return "(" + "".join(out_takes) + ")" + _jni_type_spec(returns)
|
||||
|
||||
def _jni_type_spec(jclass):
|
||||
''' Produces a JNI type specification string for the given argument.
|
||||
If the argument is a jnius.JavaClass, it produces the JNI type spec
|
||||
for the class. Signature primitives return their stored type spec.
|
||||
'''
|
||||
|
||||
if issubclass(jclass, JavaClass):
|
||||
return "L" + jclass.__javaclass__ + ";"
|
||||
elif issubclass(jclass, _SignaturePrimitive):
|
||||
return jclass._spec
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
import unittest
|
||||
|
||||
from jnius import autoclass, java_method, PythonJavaClass, cast
|
||||
|
||||
from jnius.signatures import *
|
||||
|
||||
JObject = autoclass('java/lang/Object')
|
||||
JString = autoclass('java/lang/String')
|
||||
|
||||
class TestImplemIterator(PythonJavaClass):
|
||||
__javainterfaces__ = [
|
||||
'java/util/ListIterator', ]
|
||||
|
||||
def __init__(self, collection, index=0):
|
||||
super(TestImplemIterator, self).__init__()
|
||||
self.collection = collection
|
||||
self.index = index
|
||||
|
||||
@java_signature(jboolean, ())
|
||||
def hasNext(self):
|
||||
return self.index < len(self.collection.data) - 1
|
||||
|
||||
@java_signature(JObject, ())
|
||||
def next(self):
|
||||
obj = self.collection.data[self.index]
|
||||
self.index += 1
|
||||
return obj
|
||||
|
||||
@java_signature(jboolean, ())
|
||||
def hasPrevious(self):
|
||||
return self.index >= 0
|
||||
|
||||
@java_signature(JObject, ())
|
||||
def previous(self):
|
||||
self.index -= 1
|
||||
obj = self.collection.data[self.index]
|
||||
return obj
|
||||
|
||||
@java_signature(jint, ())
|
||||
def previousIndex(self):
|
||||
return self.index - 1
|
||||
|
||||
@java_signature(JString, ())
|
||||
def toString(self):
|
||||
return repr(self)
|
||||
|
||||
@java_signature(JObject, (jint, ))
|
||||
def get(self, index):
|
||||
return self.collection.data[index - 1]
|
||||
|
||||
@java_signature(jvoid, (JObject, ))
|
||||
def set(self, obj):
|
||||
self.collection.data[self.index - 1] = obj
|
||||
|
||||
|
||||
class TestImplem(PythonJavaClass):
|
||||
__javainterfaces__ = ['java/util/List']
|
||||
|
||||
def __init__(self, *args):
|
||||
super(TestImplem, self).__init__(*args)
|
||||
self.data = list(args)
|
||||
|
||||
@java_signature(autoclass("java.util.Iterator"), ())
|
||||
def iterator(self):
|
||||
it = TestImplemIterator(self)
|
||||
return it
|
||||
|
||||
@java_signature(JString, ())
|
||||
def toString(self):
|
||||
return repr(self)
|
||||
|
||||
@java_signature(jint, ())
|
||||
def size(self):
|
||||
return len(self.data)
|
||||
|
||||
@java_signature(JObject, (jint,))
|
||||
def get(self, index):
|
||||
return self.data[index]
|
||||
|
||||
@java_signature(JObject, (jint, JObject))
|
||||
def set(self, index, obj):
|
||||
old_object = self.data[index]
|
||||
self.data[index] = obj
|
||||
return old_object
|
||||
|
||||
@java_signature(JArray(JObject), ())
|
||||
def toArray(self):
|
||||
return self.data
|
||||
|
||||
@java_signature(autoclass("java.util.ListIterator"), ())
|
||||
def listIterator(self):
|
||||
it = TestImplemIterator(self)
|
||||
return it
|
||||
|
||||
# TODO cover this case of listIterator.
|
||||
@java_method('(I)Ljava/util/ListIterator;',
|
||||
name='ListIterator')
|
||||
def listIteratorI(self, index):
|
||||
it = TestImplemIterator(self, index)
|
||||
return it
|
||||
|
||||
|
||||
from jnius.reflect import autoclass
|
||||
|
||||
class SignaturesTest(unittest.TestCase):
|
||||
|
||||
def test_construct_stack_from_testimplem(self):
|
||||
Stack = autoclass("java.util.Stack")
|
||||
pyjlist = TestImplem(1, 2, 3, 4, 5, 6, 7)
|
||||
stack = Stack()
|
||||
stack.addAll(pyjlist)
|
||||
self.assertEquals(7, pyjlist.size())
|
||||
self.assertEquals(stack.size(), pyjlist.size())
|
||||
array = pyjlist.toArray
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue