Skip to content

Commit

Permalink
Closes #1632 - Multiple dtype support and improved list processing (#…
Browse files Browse the repository at this point in the history
…1662)

* Update JSON argument list parsing to properly handle Strings/pdarray objects.
Updated parsing to require objects in the list be the same type, though pdarray dtypes are able to have varying dtypes.
Added testing for the _json_args_to_str. Ensure that numeric, str, Strings, and pdarray are properly converted for parsing on the server.

* Removing escape sequences that pytest was not happy with.

* Updating regex
  • Loading branch information
Ethan-DeBandi99 authored Aug 8, 2022
1 parent 38b25fc commit d081449
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
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$")

0 comments on commit d081449

Please sign in to comment.