Skip to content
Snippets Groups Projects
Commit c4af18be authored by Philip Elson's avatar Philip Elson :snake:
Browse files

Merge branch 'fix/enum-item-set' into 'master'

Fix enum item sets conversion

See merge request !43
parents 966d0e56 c19c2bba
No related branches found
No related tags found
1 merge request!43Fix enum item sets conversion
Pipeline #1653122 passed
......@@ -101,6 +101,9 @@ tests_whl_py38_jdk8_jp07:
.base_wheel_test
variables:
env_spec: python=3.8 openjdk=8 JPype1=0.7
# The latest JPype 0.7 will fail currently
rules:
- allow_failure: true
tests_whl_py38_jdk11_jp0p7p1:
extends:
......@@ -113,6 +116,9 @@ tests_whl_py38_jdk11_jp07:
.base_wheel_test
variables:
env_spec: python=3.8 openjdk=11 JPype1=0.7
# The latest JPype 0.7 will fail currently
rules:
- allow_failure: true
build_wheel:
......
......@@ -1104,6 +1104,11 @@ class PyJapc(object):
"[2, nValues]".format(simpleValueDesc.getName(), tStr))
return
if tStr == "EnumSet":
# EnumSets aren't dimensioned arrays - they are simply a collection
# of flags (of arbitrary length) which can be combined together.
return
npArray = np.atleast_2d(npArray)
rc = simpleValueDesc.getRowCount()
cc = simpleValueDesc.getColumnCount()
......@@ -1233,6 +1238,11 @@ class PyJapc(object):
else:
parValNew.setInt(pyVal)
elif ts == "EnumSet":
parValNew = self._getSimpleValFromDesc(valueDescriptor)
# For now, enumsets can only be SET with an INT.
parValNew.setInt(pyVal)
else:
# This is a bit lame. For all primitives and arrays, the value descriptor is
# completely ignored and we rely on the python type completely.
......@@ -1384,7 +1394,7 @@ class PyJapc(object):
# Handle enumsets
# -------------------------------------------------------
if tStr == "enumset":
return [(v.code, v.string) for v in val.value]
return [(v.getCode(), v.getString()) for v in val.getEnumItemSet()]
# -------------------------------------------------------
# Handle the Primitives / arrays
......
......@@ -24,6 +24,28 @@ def std_meaning_enum_descriptor(std_meaning_enum):
return value_descriptor
@pytest.fixture
def enumtype_byte(jvm):
"""
An EnumType of bitsize BYTE, which is also good for EnumItemSet testing.
"""
EnumerationRegistry = jp.JClass("cern.japc.value.spi.value.EnumerationRegistry")
EnumItemData = jp.JClass("cern.japc.value.spi.value.EnumItemData")
EnumTypeBitSize = jp.JClass("cern.japc.value.EnumTypeBitSize")
HashSet = jp.JClass("java.util.HashSet")
item_set = HashSet()
item_set.add(EnumItemData(1, "Item 1"))
item_set.add(EnumItemData(2, "Item 2"))
item_set.add(EnumItemData(4, "Item 3"))
item_set.add(EnumItemData(8, "Item 4"))
enum_type = EnumerationRegistry.registerEnumType("TestEnum", EnumTypeBitSize.BYTE, item_set)
yield enum_type
# We can't clear specific EnumTypes, so for now, just clear the whole lot.
EnumerationRegistry.clearAll()
@pytest.fixture(scope="module")
def jvm():
mgr = cmmnbuild_dep_manager.Manager('pyjapc')
......
......@@ -126,6 +126,73 @@ def test_invalid_enum(japc, std_meaning_enum_descriptor, to_convert):
japc._convertPyToVal(to_convert, std_meaning_enum_descriptor)
@pytest.fixture
def enumset_vdesc(enumtype_byte):
SimpleDescriptor = jp.JClass(
"cern.japc.core.spi.value.SimpleDescriptorImpl")
value_descriptor = SimpleDescriptor(
jp.JClass("cern.japc.value.ValueType").ENUM_SET, enumtype_byte)
yield value_descriptor
@pytest.mark.parametrize(
['py_value', 'enumset_str'],
[(0, "(EnumSet:1) -> []"),
(2 | 4, "(EnumSet:1) -> [Item 2, Item 3]"),
])
def test_convert_py_to_val_enumset(japc, enumset_vdesc, py_value, enumset_str):
res = japc._convertPyToVal(py_value, enumset_vdesc)
assert isinstance(res, jp.JClass('cern.japc.value.spi.value.simple.EnumSetValue'))
assert str(res) == enumset_str
@pytest.mark.parametrize(
['py_value'],
[("[Item 2, Item 3]",),
([],),
([1, 2],),
([(1, "Item 1")],),
])
def test_convert_py_to_val_enumset_invalid_types(japc, enumset_vdesc, py_value):
# The error should come straight out of JPype.
if JPYPE_LT_0p7:
expected_exception = pytest.raises(
RuntimeError, match="No matching overloads found")
else:
expected_exception = pytest.raises(
TypeError,
match=("No matching overloads found for "
"cern.japc.value.spi.value.simple.EnumSetValue"))
with expected_exception:
japc._convertPyToVal(py_value, enumset_vdesc)
@pytest.mark.parametrize(
['enumset_code', 'expected_py'],
[(0, []),
(1, [(1, 'Item 1')]),
(2, [(2, 'Item 2')]),
(1 | 2, [(1, 'Item 1'), (2, 'Item 2')]),
(1 | 2 | 3, [(1, 'Item 1'), (2, 'Item 2')]),
(2 | 4 | 8, [(2, 'Item 2'), (4, 'Item 3'), (8, 'Item 4')]),
(1 | 4 | 8 | 16, [(1, 'Item 1'), (4, 'Item 3'), (8, 'Item 4')]),
])
def test_convert_val_to_py_enumset(japc, enumtype_byte, enumset_code, expected_py):
SimpleParameterValueFactory = jp.JClass(
"cern.japc.core.factory.SimpleParameterValueFactory")
EnumItemSetImpl = jp.JClass("cern.japc.value.spi.value.EnumItemSetImpl")
enum_set_value = SimpleParameterValueFactory.newSimpleParameterValue(
EnumItemSetImpl(enumtype_byte, enumset_code)
)
res = japc._convertValToPy(enum_set_value)
assert res == expected_py
def test_convert_py_to_simple(japc):
assert japc._convertPyToSimpleVal(1).toString() == '(int:1) -> 1'
assert japc._convertPyToSimpleVal(1.1).toString() == '(double:1) -> 1.1'
......
......@@ -17,7 +17,7 @@ with (HERE / 'README.rst').open('rt') as fh:
REQUIREMENTS: dict = {
'core': [
'jpype1>=0.6.1,<0.8,!=0.7.2',
'jpype1>=0.6.1,!=0.7.0,!=0.7.2,<=0.7.1',
'cmmnbuild-dep-manager>=2.4.0',
'numpy',
'pytz',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment