in scripts/validation_utils.py [0:0]
def get_field_value(container, field_name, field_type):
"""Fetch a field from a container with typechecking and default values.
The field value is coerced to the desired type. If the field is
not present, an instance of `field_type` is constructed with no
arguments and used as the default value.
This function exists because yaml parsing can lead to surprising
outputs, and the resulting errors are confusing. For example:
entrypoint1: a string, but I can accidentally treat as an sequence
entrypoint2: [a, list, but, I, might, think, its, a, string]
version1: 3 # Parsed to int
version2: 3.1 # Parsed to float
version3: 3.1.1 # Parsed to str
feature: off # Parsed to the boolean False
Args:
container (dict): Object decoded from yaml
field_name (str): Field that should be present in `container`
field_type (type): Expected type for field value
Returns:
Any: Fetched or default value of field
Raises:
ValueError: if field value cannot be converted to the desired type
"""
try:
value = container[field_name]
if value is None:
return field_type()
except (IndexError, KeyError):
return field_type()
msg = 'Expected "{}" field to be of type "{}", but found type "{}"'
if not isinstance(value, field_type):
# list('some string') is a successful type cast as far as Python
# is concerned, but doesn't exactly produce the results we want.
# We have a whitelist of conversions we will attempt.
whitelist = (
(float, str),
(int, str),
(str, float),
(str, int),
(int, float),
)
if (type(value), field_type) not in whitelist:
raise ValueError(msg.format(field_name, field_type, type(value)))
try:
value = field_type(value)
except ValueError as e:
e.message = msg.format(field_name, field_type, type(value))
raise
return value