@@ -68,6 +68,7 @@ def __post_init__(self) -> None:
6868 )
6969 raise TypeError ("FlowEntry.priority must be a non-negative int" )
7070
71+ # Basic numeric validation
7172 for name , value in (
7273 ("demand" , self .demand ),
7374 ("placed" , self .placed ),
@@ -79,9 +80,25 @@ def __post_init__(self) -> None:
7980 if not math .isfinite (float (value )):
8081 logger .error ("FlowEntry.%s must be finite: %r" , name , value )
8182 raise ValueError (f"FlowEntry.{ name } must be finite" )
82- if float (value ) < 0.0 :
83- logger .error ("FlowEntry.%s must be non-negative: %r" , name , value )
84- raise ValueError (f"FlowEntry.{ name } must be non-negative" )
83+
84+ # Non-negativity with tolerance for floating-point artifacts on 'dropped'
85+ if float (self .demand ) < 0.0 :
86+ logger .error ("FlowEntry.demand must be non-negative: %r" , self .demand )
87+ raise ValueError ("FlowEntry.demand must be non-negative" )
88+ if float (self .placed ) < 0.0 :
89+ logger .error ("FlowEntry.placed must be non-negative: %r" , self .placed )
90+ raise ValueError ("FlowEntry.placed must be non-negative" )
91+ if float (self .dropped ) < 0.0 :
92+ # Clamp tiny negative values caused by rounding noise
93+ if abs (float (self .dropped )) <= 1e-9 :
94+ logger .debug (
95+ "Normalizing tiny negative FlowEntry.dropped %.12g to 0.0" ,
96+ float (self .dropped ),
97+ )
98+ self .dropped = 0.0
99+ else :
100+ logger .error ("FlowEntry.dropped must be non-negative: %r" , self .dropped )
101+ raise ValueError ("FlowEntry.dropped must be non-negative" )
85102
86103 # Consistency: dropped ≈ demand - placed
87104 expected_drop = float (self .demand ) - float (self .placed )
0 commit comments