Skip to content

Commit e78a716

Browse files
authored
Handle errors in range_handler comparisons (#269)
1 parent 7005a7e commit e78a716

2 files changed

Lines changed: 41 additions & 2 deletions

File tree

atom/src/validatebehavior.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -881,23 +881,37 @@ range_handler( Member* member, CAtom* atom, PyObject* oldvalue, PyObject* newval
881881
PyObject* high = PyTuple_GET_ITEM( member->validate_context, 1 );
882882
if( low != Py_None )
883883
{
884-
if( PyObject_RichCompareBool( low , newvalue, Py_GT ) )
884+
switch (PyObject_RichCompareBool( low , newvalue, Py_GT ))
885+
{
886+
case 0:
887+
break;
888+
case 1:
885889
return PyErr_Format(
886890
PyExc_ValueError,
887891
"range value for '%s' of '%s' too small",
888892
PyUnicode_AsUTF8( member->name ),
889893
Py_TYPE( pyobject_cast( atom ) )->tp_name
890894
);
895+
default:
896+
return 0;
897+
}
891898
}
892899
if( high != Py_None )
893900
{
894-
if( PyObject_RichCompareBool( high , newvalue, Py_LT ) )
901+
switch( PyObject_RichCompareBool( high , newvalue, Py_LT ) )
902+
{
903+
case 0:
904+
break;
905+
case 1:
895906
return PyErr_Format(
896907
PyExc_ValueError,
897908
"range value for '%s' of '%s' too large",
898909
PyUnicode_AsUTF8( member->name ),
899910
Py_TYPE( pyobject_cast( atom ) )->tp_name
900911
);
912+
default:
913+
return 0;
914+
}
901915
}
902916
return cppy::incref( newvalue );
903917
}

tests/test_validators.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,3 +434,28 @@ def test_custom_validate(mode, factory):
434434
with pytest.raises(TypeError) as excinfo:
435435
type(v).v.set_validate_mode(getattr(Validate, mode), 1)
436436
assert "str" in excinfo.exconly()
437+
438+
439+
def test_validate_range_error():
440+
class CustomInt(int):
441+
def __gt__(self, other):
442+
raise TypeError("Cannot be compared")
443+
444+
def __lt__(self, other):
445+
raise TypeError("Cannot be compared")
446+
447+
class Obj(Atom):
448+
x = Range(low=0)
449+
y = Range(high=10)
450+
451+
o = Obj()
452+
o.x = 1
453+
o.y = 9
454+
with pytest.raises(ValueError):
455+
o.x = -1
456+
with pytest.raises(ValueError):
457+
o.y = 11
458+
with pytest.raises(TypeError):
459+
o.x = CustomInt(-1)
460+
with pytest.raises(TypeError):
461+
o.y = CustomInt(11)

0 commit comments

Comments
 (0)