@@ -426,7 +426,9 @@ def test_clahe_maps_both_parameters(self):
426426 ],
427427 ids = ["default" , "scalar-default-value" , "scalar" , "pair" , "pair-non-default" ],
428428 )
429- def test_clahe_scalar_clip_limit_is_a_range_not_a_fixed_value (self , configured , expected ) -> None :
429+ def test_clahe_scalar_clip_limit_is_a_range_not_a_fixed_value (
430+ self , configured : float | tuple [float , float ] | None , expected : tuple [float , float ]
431+ ) -> None :
430432 """Albumentations reads a scalar clip_limit as (1, v), so the GPU path must too.
431433
432434 Passing it through `_as_range` produced the degenerate (v, v), which pins every sample to maximum contrast
@@ -441,20 +443,39 @@ def test_clahe_scalar_clip_limit_is_a_range_not_a_fixed_value(self, configured,
441443
442444 assert tuple (transform .clip_limit ) == pytest .approx (expected )
443445
444- def test_clahe_clip_limit_matches_albumentations (self ) -> None :
446+ @pytest .mark .parametrize (
447+ "configured" ,
448+ [4.0 , 2.0 , (2.0 , 6.0 )],
449+ ids = ["scalar-default-value" , "scalar" , "pair" ],
450+ )
451+ def test_clahe_clip_limit_matches_albumentations (self , configured : float | tuple [float , float ]) -> None :
445452 """The contract stated directly: same config, same range on both backends."""
446453 albumentations = pytest .importorskip ("albumentations" )
447454
448455 from rfdetr .datasets .kornia_transforms import build_kornia_pipeline
449456
450- for configured in (4.0 , 2.0 , (2.0 , 6.0 )):
451- pipeline = build_kornia_pipeline ({"CLAHE" : {"clip_limit" : configured }}, 560 )
452- transform = next (iter (pipeline .children ()))
453- cpu = albumentations .CLAHE (clip_limit = configured )
457+ pipeline = build_kornia_pipeline ({"CLAHE" : {"clip_limit" : configured }}, 560 )
458+ transform = next (iter (pipeline .children ()))
459+ cpu = albumentations .CLAHE (clip_limit = configured )
454460
455- assert tuple (transform .clip_limit ) == pytest .approx (tuple (cpu .clip_limit )), (
456- f"backends disagree for clip_limit={ configured !r} "
457- )
461+ assert tuple (transform .clip_limit ) == pytest .approx (tuple (cpu .clip_limit )), (
462+ f"backends disagree for clip_limit={ configured !r} "
463+ )
464+
465+ @pytest .mark .parametrize ("configured" , [[4.0 ], (4.0 ,), (1.0 , 2.0 , 3.0 )], ids = ["one-list" , "one-tuple" , "three" ])
466+ def test_clahe_rejects_sequences_that_albumentations_rejects (
467+ self , configured : tuple [float , ...] | list [float ]
468+ ) -> None :
469+ """A one-element sequence is not a scalar.
470+
471+ Albumentations validates `clip_limit` as a float or an exact 2-tuple and raises on `[4.0]`. Reading it as a
472+ scalar here would accept a config the CPU backend refuses, which is the divergence this helper exists to
473+ remove.
474+ """
475+ from rfdetr .datasets .kornia_transforms import build_kornia_pipeline
476+
477+ with pytest .raises (ValueError , match = "2-element" ):
478+ build_kornia_pipeline ({"CLAHE" : {"clip_limit" : configured }}, 560 )
458479
459480 def test_hue_saturation_value_still_unsupported (self ):
460481 """Deliberately out of scope: albumentations shifts additively, Kornia scales multiplicatively."""
0 commit comments