@@ -112,15 +112,27 @@ def get_schema_fields(
112
112
113
113
if items := schema .get ('items' ):
114
114
# `items` advances the pointer and sets array context (for the next level only).
115
- yield from get_schema_fields (
116
- items ,
117
- f'{ pointer } /items' ,
118
- path_components ,
119
- definition ,
120
- deprecated ,
121
- whole_list_merge = whole_list_merge ,
122
- array = True ,
123
- )
115
+ if isinstance (items , dict ):
116
+ yield from get_schema_fields (
117
+ items ,
118
+ f'{ pointer } /items' ,
119
+ path_components ,
120
+ definition ,
121
+ deprecated ,
122
+ whole_list_merge = whole_list_merge ,
123
+ array = True ,
124
+ )
125
+ else :
126
+ for i , subschema in enumerate (items ):
127
+ yield from get_schema_fields (
128
+ subschema ,
129
+ f'{ pointer } /items/{ i } ' ,
130
+ path_components ,
131
+ definition ,
132
+ deprecated ,
133
+ whole_list_merge = whole_list_merge ,
134
+ array = True ,
135
+ )
124
136
125
137
for keyword in ('anyOf' , 'allOf' , 'oneOf' ):
126
138
if elements := schema .get (keyword ):
@@ -152,7 +164,7 @@ def get_schema_fields(
152
164
prop_pointer = f'{ pointer } /properties/{ name } '
153
165
prop_path_components = (* path_components , name )
154
166
prop_deprecated = _deprecated (subschema )
155
- prop_items = subschema . get ( 'items' , {} )
167
+ prop_codelist , prop_open_codelist = _codelist ( subschema )
156
168
157
169
# To date, codelist and openCodelist in OCDS aren't set on `items`.
158
170
yield Field (
@@ -163,8 +175,8 @@ def get_schema_fields(
163
175
definition = definition ,
164
176
deprecated_self = prop_deprecated ,
165
177
deprecated = deprecated or prop_deprecated ,
166
- codelist = subschema . get ( 'codelist' ) or prop_items . get ( 'codelist' , '' ) ,
167
- open_codelist = subschema . get ( 'openCodelist' ) or prop_items . get ( 'openCodelist' , False ) ,
178
+ codelist = prop_codelist ,
179
+ open_codelist = prop_open_codelist ,
168
180
multilingual = name in multilingual ,
169
181
required = name in required ,
170
182
merge_by_id = name == 'id' and array and not whole_list_merge ,
@@ -186,7 +198,7 @@ def get_schema_fields(
186
198
prop_pointer = f'{ pointer } /patternProperties/{ name } '
187
199
prop_path_components = (* path_components , name )
188
200
prop_deprecated = _deprecated (subschema )
189
- prop_items = subschema . get ( 'items' , {} )
201
+ prop_codelist , prop_open_codelist = _codelist ( subschema )
190
202
191
203
yield Field (
192
204
name = name ,
@@ -196,8 +208,8 @@ def get_schema_fields(
196
208
definition = definition ,
197
209
deprecated_self = prop_deprecated ,
198
210
deprecated = deprecated or prop_deprecated ,
199
- codelist = subschema . get ( 'codelist' ) or prop_items . get ( 'codelist' , '' ) ,
200
- open_codelist = subschema . get ( 'openCodelist' ) or prop_items . get ( 'openCodelist' , False ) ,
211
+ codelist = prop_codelist ,
212
+ open_codelist = prop_open_codelist ,
201
213
pattern = True ,
202
214
# `patternProperties` can't be multilingual, required, or "id".
203
215
)
@@ -222,6 +234,15 @@ def get_schema_fields(
222
234
yield from get_schema_fields (subschema , f'/{ keyword } /{ name } ' , definition = name )
223
235
224
236
237
+ def _codelist (subschema ):
238
+ if codelist := subschema .get ('codelist' ):
239
+ return codelist , subschema .get ('openCodelist' , False )
240
+ # The behavior hasn't been decided if `items` is an array (e.g. with conflicting codelist-related values).
241
+ if (items := subschema .get ('items' )) and isinstance (items , dict ):
242
+ return items .get ('codelist' , '' ), items .get ('openCodelist' , False )
243
+ return '' , False
244
+
245
+
225
246
def _deprecated (value ):
226
247
return value .get ('deprecated' ) or (hasattr (value , '__reference__' ) and value .__reference__ .get ('deprecated' )) or {}
227
248
0 commit comments