From 29edb72659e4fd3402c2e709d3f938f9c0f59a68 Mon Sep 17 00:00:00 2001 From: Alexander Schrijver Date: Sat, 4 Mar 2017 14:41:28 +0100 Subject: [PATCH] When a KeyError is thrown in a property attribute, it should propogate as a ValueError. --- rest_framework/fields.py | 5 ++++- tests/test_serializer.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 2efe89610..c5ad55668 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -100,7 +100,10 @@ def get_attribute(instance, attrs): if isinstance(instance, collections.Mapping): instance = instance[attr] else: - instance = getattr(instance, attr) + try: + instance = getattr(instance, attr) + except KeyError as exc: + raise ValueError('Exception raised in property attribute "{0}"; original exception was: {1}'.format(attr, exc)) except ObjectDoesNotExist: return None if is_simple_callable(instance): diff --git a/tests/test_serializer.py b/tests/test_serializer.py index cd82ba3df..5211a0c5a 100644 --- a/tests/test_serializer.py +++ b/tests/test_serializer.py @@ -344,6 +344,23 @@ class TestUnicodeRepr: class TestNotRequiredOutput: + def test_not_required_property_exception(self): + """ + A KeyError should propogate when it is thrown in a property attribute. + """ + class ExampleSerializer(serializers.Serializer): + raises_key_error = serializers.CharField(required=False) + + class ExampleObject: + @property + def raises_key_error(self): + raise KeyError() + + instance = ExampleObject() + serializer = ExampleSerializer(instance) + with pytest.raises(ValueError): + serializer.data + def test_not_required_output_for_dict(self): """ 'required=False' should allow a dictionary key to be missing in output.