mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-23 01:57:00 +03:00
Fix regression of RegexField
. (#4490)
* Don't deepcopy 'regex' arguments, instead treat as immutable.
This commit is contained in:
parent
a68b37d8bc
commit
4655501d51
|
@ -252,6 +252,8 @@ class SkipField(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
REGEX_TYPE = type(re.compile(''))
|
||||||
|
|
||||||
NOT_READ_ONLY_WRITE_ONLY = 'May not set both `read_only` and `write_only`'
|
NOT_READ_ONLY_WRITE_ONLY = 'May not set both `read_only` and `write_only`'
|
||||||
NOT_READ_ONLY_REQUIRED = 'May not set both `read_only` and `required`'
|
NOT_READ_ONLY_REQUIRED = 'May not set both `read_only` and `required`'
|
||||||
NOT_REQUIRED_DEFAULT = 'May not set both `required` and `default`'
|
NOT_REQUIRED_DEFAULT = 'May not set both `required` and `default`'
|
||||||
|
@ -581,16 +583,17 @@ class Field(object):
|
||||||
When cloning fields we instantiate using the arguments it was
|
When cloning fields we instantiate using the arguments it was
|
||||||
originally created with, rather than copying the complete state.
|
originally created with, rather than copying the complete state.
|
||||||
"""
|
"""
|
||||||
args = copy.deepcopy(self._args)
|
# Treat regexes and validators as immutable.
|
||||||
kwargs = dict(self._kwargs)
|
|
||||||
# Bit ugly, but we need to special case 'validators' as Django's
|
|
||||||
# RegexValidator does not support deepcopy.
|
|
||||||
# We treat validator callables as immutable objects.
|
|
||||||
# See https://github.com/tomchristie/django-rest-framework/issues/1954
|
# See https://github.com/tomchristie/django-rest-framework/issues/1954
|
||||||
validators = kwargs.pop('validators', None)
|
# and https://github.com/tomchristie/django-rest-framework/pull/4489
|
||||||
kwargs = copy.deepcopy(kwargs)
|
args = [
|
||||||
if validators is not None:
|
copy.deepcopy(item) if not isinstance(item, REGEX_TYPE) else item
|
||||||
kwargs['validators'] = validators
|
for item in self._args
|
||||||
|
]
|
||||||
|
kwargs = {
|
||||||
|
key: (copy.deepcopy(value) if (key not in ('validators', 'regex')) else value)
|
||||||
|
for key, value in self._kwargs.items()
|
||||||
|
}
|
||||||
return self.__class__(*args, **kwargs)
|
return self.__class__(*args, **kwargs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
|
@ -590,6 +591,20 @@ class TestRegexField(FieldValues):
|
||||||
field = serializers.RegexField(regex='[a-z][0-9]')
|
field = serializers.RegexField(regex='[a-z][0-9]')
|
||||||
|
|
||||||
|
|
||||||
|
class TestiCompiledRegexField(FieldValues):
|
||||||
|
"""
|
||||||
|
Valid and invalid values for `RegexField`.
|
||||||
|
"""
|
||||||
|
valid_inputs = {
|
||||||
|
'a9': 'a9',
|
||||||
|
}
|
||||||
|
invalid_inputs = {
|
||||||
|
'A9': ["This value does not match the required pattern."]
|
||||||
|
}
|
||||||
|
outputs = {}
|
||||||
|
field = serializers.RegexField(regex=re.compile('[a-z][0-9]'))
|
||||||
|
|
||||||
|
|
||||||
class TestSlugField(FieldValues):
|
class TestSlugField(FieldValues):
|
||||||
"""
|
"""
|
||||||
Valid and invalid values for `SlugField`.
|
Valid and invalid values for `SlugField`.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import pickle
|
import pickle
|
||||||
|
import re
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
@ -337,3 +338,16 @@ class TestDefaultInclusions:
|
||||||
assert serializer.is_valid()
|
assert serializer.is_valid()
|
||||||
assert serializer.validated_data == {'integer': 456}
|
assert serializer.validated_data == {'integer': 456}
|
||||||
assert serializer.errors == {}
|
assert serializer.errors == {}
|
||||||
|
|
||||||
|
|
||||||
|
class TestSerializerValidationWithCompiledRegexField:
|
||||||
|
def setup(self):
|
||||||
|
class ExampleSerializer(serializers.Serializer):
|
||||||
|
name = serializers.RegexField(re.compile(r'\d'), required=True)
|
||||||
|
self.Serializer = ExampleSerializer
|
||||||
|
|
||||||
|
def test_validation_success(self):
|
||||||
|
serializer = self.Serializer(data={'name': '2'})
|
||||||
|
assert serializer.is_valid()
|
||||||
|
assert serializer.validated_data == {'name': '2'}
|
||||||
|
assert serializer.errors == {}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user