Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closes #1632 - Multiple dtype support and improved list processing #1662

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions arkouda/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,21 @@ def _build_list_param(key: str, val: list) -> ParameterObject:
-------
ParameterObject
"""
dtypes = set([p.dtype if hasattr(p, "dtype") else type(p).__name__ for p in val])
from arkouda.pdarrayclass import pdarray
from arkouda.strings import Strings

# want the object type. If pdarray the content dtypes can vary
dtypes = set([type(p).__name__ for p in val])
if len(dtypes) > 1:
t_str = ", ".join(dtypes)
raise TypeError(f"List values must be of the same type. Found {t_str}")
return ParameterObject(key, ObjectType.LIST, dtypes.pop(), json.dumps(val))
t = dtypes.pop()
if any(x == t for x in [pdarray.__name__, Strings.__name__]):
return ParameterObject(key, ObjectType.LIST, t, json.dumps([x.name for x in val]))
else:
# need all values to be str for chapel to read list properly
v = val if t == str.__name__ else [str(x) for x in val]
return ParameterObject(key, ObjectType.LIST, t, json.dumps(v))

@staticmethod
@typechecked
Expand Down
63 changes: 63 additions & 0 deletions tests/message_test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import json
import unittest

from base_test import ArkoudaTest

from arkouda.client import _json_args_to_str
from arkouda.message import MessageFormat, MessageType, ReplyMessage, RequestMessage
from arkouda.pdarraycreation import arange, array


class MessageTest(unittest.TestCase):
Expand Down Expand Up @@ -98,3 +102,62 @@ def testReplyMessage(self):

with self.assertRaises(ValueError):
ReplyMessage.fromdict({"msg": "normal result", "msgType": "NORMAL"})


class JSONArgs(ArkoudaTest):
def testJSONArgs(self):
# test single value args
size, args = _json_args_to_str({"arg1": "Test", "arg2": 5})
self.assertEqual(size, 2)
self.assertListEqual(
[
'{"key": "arg1", "objType": "VALUE", "dtype": "str", "val": "Test"}',
'{"key": "arg2", "objType": "VALUE", "dtype": "int", "val": "5"}',
],
json.loads(args),
)

# test list arg of numerics
size, args = _json_args_to_str({"list1": [3, 2, 4]})
self.assertEqual(size, 1)
self.assertListEqual(
[
'{"key": "list1", "objType": "LIST", "dtype": "int", "val": "[\\"3\\", \\"2\\", \\"4\\"]"}'
],
json.loads(args),
)

# test list of str
size, args = _json_args_to_str({"list1": ["a", "b", "c"], "list2": ["d", "e", "f"]})
self.assertEqual(size, 2)
self.assertListEqual(
[
'{"key": "list1", "objType": "LIST", "dtype": "str", "val": "[\\"a\\", \\"b\\", \\"c\\"]"}',
'{"key": "list2", "objType": "LIST", "dtype": "str", "val": "[\\"d\\", \\"e\\", \\"f\\"]"}',
],
json.loads(args),
)

# test list of pdarray
pd1 = arange(3)
pd2 = arange(4)
size, args = _json_args_to_str({"pd1": pd1, "pd2": pd2})
self.assertEqual(size, 2)
for a in json.loads(args):
p = json.loads(a)
self.assertRegex(p["key"], "^pd(1|2)$")
self.assertEqual(p["objType"], "PDARRAY")
self.assertEqual(p["dtype"], "int64")
self.assertRegex(p["val"], "^id_\\w{7}_\\d$")

# test list of Strings
str1 = array(["abc", "def"])
str2 = array(["Test", "Test2"])
size, args = _json_args_to_str({"str1": str1, "str2": str2})
self.assertEqual(size, 2)
for a in json.loads(args):
p = json.loads(a)
self.assertRegex(p["key"], "^str(1|2)$")
self.assertEqual(p["objType"], "SEGSTRING")
self.assertEqual(p["dtype"], "str")
self.assertRegex(p["val"], "^id_\\w{7}_\\d$")