handle long strings as char array (thanks @huppert_m)

This commit is contained in:
2023-10-13 14:06:18 +02:00
parent acaf22391b
commit c7ec4574a6
2 changed files with 28 additions and 11 deletions

View File

@ -11,6 +11,8 @@ DTYPES = {
STR_REPS = {v:k for k, v in DTYPES.items()} STR_REPS = {v:k for k, v in DTYPES.items()}
MAX_STRING_LENGTH = 40 # epics string is limited to 40 characters, beyond that char arrays are needed
class PVInfo: class PVInfo:
@ -34,34 +36,34 @@ class PVInfo:
def infer_type(value, parse_string=True): #TODO char vs. strings? def infer_type(value, parse_string=True):
if isinstance(value, Sequence) and not isinstance(value, str): if isinstance(value, Sequence) and not isinstance(value, str):
value = np.array(value) # rely on numpy to figure out a consistent dtype value = np.array(value) # rely on numpy to figure out a consistent dtype
if isinstance(value, np.ndarray): if isinstance(value, np.ndarray):
return infer_type_numpy(value) #TODO: also parse strings for np arrays?! return infer_type_numpy(value) #TODO: also parse strings for np arrays?!
elif isinstance(value, np.generic): # covers all numpy scalars
if isinstance(value, np.generic): # covers all numpy scalars
value = value.item() value = value.item()
return infer_type_scalar(value, parse_string=parse_string)
def infer_type_scalar(value, parse_string=True):
if parse_string and isinstance(value, str): if parse_string and isinstance(value, str):
if value in STR_REPS: if value in STR_REPS:
value = STR_REPS[value] value = STR_REPS[value]
if isinstance(value, str):
return infer_type_str(value)
return infer_type_scalar(value)
def infer_type_scalar(value):
if isinstance(value, type): if isinstance(value, type):
dtype = value dtype = value
value = dtype() value = dtype()
else: else:
dtype = type(value) dtype = type(value)
#TODO: this can probably be removed
if isinstance(dtype, str):
raise Exception("how?")
#TODO: bool -> int or string? #TODO: bool -> int or string?
if isinstance(value, bool): if isinstance(value, bool):
dtype = int dtype = int
@ -96,3 +98,13 @@ def infer_type_numpy(arr):
def infer_type_str(value):
count = len(value)
#TODO: handle count == 1 as a single char?
if count > MAX_STRING_LENGTH:
return "char", value, count
else:
return "string", value

View File

@ -25,6 +25,11 @@ def test_it_type_int():
def test_it_value_str(): def test_it_value_str():
assert it("test") == ("string", "test") assert it("test") == ("string", "test")
def test_it_value_long_str():
dat = "test" * 100
ref = dat
assert it(dat) == ("char", ref, len(ref))
def test_it_value_float(): def test_it_value_float():
assert it(1.23) == ("float", 1.23) assert it(1.23) == ("float", 1.23)