11from datetime import date , datetime
22from decimal import Decimal
3- from typing import Union
3+ from typing import Optional , Union
44
55from .generic_utils import is_valid_simple_snomed , nhs_number_mod11_check
66
@@ -23,6 +23,9 @@ def for_string(
2323 if not isinstance (field_value , str ):
2424 raise TypeError (f"{ field_location } must be a string" )
2525
26+ if field_value .isspace ():
27+ raise ValueError (f"{ field_location } must be a non-empty string" )
28+
2629 if defined_length :
2730 if len (field_value ) != defined_length :
2831 raise ValueError (f"{ field_location } must be { defined_length } characters" )
@@ -46,14 +49,15 @@ def for_string(
4649 def for_list (
4750 field_value : list ,
4851 field_location : str ,
49- defined_length : int = None ,
52+ defined_length : Optional [int ] = None ,
53+ max_length : Optional [int ] = None ,
5054 elements_are_strings : bool = False ,
55+ string_element_max_length : Optional [int ] = None ,
5156 elements_are_dicts : bool = False ,
5257 ):
5358 """
54- Apply pre-validation to a list field to ensure it is a non-empty list which meets the length
55- requirements and requirements, if applicable, for each list element to be a non-empty string
56- or non-empty dictionary
59+ Apply pre-validation to a list field to ensure it is a non-empty list which meets the length requirements and
60+ requirements, if applicable, for each list element to be a non-empty string or non-empty dictionary
5761 """
5862 if not isinstance (field_value , list ):
5963 raise TypeError (f"{ field_location } must be an array" )
@@ -65,12 +69,12 @@ def for_list(
6569 if len (field_value ) == 0 :
6670 raise ValueError (f"{ field_location } must be a non-empty array" )
6771
72+ if max_length is not None and len (field_value ) > max_length :
73+ raise ValueError (f"{ field_location } must be an array of maximum length { max_length } " )
74+
6875 if elements_are_strings :
69- for element in field_value :
70- if not isinstance (element , str ):
71- raise TypeError (f"{ field_location } must be an array of strings" )
72- if len (element ) == 0 :
73- raise ValueError (f"{ field_location } must be an array of non-empty strings" )
76+ for idx , element in enumerate (field_value ):
77+ PreValidation .for_string (element , f"{ field_location } [{ idx } ]" , max_length = string_element_max_length )
7478
7579 if elements_are_dicts :
7680 for element in field_value :
@@ -181,6 +185,7 @@ def for_positive_integer(field_value: int, field_location: str, max_value: int =
181185 Apply pre-validation to an integer field to ensure that it is a positive integer,
182186 which does not exceed the maximum allowed value (if applicable)
183187 """
188+ # This check uses type() instead of isinstance() because bool is a subclass of int.
184189 if type (field_value ) is not int : # pylint: disable=unidiomatic-typecheck
185190 raise TypeError (f"{ field_location } must be a positive integer" )
186191
@@ -198,6 +203,7 @@ def for_integer_or_decimal(field_value: Union[int, Decimal], field_location: str
198203 which does not exceed the maximum allowed number of decimal places (if applicable)
199204 """
200205 if not (
206+ # This check uses type() instead of isinstance() because bool is a subclass of int.
201207 type (field_value ) is int # pylint: disable=unidiomatic-typecheck
202208 or type (field_value ) is Decimal # pylint: disable=unidiomatic-typecheck
203209 ):
0 commit comments