Skip to content

Commit 8e304e1

Browse files
james-mchughJames Riley McHugh
and
James Riley McHugh
authored
Fixed AttributeError raised by data property being silently ignored (#9455)
Signed-off-by: James Riley McHugh <[email protected]> Co-authored-by: James Riley McHugh <[email protected]>
1 parent b6ea110 commit 8e304e1

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

rest_framework/request.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ def query_params(self):
217217
@property
218218
def data(self):
219219
if not _hasattr(self, '_full_data'):
220-
self._load_data_and_files()
220+
with wrap_attributeerrors():
221+
self._load_data_and_files()
221222
return self._full_data
222223

223224
@property
@@ -420,13 +421,14 @@ def __getattr__(self, attr):
420421
_request = self.__getattribute__("_request")
421422
return getattr(_request, attr)
422423
except AttributeError:
423-
return self.__getattribute__(attr)
424+
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{attr}'")
424425

425426
@property
426427
def POST(self):
427428
# Ensure that request.POST uses our request parsing.
428429
if not _hasattr(self, '_data'):
429-
self._load_data_and_files()
430+
with wrap_attributeerrors():
431+
self._load_data_and_files()
430432
if is_form_media_type(self.content_type):
431433
return self._data
432434
return QueryDict('', encoding=self._request._encoding)
@@ -437,7 +439,8 @@ def FILES(self):
437439
# Different from the other two cases, which are not valid property
438440
# names on the WSGIRequest class.
439441
if not _hasattr(self, '_files'):
440-
self._load_data_and_files()
442+
with wrap_attributeerrors():
443+
self._load_data_and_files()
441444
return self._files
442445

443446
def force_plaintext_errors(self, value):

tests/test_request.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,25 @@ def test_standard_behaviour_determines_non_form_content_PUT(self):
126126
request.parsers = (PlainTextParser(), )
127127
assert request.data == content
128128

129+
def test_calling_data_fails_when_attribute_error_is_raised(self):
130+
"""
131+
Ensure attribute errors raised when parsing are properly re-raised.
132+
"""
133+
expected_message = "Internal error"
134+
135+
class BrokenParser:
136+
media_type = "application/json"
137+
138+
def parse(self, *args, **kwargs):
139+
raise AttributeError(expected_message)
140+
141+
http_request = factory.post('/', data={}, format="json")
142+
request = Request(http_request)
143+
request.parsers = (BrokenParser,)
144+
145+
with self.assertRaisesMessage(WrappedAttributeError, expected_message):
146+
request.data
147+
129148

130149
class MockView(APIView):
131150
authentication_classes = (SessionAuthentication,)

0 commit comments

Comments
 (0)