Skip to content

Commit

Permalink
Merge branch 'master' into bug_1194
Browse files Browse the repository at this point in the history
  • Loading branch information
marscher committed Aug 20, 2024
2 parents af03e98 + 7de66d0 commit f667f87
Show file tree
Hide file tree
Showing 18 changed files with 342 additions and 263 deletions.
388 changes: 201 additions & 187 deletions LICENSE

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions doc/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Latest Changes:

- **1.5.1_dev0 - 2023-12-15**
- Fixed uncaught exception while setting traceback causing issues in Python 3.11/3.12.

- Use PEP-518 and PEP-660 configuration for the package, allowing editable and
configurable builds using modern Python packaging tooling.
Where before ``python setup.py --enable-tracing develop``, now can be done with
Expand All @@ -22,6 +23,12 @@ Latest Changes:
- Fixed a problem that caused ``dir(jpype.JPackage("mypackage"))`` to fail if
the class path contained non-ascii characters. See issue #1194.

- Update for tests for numpy 2.0.

- Support of np.float16 conversion with arrays.



- **1.5.0 - 2023-04-03**

- Support for Python 3.12
Expand Down
2 changes: 1 addition & 1 deletion doc/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ bench requires JDK to build.

**4. Test JPype with (optional):** ::

python setup.py test
python -m pytest



Expand Down
2 changes: 1 addition & 1 deletion doc/userguide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ JPype User Guide
JPype Introduction
******************
JPype is a Python module to provide full access to Java from within Python.
Unlike Jython, JPype does not achive this by re-implementing Python, but
Unlike Jython, JPype does not achieve this by re-implementing Python, but
instead by interfacing both virtual machines at the native level. This
shared memory based approach achieves good computing performance, while
providing the access to the entirety of CPython and Java libraries.
Expand Down
76 changes: 76 additions & 0 deletions native/common/jp_convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,61 @@
See NOTICE file for details.
*****************************************************************************/
#include "jpype.h"
#include <math.h>
#include <bitset>

namespace
{

template <jvalue func(void *c) >
class Half
{
public:
static jvalue convert(void* c)
{
uint16_t i = *(uint16_t*) c;
uint32_t sign = (i&0x8000)>>15;
uint32_t man = (i&0x7C00)>>10;
uint32_t frac = (i&0x03ff);
uint32_t k = sign<<31;

if (man == 0)
{
// subnormal numbers
if (frac != 0)
{
frac = frac | (frac >> 1);
frac = frac | (frac >> 2);
frac = frac | (frac >> 4);
frac = frac | (frac >> 8);
int zeros = std::bitset<32>(~frac).count();
man = 127-zeros+7;
man <<= 23;
frac <<= zeros-8;
frac &= 0x7fffff;
k |= man | frac;
}
}
else if (man < 31)
{
// normal numbers
man = man-15+127;
man <<= 23;
frac <<= 13;
k |= man | frac;
}
else
{
// to infinity and beyond!
if (frac == 0)
k |= 0x7f800000;
else
k |= 0x7f800001 | ((frac&0x200)<<12);
}
return func(&k);
}
};

template <class T>
class Convert
{
Expand Down Expand Up @@ -385,6 +436,31 @@ jconverter getConverter(const char* from, int itemsize, const char* to)
case 'd': return &Convert<double>::toD;
}
break;
case 'e':
if (reverse) switch (to[0])
{
case 'z': return &Reverse<Half<Convert<float>::toZ>::convert>::call4;
case 'b': return &Reverse<Half<Convert<float>::toB>::convert>::call4;
case 'c': return &Reverse<Half<Convert<float>::toC>::convert>::call4;
case 's': return &Reverse<Half<Convert<float>::toS>::convert>::call4;
case 'i': return &Reverse<Half<Convert<float>::toI>::convert>::call4;
case 'j': return &Reverse<Half<Convert<float>::toJ>::convert>::call4;
case 'f': return &Reverse<Half<Convert<float>::toF>::convert>::call4;
case 'd': return &Reverse<Half<Convert<float>::toD>::convert>::call4;
}
else switch (to[0])
{
case 'z': return &Half<Convert<float>::toZ>::convert;
case 'b': return &Half<Convert<float>::toB>::convert;
case 'c': return &Half<Convert<float>::toC>::convert;
case 's': return &Half<Convert<float>::toS>::convert;
case 'i': return &Half<Convert<float>::toI>::convert;
case 'j': return &Half<Convert<float>::toJ>::convert;
case 'f': return &Half<Convert<float>::toF>::convert;
case 'd': return &Half<Convert<float>::toD>::convert;
}
break;

case 'n':
if (reverse) switch (to[0])
{
Expand Down
3 changes: 2 additions & 1 deletion native/python/include/pyjp.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,14 @@ JPValue *PyJPValue_getJavaSlot(PyObject* obj);
PyObject *PyJPModule_getClass(PyObject* module, PyObject *obj);
PyObject *PyJPValue_getattro(PyObject *obj, PyObject *name);
int PyJPValue_setattro(PyObject *self, PyObject *name, PyObject *value);
void PyJPClass_hook(JPJavaFrame &frame, JPClass* cls);
PyObject *PyJPChar_Create(PyTypeObject *type, Py_UCS2 p);

#ifdef __cplusplus
}
#endif

void PyJPClass_hook(JPJavaFrame &frame, JPClass* cls);

// C++ methods
JPPyObject PyJPArray_create(JPJavaFrame &frame, PyTypeObject* wrapper, const JPValue& value);
JPPyObject PyJPBuffer_create(JPJavaFrame &frame, PyTypeObject *type, const JPValue & value);
Expand Down
3 changes: 0 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[alias]
test=pytest

[tool:pytest]
addopts = --verbose
testpaths =
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
'develop': setupext.develop.Develop,
'test_java': setupext.test_java.TestJavaCommand,
'sdist': setupext.sdist.BuildSourceDistribution,
'test': setupext.pytester.PyTest,
},
zip_safe=False,
ext_modules=[jpypeJar, jpypeLib, ],
Expand Down
1 change: 0 additions & 1 deletion setupext/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@
from . import develop
from . import test_java
from . import sdist
from . import pytester
39 changes: 0 additions & 39 deletions setupext/pytester.py

