mirror of https://github.com/kivy/kivy.git
EventDispatcher: Add nicer error message for non-existing properties (#7536)
* nicer error message for unknown properties * edit kivy/tests/test_widget.py * edit kivy/_event.pyx * edit kivy/_event.pyx, edit kivy/tests/test_widget.py * edit kivy/_event.pyx * edit kivy/_event.pyx * edit kivy/tests/test_widget.py, edit kivy/_event.pyx * edit kivy/tests/test_widget.py * edit kivy/tests/test_widget.py * edit kivy/_event.pyx * more tests * test * test * edit kivy/_event.pyx * move tests * fix ALL the things * Update kivy/_event.pyx Co-authored-by: matham <matt@einhorn.dev> * edit kivy/_event.pyx * pytestify * remove kivy/graphics/cgl.h * edit kivy/tests/test_properties.py * edit kivy/tests/test_properties.py, edit kivy/_event.pyx * typeerror * fix Co-authored-by: matham <matt@einhorn.dev>
This commit is contained in:
parent
c0800fa6f9
commit
28bfe768d8
|
@ -228,7 +228,19 @@ cdef class EventDispatcher(ObjectWithUid):
|
|||
prop_args = {
|
||||
k: kwargs.pop(k) for k in list(kwargs.keys()) if k in properties}
|
||||
self._kwargs_applied_init = set(prop_args.keys()) if prop_args else set()
|
||||
super(EventDispatcher, self).__init__(**kwargs)
|
||||
|
||||
# at this point any kwargs passed may go to object
|
||||
# which will raise a TypeError and cause confusion
|
||||
try:
|
||||
super(EventDispatcher, self).__init__(**kwargs)
|
||||
except TypeError as e:
|
||||
if kwargs and str(e).startswith("object.__init__() takes"):
|
||||
raise TypeError(
|
||||
'Properties {} passed to __init__ may not be existing '
|
||||
'property names. Valid properties are {}'.format(
|
||||
sorted(kwargs.keys()), sorted(properties.keys()))) from e
|
||||
else:
|
||||
raise
|
||||
|
||||
__cls__ = self.__class__
|
||||
if __cls__ not in cache_events_handlers:
|
||||
|
|
|
@ -1266,3 +1266,67 @@ def test_inherit_property():
|
|||
event.b = 'goodbye'
|
||||
assert event.b == 'goodbye'
|
||||
assert args == (event, 'goodbye')
|
||||
|
||||
|
||||
def test_unknown_property():
|
||||
from kivy.properties import NumericProperty
|
||||
|
||||
class MyWidget(EventDispatcher):
|
||||
width = NumericProperty(0)
|
||||
|
||||
with pytest.raises(TypeError) as cm:
|
||||
MyWidget(width=12, unkn="abc")
|
||||
assert "Properties ['unkn'] passed to __init__ may not be existing " \
|
||||
"property names. Valid properties are ['width']" \
|
||||
== str(cm.value)
|
||||
|
||||
|
||||
def test_known_property_multiple_inheritance():
|
||||
|
||||
class Behavior:
|
||||
def __init__(self, name):
|
||||
print(f'Behavior: {self}, name={name}')
|
||||
super().__init__()
|
||||
|
||||
class Widget2(Behavior, EventDispatcher):
|
||||
pass
|
||||
|
||||
class Widget3(EventDispatcher, Behavior):
|
||||
pass
|
||||
|
||||
with pytest.raises(TypeError) as cm:
|
||||
EventDispatcher(name='Pasta')
|
||||
assert "Properties ['name'] passed to __init__ may not be existing" \
|
||||
in str(cm.value)
|
||||
|
||||
Widget2(name='Pasta') # does not raise a ValueError
|
||||
Widget3(name='Pasta') # does not raise a ValueError
|
||||
|
||||
|
||||
def test_pass_other_typeerror():
|
||||
|
||||
class Behavior:
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
raise TypeError("this is a typeerror unrelated to object")
|
||||
|
||||
class Widget2(Behavior, EventDispatcher):
|
||||
pass
|
||||
|
||||
class Widget3(EventDispatcher, Behavior):
|
||||
pass
|
||||
|
||||
for cls in [Widget2, Widget3]:
|
||||
with pytest.raises(TypeError) as cm:
|
||||
cls(name='Pasta')
|
||||
assert "this is a typeerror unrelated to object" == str(cm.value)
|
||||
|
||||
|
||||
def test_object_init_error(): # the above 3 test rely on this
|
||||
class TestCls(object):
|
||||
def __init__(self, **kwargs):
|
||||
super(TestCls, self).__init__(**kwargs)
|
||||
|
||||
with pytest.raises(TypeError) as cm:
|
||||
TestCls(name='foo')
|
||||
assert str(cm.value).startswith("object.__init__() takes")
|
||||
|
|
Loading…
Reference in New Issue