1515 S3Connection ,
1616)
1717
18+ from .choices import FileChoices
1819from .types import Boolean , DHIS2ConnectionType , IASOConnectionType , Secret , TYPES_BY_PYTHON_TYPE
1920from .widgets import DHIS2Widget , IASOWidget
2021
@@ -42,7 +43,7 @@ def __init__(
4243 | File
4344 ],
4445 name : str | None = None ,
45- choices : typing .Sequence | None = None ,
46+ choices : typing .Sequence | FileChoices | None = None ,
4647 help : str | None = None ,
4748 default : typing .Any | None = None ,
4849 widget : DHIS2Widget | IASOWidget | None = None ,
@@ -66,14 +67,19 @@ def __init__(
6667 if choices is not None :
6768 if not self .type .accepts_choices :
6869 raise InvalidParameterError (f"Parameters of type { self .type } don't accept choices." )
69- elif len (choices ) == 0 :
70- raise InvalidParameterError ("Choices, if provided, cannot be empty." )
71-
72- try :
73- for choice in choices :
74- self .type .validate (choice )
75- except ParameterValueError :
76- raise InvalidParameterError (f"The provided choices are not valid for the { self .type } parameter type." )
70+ if isinstance (choices , FileChoices ):
71+ # validate_spec() already ran in FileChoices.__init__; nothing more to check here
72+ pass
73+ else :
74+ if len (choices ) == 0 :
75+ raise InvalidParameterError ("Choices, if provided, cannot be empty." )
76+ try :
77+ for choice in choices :
78+ self .type .validate (choice )
79+ except ParameterValueError :
80+ raise InvalidParameterError (
81+ f"The provided choices are not valid for the { self .type } parameter type."
82+ )
7783 self .choices = choices
7884
7985 self .name = name
@@ -100,11 +106,11 @@ def validate(self, value: typing.Any) -> typing.Any:
100106
101107 def to_dict (self ) -> dict [str , typing .Any ]:
102108 """Return a dictionary representation of the Parameter instance."""
103- return {
109+ d = {
104110 "code" : self .code ,
105111 "type" : self .type .spec_type ,
106112 "name" : self .name ,
107- "choices" : self .choices ,
113+ "choices" : None if isinstance ( self . choices , FileChoices ) else self .choices ,
108114 "help" : self .help ,
109115 "default" : self .default ,
110116 "widget" : self .widget .value if self .widget else None ,
@@ -113,6 +119,9 @@ def to_dict(self) -> dict[str, typing.Any]:
113119 "multiple" : self .multiple ,
114120 "directory" : self .directory ,
115121 }
122+ if isinstance (self .choices , FileChoices ):
123+ d ["file_choices" ] = self .choices .to_dict ()
124+ return d
116125
117126 def _validate_single (self , value : typing .Any ):
118127 # Normalize empty values to None and handles default
@@ -129,7 +138,7 @@ def _validate_single(self, value: typing.Any):
129138 return None
130139
131140 pre_validated = self .type .validate (normalized_value )
132- if self .choices is not None and pre_validated not in self .choices :
141+ if self .choices is not None and not isinstance ( self . choices , FileChoices ) and pre_validated not in self .choices :
133142 raise ParameterValueError (f"The provided value for { self .code } is not included in the provided choices." )
134143
135144 return pre_validated
@@ -152,7 +161,11 @@ def _validate_multiple(self, value: typing.Any):
152161 raise ParameterValueError (f"{ self .code } is required" )
153162
154163 pre_validated = [self .type .validate (single_value ) for single_value in normalized_value ]
155- if self .choices is not None and any (v not in self .choices for v in pre_validated ):
164+ if (
165+ self .choices is not None
166+ and not isinstance (self .choices , FileChoices )
167+ and any (v not in self .choices for v in pre_validated )
168+ ):
156169 raise ParameterValueError (
157170 f"One of the provided values for { self .code } is not included in the provided choices."
158171 )
@@ -174,7 +187,7 @@ def _validate_default(self, default: typing.Any, multiple: bool):
174187 except ParameterValueError :
175188 raise InvalidParameterError (f"The default value for { self .code } is not valid." )
176189
177- if self .choices is not None :
190+ if self .choices is not None and not isinstance ( self . choices , FileChoices ) :
178191 if isinstance (default , list ):
179192 if not all (d in self .choices for d in default ):
180193 raise InvalidParameterError (
@@ -227,7 +240,7 @@ def parameter(
227240 | File
228241 ],
229242 name : str | None = None ,
230- choices : typing .Sequence | None = None ,
243+ choices : typing .Sequence | FileChoices | None = None ,
231244 help : str | None = None ,
232245 widget : DHIS2Widget | IASOWidget | None = None ,
233246 connection : str | None = None ,
0 commit comments