-
Notifications
You must be signed in to change notification settings - Fork 8
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
add enum checking for attributes #557
Changes from 6 commits
d4a4b36
f7726bf
74ee378
e5a19c0
e8e9f39
3ae92b1
9e351a2
89d3109
c634d9f
c2ca03e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,7 +85,7 @@ def _log(self, path: str, log_type: ValidationProblem, value: Optional[Any], *ar | |
) | ||
elif log_type == ValidationProblem.InvalidEnum: | ||
logger.warning( | ||
f"The value at {path} should be on of the following strings: {value}" | ||
f"The value at {path} should be one of the following: {value}" | ||
) | ||
elif log_type == ValidationProblem.MissingRequiredGroup: | ||
logger.warning(f"The required group, {path}, hasn't been supplied.") | ||
|
@@ -96,7 +96,7 @@ def _log(self, path: str, log_type: ValidationProblem, value: Optional[Any], *ar | |
) | ||
elif log_type == ValidationProblem.InvalidType: | ||
logger.warning( | ||
f"The value at {path} should be one of: {value}" | ||
f"The value at {path} should be one of the following Python types: {value}" | ||
f", as defined in the NXDL as {args[0] if args else '<unknown>'}." | ||
) | ||
elif log_type == ValidationProblem.InvalidDatetime: | ||
|
@@ -578,66 +578,23 @@ def is_value_valid_element_of_enum(value, elist) -> Tuple[bool, list]: | |
NUMPY_FLOAT_TYPES = (np.half, np.float16, np.single, np.double, np.longdouble) | ||
NUMPY_INT_TYPES = (np.short, np.intc, np.int_) | ||
NUMPY_UINT_TYPES = (np.ushort, np.uintc, np.uint) | ||
# np int for np version 1.26.0 | ||
np_int = ( | ||
np.intc, | ||
np.int_, | ||
np.intp, | ||
np.int8, | ||
np.int16, | ||
np.int32, | ||
np.int64, | ||
np.uint8, | ||
np.uint16, | ||
np.uint32, | ||
np.uint64, | ||
np.unsignedinteger, | ||
np.signedinteger, | ||
) | ||
np_float = (np.float16, np.float32, np.float64, np.floating) | ||
np_bytes = (np.bytes_, np.byte, np.ubyte) | ||
np_char = (np.str_, np.char.chararray, *np_bytes) | ||
np_bool = (np.bool_,) | ||
np_complex = (np.complex64, np.complex128, np.cdouble, np.csingle) | ||
|
||
NEXUS_TO_PYTHON_DATA_TYPES = { | ||
"ISO8601": (str,), | ||
"NX_BINARY": ( | ||
bytes, | ||
bytearray, | ||
np.ndarray, | ||
*np_bytes, | ||
), | ||
"NX_BOOLEAN": (bool, np.ndarray, *np_bool), | ||
"NX_CHAR": (str, np.ndarray, *np_char), | ||
"NX_DATE_TIME": (str,), | ||
"NX_FLOAT": (float, np.ndarray, *np_float), | ||
"NX_INT": (int, np.ndarray, *np_int), | ||
"ISO8601": (str), | ||
"NX_BINARY": (bytes, bytearray, np.byte, np.ubyte, np.ndarray), | ||
"NX_BOOLEAN": (bool, np.ndarray, np.bool_), | ||
"NX_CHAR": (str, np.ndarray, np.chararray), | ||
"NX_DATE_TIME": (str), | ||
"NX_FLOAT": (float, np.ndarray, np.floating), | ||
"NX_INT": (int, np.ndarray, np.integer), | ||
"NX_UINT": (np.ndarray, np.unsignedinteger), | ||
"NX_NUMBER": ( | ||
int, | ||
float, | ||
np.ndarray, | ||
*np_int, | ||
*np_float, | ||
dict, | ||
), | ||
"NX_NUMBER": (int, float, np.ndarray, np.integer, np.floating), | ||
"NX_POSINT": ( | ||
int, | ||
np.ndarray, | ||
np.signedinteger, | ||
np.integer, | ||
), # > 0 is checked in is_valid_data_field() | ||
"NX_COMPLEX": (complex, np.ndarray, *np_complex), | ||
"NXDL_TYPE_UNAVAILABLE": (str,), # Defaults to a string if a type is not provided. | ||
"NX_CHAR_OR_NUMBER": ( | ||
str, | ||
int, | ||
float, | ||
np.ndarray, | ||
*np_char, | ||
*np_int, | ||
*np_float, | ||
dict, | ||
), | ||
"NXDL_TYPE_UNAVAILABLE": (str), # Defaults to a string if a type is not provided. | ||
} | ||
|
||
|
||
|
@@ -699,18 +656,14 @@ def is_valid_data_field(value, nxdl_type, path): | |
accepted_types = NEXUS_TO_PYTHON_DATA_TYPES[nxdl_type] | ||
output_value = value | ||
|
||
if isinstance(value, list): | ||
return all(is_valid_data_field(v, nxdl_type, path) for v in value), output_value | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This produces one warning per element in a list, if the datatype is not correct. @RubelMozumder had a different solution for this in #554. |
||
if not isinstance(value, dict) and not is_valid_data_type(value, accepted_types): | ||
try: | ||
if accepted_types[0] is bool and isinstance(value, str): | ||
value = convert_str_to_bool_safe(value) | ||
if value is None: | ||
raise ValueError | ||
output_value = accepted_types[0](value) | ||
except ValueError: | ||
collector.collect_and_log( | ||
path, ValidationProblem.InvalidType, accepted_types, nxdl_type | ||
) | ||
return False, value | ||
Comment on lines
-703
to
-713
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would keep the boolean string to bool conversion, this certainly makes sense and We could even think about doing this for all datatypes with safe literal conversion, as you did for the enums. |
||
collector.collect_and_log( | ||
path, ValidationProblem.InvalidType, accepted_types, nxdl_type | ||
) | ||
return False, value | ||
|
||
if nxdl_type == "NX_POSINT" and not is_positive_int(value): | ||
collector.collect_and_log(path, ValidationProblem.IsNotPosInt, value) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still allows to write numeric arrays to an NX_CHAR, which is not correct. This issue is also solved by #554