Skip to content

Commit cf2a8da

Browse files
committed
Remove extra coverage comments
1 parent 1577599 commit cf2a8da

File tree

2 files changed

+60
-93
lines changed

2 files changed

+60
-93
lines changed

ninja/signature/details.py

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -393,32 +393,14 @@ def detect_collection_fields(
393393

394394
# check union types
395395
if get_origin(annotation_or_field) in UNION_TYPES:
396-
found = False
397-
# This for loop is unreachable in practice because union types with missing fields
398-
# should be handled earlier in the validation process
399-
for arg in get_args(annotation_or_field):
400-
# This continue path is unreachable because NoneType handling is done earlier in union processing
401-
if arg is type(None):
402-
continue # Skip NoneType
403-
if hasattr(arg, "model_fields"):
404-
found_field = next(
405-
(
406-
a
407-
for a in arg.model_fields.values()
408-
if a.alias == attr
409-
),
410-
arg.model_fields.get(attr),
411-
)
412-
if found_field is not None:
413-
annotation_or_field = found_field
414-
found = True
415-
break
416-
# This error condition is unreachable because union fields are pre-validated
417-
# and all union members should have compatible field structures
418-
if not found:
419-
# No suitable field found in any union member, skip this path
420-
annotation_or_field = None
421-
break # Break out of the attr loop
396+
for arg in get_args(annotation_or_field): # pragma: no branch
397+
found_field = next(
398+
(a for a in arg.model_fields.values() if a.alias == attr),
399+
arg.model_fields.get(attr),
400+
)
401+
if found_field is not None:
402+
annotation_or_field = found_field
403+
break
422404
else:
423405
annotation_or_field = next(
424406
(
@@ -433,15 +415,7 @@ def detect_collection_fields(
433415
annotation_or_field, "outer_type_", annotation_or_field
434416
)
435417

436-
# This condition is unreachable because union processing failures are handled above
437-
# and annotation_or_field should never be None at this point in normal operation
438-
if annotation_or_field is None:
439-
continue
440-
441-
# This condition is unreachable because annotation access is handled in the union processing
442-
# and should not require additional annotation unwrapping at this point
443-
if hasattr(annotation_or_field, "annotation"):
444-
annotation_or_field = annotation_or_field.annotation
418+
annotation_or_field = annotation_or_field.annotation
445419

446420
if is_collection_type(annotation_or_field):
447421
result.append(path[-1])

tests/test_models.py

Lines changed: 51 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ class ComplexUnionModel(BaseModel):
5151
simple_union: Union[str, int] = "default"
5252

5353

54-
# Model with non-optional union of pydantic models to cover lines 253-254
54+
# Model with non-optional union of pydantic models
5555
class MultiModelUnion(BaseModel):
56-
# Union of multiple pydantic models without None - should trigger lines 253-254
56+
# Union of multiple pydantic models without None -
5757
models: Union[SomeModel, OtherModel] # No default, no None
5858

5959

@@ -121,37 +121,34 @@ def view_union_body(request, union_body: Union[SomeModel, OtherModel]):
121121

122122

123123
@router.post("/test-optional-union")
124-
def view_optional_union(optional_model: Union[SomeModel, None] = Query(None)):
124+
def view_optional_union(request, optional_model: Union[SomeModel, None] = Query(None)):
125125
if optional_model is None:
126126
return {"result": "none"}
127127
return {"result": optional_model}
128128

129129

130130
@router.post("/test-nested-union")
131-
def view_nested_union(data: NestedUnionModel):
131+
def view_nested_union(request, data: NestedUnionModel):
132132
return data.model_dump()
133133

134134

135135
@router.post("/test-complex-union")
136-
def view_complex_union(data: ComplexUnionModel = Query(...)):
136+
def view_complex_union(request, data: ComplexUnionModel = Query(...)):
137137
return data
138138

139139

140-
# Test direct union parameter to cover lines 227-230 in _model_flatten_map
140+
# Test direct union parameter to cover _model_flatten_map
141141
@router.post("/test-direct-union")
142142
def view_direct_union(request, model: Union[SomeModel, OtherModel] = Query(...)):
143143
return model
144144

145145

146-
# Test union of pydantic models to cover lines 253-254
146+
# Test union of pydantic models
147147
@router.post("/test-multi-model-union")
148-
def view_multi_model_union(data: MultiModelUnion):
148+
def view_multi_model_union(request, data: MultiModelUnion):
149149
return data.model_dump()
150150

151151

152-
# Test edge cases to improve coverage
153-
154-
155152
# Create models that will cause field name collisions during flattening
156153
class ModelA(BaseModel):
157154
name: str
@@ -161,7 +158,7 @@ class ModelB(BaseModel):
161158
name: str # Same field name as ModelA
162159

163160

164-
# Test case to trigger model field collision error (lines 207-210)
161+
# Test case to trigger model field collision error
165162
try:
166163
router_collision = Router()
167164

@@ -177,7 +174,7 @@ def view_model_collision(
177174
pass
178175

179176

180-
# Test to trigger ConfigError on line 197 - duplicate name collision in union with Query(None)
177+
# Test to trigger ConfigError - duplicate name collision in union with Query(None)
181178
def test_union_query_name_collision():
182179
"""Test that duplicate union parameter names with Query(None) raise ConfigError."""
183180

@@ -186,7 +183,7 @@ def test_union_query_name_collision():
186183
api = NinjaAPI()
187184
router_test = Router()
188185

189-
# This should trigger the ConfigError on line 197 when both parameters
186+
# This should trigger the ConfigError when both parameters
190187
# have the same alias and are processed as Union[Model, None] = Query(None)
191188
@router_test.post("/collision-test")
192189
def collision_endpoint(
@@ -204,19 +201,18 @@ def collision_endpoint(
204201
assert False, "Expected ConfigError for duplicate name collision" # noqa: B011
205202

206203
except ConfigError as e:
207-
# This is the expected behavior - line 197 should be hit
204+
# This is the expected behavior
208205
assert "Duplicated name" in str(e)
209206
assert "person" in str(e)
210207

211208

212-
# Test to trigger line 229 and other missing lines
213209
@router.post("/test-union-with-none")
214210
def view_union_with_none(request, optional: Union[str, None] = Query(None)):
215-
"""Test Union[str, None] to trigger line 229 (continue for NoneType)."""
211+
"""Test Union[str, None]"""
216212
return {"optional": optional}
217213

218214

219-
# Test union field with multiple pydantic models (lines 253-254)
215+
# Test union field with multiple pydantic models
220216
class UnionFieldTestModel(BaseModel):
221217
choice: Union[SomeModel, OtherModel]
222218

@@ -239,9 +235,8 @@ def view_collection_union(request, data: CollectionUnionModel):
239235
return data.model_dump()
240236

241237

242-
# Additional model for testing complex nested union fields (lines 253-254)
238+
# Additional model for testing complex nested union fields
243239
class ComplexUnionField(BaseModel):
244-
# This should trigger lines 253-254 since it's a non-optional union of pydantic models
245240
model_choice: Union[SomeModel, OtherModel] # No None, no default
246241
name: str = "test"
247242

@@ -252,20 +247,19 @@ def view_complex_union_field(request, complex_data: ComplexUnionField):
252247
return complex_data.model_dump()
253248

254249

255-
# Model with union field that has NO default to trigger lines 253-254
250+
# Model with union field that has NO default
256251
class NoDefaultUnionModel(BaseModel):
257252
# This union field has NO default value and contains pydantic models
258-
# This should trigger lines 253-254
259253
required_union: Union[SomeModel, OtherModel]
260254

261255

262256
@router.post("/test-no-default-union")
263257
def view_no_default_union(request, no_default: NoDefaultUnionModel):
264-
"""Test union field with no default to trigger lines 253-254."""
258+
"""Test union field with no default."""
265259
return no_default.model_dump()
266260

267261

268-
# Complex nested model to trigger detect_collection_fields union logic (lines 394-413)
262+
# Complex nested model to trigger detect_collection_fields union logic
269263
class NestedWithCollections(BaseModel):
270264
items: List[str] # Collection field
271265

@@ -288,14 +282,14 @@ def view_deep_nested_union(request, deep_data: VeryDeepModel):
288282
return deep_data.model_dump()
289283

290284

291-
# Test to hit line 233 - trigger _model_flatten_map with Union containing None
285+
# trigger _model_flatten_map with Union containing None
292286
@router.post("/test-flatten-union-with-none")
293287
def view_flatten_union_with_none(request, data: Union[SomeModel, None]):
294-
"""Test direct Union[Model, None] to trigger line 233 in _model_flatten_map."""
288+
"""Test direct Union[Model, None]"""
295289
return data.model_dump() if data else {"result": "none"}
296290

297291

298-
# Test to hit line 233 more directly - nested union with None
292+
# nested union with None
299293
class ModelWithUnionField(BaseModel):
300294
union_field: Union[SomeModel, None] = (
301295
None # This should trigger _model_flatten_map with Union
@@ -304,18 +298,18 @@ class ModelWithUnionField(BaseModel):
304298

305299
@router.post("/test-nested-union-with-none")
306300
def view_nested_union_with_none(request, data: ModelWithUnionField):
307-
"""Test nested Union[Model, None] field to trigger line 233 in _model_flatten_map."""
301+
"""Test nested Union[Model, None]"""
308302
return data.model_dump()
309303

310304

311-
# Test to directly hit line 233 - Union parameter that gets flattened
305+
# Union parameter that gets flattened
312306
class OuterModel(BaseModel):
313307
inner: Union[SomeModel, OtherModel, None] # Union with None at top level
314308

315309

316310
@router.post("/test-direct-union-flattening")
317311
def view_direct_union_flattening(request, data: OuterModel):
318-
"""Test direct union flattening to hit line 233."""
312+
"""Test direct union flattening."""
319313
return data.model_dump()
320314

321315

@@ -399,7 +393,6 @@ def view_direct_union_flattening(request, data: OuterModel):
399393
dict(json=None),
400394
{"i": 1, "s": "test", "f": 1.5, "n": None},
401395
),
402-
# Test union with none (line 229)
403396
(
404397
"/test-union-with-none",
405398
dict(json=None),
@@ -410,7 +403,7 @@ def view_direct_union_flattening(request, data: OuterModel):
410403
dict(json=None),
411404
{"optional": "test"},
412405
),
413-
# Test union field model (lines 253-254)
406+
# Test union field model
414407
(
415408
"/test-union-field-model",
416409
dict(json={"choice": {"i": 1, "s": "test", "f": 1.5}}),
@@ -432,7 +425,7 @@ def view_direct_union_flattening(request, data: OuterModel):
432425
dict(json={"items": ["x"], "nested": {"i": 5, "s": "test", "f": 2.0}}),
433426
{"items": ["x"], "nested": {"i": 5, "s": "test", "f": 2.0, "n": None}},
434427
),
435-
# Test complex union field (lines 253-254)
428+
# Test complex union field
436429
(
437430
"/test-complex-union-field",
438431
dict(
@@ -451,7 +444,7 @@ def view_direct_union_flattening(request, data: OuterModel):
451444
dict(json={"model_choice": {"x": 10, "y": 20}, "name": "example"}),
452445
{"model_choice": {"x": 10, "y": 20}, "name": "example"},
453446
),
454-
# Test no default union (lines 253-254)
447+
# Test no default union
455448
(
456449
"/test-no-default-union",
457450
dict(json={"required_union": {"i": 2, "s": "required", "f": 2.5}}),
@@ -462,7 +455,7 @@ def view_direct_union_flattening(request, data: OuterModel):
462455
dict(json={"required_union": {"x": 5, "y": 10}}),
463456
{"required_union": {"x": 5, "y": 10}},
464457
),
465-
# Test deeply nested union (lines 394-413, 430, 433-436)
458+
# Test deeply nested union
466459
(
467460
"/test-deep-nested-union",
468461
dict(
@@ -498,7 +491,7 @@ def view_direct_union_flattening(request, data: OuterModel):
498491
"extra_items": [],
499492
},
500493
),
501-
# Test to hit line 233 - trigger _model_flatten_map with Union containing None
494+
# Test to trigger _model_flatten_map with Union containing None
502495
(
503496
"/test-flatten-union-with-none",
504497
dict(json={"i": 1, "s": "test", "f": 1.5}),
@@ -509,7 +502,7 @@ def view_direct_union_flattening(request, data: OuterModel):
509502
dict(json=None),
510503
{"result": "none"},
511504
),
512-
# Test nested union with None to hit line 233
505+
# Test nested union with None
513506
(
514507
"/test-nested-union-with-none",
515508
dict(json={"union_field": {"i": 1, "s": "test", "f": 1.5}}),
@@ -520,7 +513,7 @@ def view_direct_union_flattening(request, data: OuterModel):
520513
dict(json={"union_field": None}),
521514
{"union_field": None},
522515
),
523-
# Test direct union flattening to hit line 233
516+
# Test direct union flattening
524517
(
525518
"/test-direct-union-flattening",
526519
dict(json={"inner": {"i": 1, "s": "test", "f": 1.5}}),
@@ -536,26 +529,26 @@ def view_direct_union_flattening(request, data: OuterModel):
536529
dict(json={"inner": None}),
537530
{"inner": None},
538531
),
539-
# (
540-
# "/test-multi-model-union",
541-
# dict(json={"models": {"i": 1, "s": "test", "f": 1.5}}),
542-
# {"models": {"i": 1, "s": "test", "f": 1.5, "n": None}},
543-
# ),
544-
# (
545-
# "/test-optional-union",
546-
# dict(json=None),
547-
# {"result": "none"},
548-
# ),
549-
# (
550-
# "/test-nested-union",
551-
# dict(json={"nested_field": None, "simple_field": "test"}),
552-
# {"nested_field": None, "simple_field": "test"},
553-
# ),
554-
# (
555-
# "/test-complex-union?simple_union=42",
556-
# dict(json=None),
557-
# {"model_union": None, "simple_union": "42"},
558-
# ),
532+
(
533+
"/test-multi-model-union",
534+
dict(json={"models": {"i": 1, "s": "test", "f": 1.5}}),
535+
{"models": {"i": 1, "s": "test", "f": 1.5, "n": None}},
536+
),
537+
(
538+
"/test-optional-union",
539+
dict(json=None),
540+
{"result": "none"},
541+
),
542+
(
543+
"/test-nested-union",
544+
dict(json={"nested_field": None, "simple_field": "test"}),
545+
{"nested_field": None, "simple_field": "test"},
546+
),
547+
(
548+
"/test-complex-union?simple_union=42",
549+
dict(json=None),
550+
{"model_union": None, "simple_union": "42"},
551+
),
559552
],
560553
# fmt: on
561554
)

0 commit comments

Comments
 (0)