This file was deleted.

31 changes: 16 additions & 15 deletions test/jpypetest/test_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,11 @@ def testMemoryByte(self):
jtype = jpype.JByte[:]

# Simple checks
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
for dtype in "c?bBhHiIlLqQfdnN":
jtype(mv.cast(dtype))
jtype(mv.cast("@" + dtype))

for dtype in ("s", "p", "P", "e"):
for dtype in "spP":
with self.assertRaises(Exception):
jtype(mv.cast(dtype))

Expand All @@ -328,11 +328,12 @@ def testMemoryInt(self):
jtype = jpype.JInt[:]

# Simple checks
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
for dtype in "c?bBhHiIlLqQfdnN":
print(dtype)
jtype(mv.cast(dtype))
jtype(mv.cast("@" + dtype))

for dtype in ("s", "p", "P", "e"):
for dtype in "spP":
with self.assertRaises(Exception):
jtype(mv.cast(dtype))

Expand All @@ -341,11 +342,11 @@ def testMemoryShort(self):
jtype = jpype.JShort[:]

# Simple checks
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
for dtype in "c?bBhHiIlLqQfdnN":
jtype(mv.cast(dtype))
jtype(mv.cast("@" + dtype))

for dtype in ("s", "p", "P", "e"):
for dtype in "spP":
with self.assertRaises(Exception):
jtype(mv.cast(dtype))

Expand All @@ -354,11 +355,11 @@ def testMemoryLong(self):
jtype = jpype.JLong[:]

# Simple checks
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
for dtype in "c?bBhHiIlLqQfdnN":
jtype(mv.cast(dtype))
jtype(mv.cast("@" + dtype))

for dtype in ("s", "p", "P", "e"):
for dtype in "spP":
with self.assertRaises(Exception):
jtype(mv.cast(dtype))

Expand All @@ -367,11 +368,11 @@ def testMemoryFloat(self):
jtype = jpype.JFloat[:]

# Simple checks
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
for dtype in "c?bBhHiIlLqQfdnN":
jtype(mv.cast(dtype))
jtype(mv.cast("@" + dtype))

