|
14 | 14 | import rest_framework
|
15 | 15 | from rest_framework import exceptions, serializers
|
16 | 16 | from rest_framework.compat import ProhibitNullCharactersValidator
|
17 |
| -from rest_framework.fields import DjangoImageField, is_simple_callable |
| 17 | +from rest_framework.fields import ( |
| 18 | + BuiltinSignatureError, DjangoImageField, is_simple_callable |
| 19 | +) |
18 | 20 |
|
19 | 21 | # Tests for helper functions.
|
20 | 22 | # ---------------------------
|
@@ -86,6 +88,18 @@ class Meta:
|
86 | 88 |
|
87 | 89 | assert is_simple_callable(ChoiceModel().get_choice_field_display)
|
88 | 90 |
|
| 91 | + def test_builtin_function(self): |
| 92 | + # Built-in function signatures are not easily inspectable, so the |
| 93 | + # current expectation is to just raise a helpful error message. |
| 94 | + timestamp = datetime.datetime.now() |
| 95 | + |
| 96 | + with pytest.raises(BuiltinSignatureError) as exc_info: |
| 97 | + is_simple_callable(timestamp.date) |
| 98 | + |
| 99 | + assert str(exc_info.value) == ( |
| 100 | + 'Built-in function signatures are not inspectable. Wrap the ' |
| 101 | + 'function call in a simple, pure Python function.') |
| 102 | + |
89 | 103 | def test_type_annotation(self):
|
90 | 104 | # The annotation will otherwise raise a syntax error in python < 3.5
|
91 | 105 | locals = {}
|
@@ -206,6 +220,18 @@ def example_callable(self):
|
206 | 220 |
|
207 | 221 | assert 'method call failed' in str(exc_info.value)
|
208 | 222 |
|
| 223 | + def test_builtin_callable_source_raises(self): |
| 224 | + class BuiltinSerializer(serializers.Serializer): |
| 225 | + date = serializers.ReadOnlyField(source='timestamp.date') |
| 226 | + |
| 227 | + with pytest.raises(BuiltinSignatureError) as exc_info: |
| 228 | + BuiltinSerializer({'timestamp': datetime.datetime.now()}).data |
| 229 | + |
| 230 | + assert str(exc_info.value) == ( |
| 231 | + 'Field source for `BuiltinSerializer.date` maps to a built-in ' |
| 232 | + 'function type and is invalid. Define a property or method on ' |
| 233 | + 'the `dict` instance that wraps the call to the built-in function.') |
| 234 | + |
209 | 235 |
|
210 | 236 | class TestReadOnly:
|
211 | 237 | def setup(self):
|
|
0 commit comments