for dtype in ("s", "p", "P", "e"):
for dtype in "spP":
with self.assertRaises(Exception):
jtype(mv.cast(dtype))

Expand All @@ -380,11 +381,11 @@ def testMemoryDouble(self):
jtype = jpype.JDouble[:]

# Simple checks
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
for dtype in "c?bBhHiIlLqQfdnN":
jtype(mv.cast(dtype))
jtype(mv.cast("@" + dtype))

for dtype in ("s", "p", "P", "e"):
for dtype in "spP":
with self.assertRaises(Exception):
jtype(mv.cast(dtype))

Expand All @@ -393,11 +394,11 @@ def testMemoryBoolean(self):
jtype = jpype.JBoolean[:]

# Simple checks
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
for dtype in "c?bBhHiIlLqQfdnN":
jtype(mv.cast(dtype))
jtype(mv.cast("@" + dtype))

for dtype in ("s", "p", "P", "e"):
for dtype in "spP":
with self.assertRaises(Exception):
jtype(mv.cast(dtype))

Expand All @@ -406,7 +407,7 @@ def testMemoryChar(self):
jtype = jpype.JChar[:]

# Simple checks
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "n", "N"):
for dtype in "c?bBhHiIlLqQnN":
jtype(mv.cast(dtype))
jtype(mv.cast("@" + dtype))

Expand Down
4 changes: 2 additions & 2 deletions test/jpypetest/test_conversionInt.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ def testIntFromFloat(self):
self.Test.callInt(float(2))

@common.unittest.skipUnless(haveNumpy(), "numpy not available")
def testIntFromNPFloat(self):
def testIntFromNPFloat16(self):
import numpy as np
with self.assertRaises(TypeError):
self.Test.callInt(np.float_(2))
self.Test.callInt(np.float16(2))

@common.unittest.skipUnless(haveNumpy(), "numpy not available")
def testIntFromNPFloat32(self):
Expand Down
4 changes: 2 additions & 2 deletions test/jpypetest/test_conversionLong.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ def testLongFromFloat(self):
self.Test.callLong(float(2))

@common.unittest.skipUnless(haveNumpy(), "numpy not available")
def testLongFromNPFloat(self):
def testLongFromNPFloat16(self):
import numpy as np
with self.assertRaises(TypeError):
self.Test.callLong(np.float_(2))
self.Test.callLong(np.float16(2))

@common.unittest.skipUnless(haveNumpy(), "numpy not available")
def testLongFromNPFloat32(self):
Expand Down
4 changes: 2 additions & 2 deletions test/jpypetest/test_conversionShort.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ def testShortFromFloat(self):
self.Test.callShort(float(2))

@common.unittest.skipUnless(haveNumpy(), "numpy not available")
def testShortFromNPFloat(self):
def testShortFromNPFloat16(self):
import numpy as np
with self.assertRaises(TypeError):
self.Test.callShort(np.float_(2))
self.Test.callShort(np.float16(2))

@common.unittest.skipUnless(haveNumpy(), "numpy not available")
def testShortFromNPFloat32(self):
Expand Down
4 changes: 2 additions & 2 deletions test/jpypetest/test_jboolean.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,10 @@ def testBooleanFromFloat(self):
self.Test.callBoolean(float(2))

@common.requireNumpy
def testBooleanFromNPFloat(self):
def testBooleanFromNPFloat16(self):
import numpy as np
with self.assertRaises(TypeError):
self.Test.callBoolean(np.float_(2))
self.Test.callBoolean(np.float16(2))

@common.requireNumpy
def testBooleanFromNPFloat32(self):
Expand Down
4 changes: 2 additions & 2 deletions test/jpypetest/test_jbyte.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ def testByteFromFloat(self):
self.fixture.callByte(float(2))

@common.requireNumpy
def testByteFromNPFloat(self):
def testByteFromNPFloat16(self):
import numpy as np
with self.assertRaises(TypeError):
self.fixture.callByte(np.float_(2))
self.fixture.callByte(np.float16(2))

@common.requireNumpy
def testByteFromNPFloat32(self):
Expand Down
Loading

0 comments on commit f667f87

Please sign in to comment.