Skip to content

Commit a094f59

Browse files
committed
Make Field constructors keyword-only
1 parent 010c8d4 commit a094f59

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

rest_framework/fields.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ class Field:
320320
default_empty_html = empty
321321
initial = None
322322

323-
def __init__(self, read_only=False, write_only=False,
323+
def __init__(self, *, read_only=False, write_only=False,
324324
required=None, default=empty, initial=empty, source=None,
325325
label=None, help_text=None, style=None,
326326
error_messages=None, validators=None, allow_null=False):
@@ -1161,14 +1161,14 @@ class DateTimeField(Field):
11611161
}
11621162
datetime_parser = datetime.datetime.strptime
11631163

1164-
def __init__(self, format=empty, input_formats=None, default_timezone=None, *args, **kwargs):
1164+
def __init__(self, format=empty, input_formats=None, default_timezone=None, **kwargs):
11651165
if format is not empty:
11661166
self.format = format
11671167
if input_formats is not None:
11681168
self.input_formats = input_formats
11691169
if default_timezone is not None:
11701170
self.timezone = default_timezone
1171-
super().__init__(*args, **kwargs)
1171+
super().__init__(**kwargs)
11721172

11731173
def enforce_timezone(self, value):
11741174
"""
@@ -1247,12 +1247,12 @@ class DateField(Field):
12471247
}
12481248
datetime_parser = datetime.datetime.strptime
12491249

1250-
def __init__(self, format=empty, input_formats=None, *args, **kwargs):
1250+
def __init__(self, format=empty, input_formats=None, **kwargs):
12511251
if format is not empty:
12521252
self.format = format
12531253
if input_formats is not None:
12541254
self.input_formats = input_formats
1255-
super().__init__(*args, **kwargs)
1255+
super().__init__(**kwargs)
12561256

12571257
def to_internal_value(self, value):
12581258
input_formats = getattr(self, 'input_formats', api_settings.DATE_INPUT_FORMATS)
@@ -1313,12 +1313,12 @@ class TimeField(Field):
13131313
}
13141314
datetime_parser = datetime.datetime.strptime
13151315

1316-
def __init__(self, format=empty, input_formats=None, *args, **kwargs):
1316+
def __init__(self, format=empty, input_formats=None, **kwargs):
13171317
if format is not empty:
13181318
self.format = format
13191319
if input_formats is not None:
13201320
self.input_formats = input_formats
1321-
super().__init__(*args, **kwargs)
1321+
super().__init__(**kwargs)
13221322

13231323
def to_internal_value(self, value):
13241324
input_formats = getattr(self, 'input_formats', api_settings.TIME_INPUT_FORMATS)
@@ -1468,9 +1468,9 @@ class MultipleChoiceField(ChoiceField):
14681468
}
14691469
default_empty_html = []
14701470

1471-
def __init__(self, *args, **kwargs):
1471+
def __init__(self, **kwargs):
14721472
self.allow_empty = kwargs.pop('allow_empty', True)
1473-
super().__init__(*args, **kwargs)
1473+
super().__init__(**kwargs)
14741474

14751475
def get_value(self, dictionary):
14761476
if self.field_name not in dictionary:
@@ -1527,12 +1527,12 @@ class FileField(Field):
15271527
'max_length': _('Ensure this filename has at most {max_length} characters (it has {length}).'),
15281528
}
15291529

1530-
def __init__(self, *args, **kwargs):
1530+
def __init__(self, **kwargs):
15311531
self.max_length = kwargs.pop('max_length', None)
15321532
self.allow_empty_file = kwargs.pop('allow_empty_file', False)
15331533
if 'use_url' in kwargs:
15341534
self.use_url = kwargs.pop('use_url')
1535-
super().__init__(*args, **kwargs)
1535+
super().__init__(**kwargs)
15361536

15371537
def to_internal_value(self, data):
15381538
try:
@@ -1576,9 +1576,9 @@ class ImageField(FileField):
15761576
),
15771577
}
15781578

1579-
def __init__(self, *args, **kwargs):
1579+
def __init__(self, **kwargs):
15801580
self._DjangoImageField = kwargs.pop('_DjangoImageField', DjangoImageField)
1581-
super().__init__(*args, **kwargs)
1581+
super().__init__(**kwargs)
15821582

15831583
def to_internal_value(self, data):
15841584
# Image validation is a bit grungy, so we'll just outright
@@ -1593,8 +1593,8 @@ def to_internal_value(self, data):
15931593
# Composite field types...
15941594

15951595
class _UnvalidatedField(Field):
1596-
def __init__(self, *args, **kwargs):
1597-
super().__init__(*args, **kwargs)
1596+
def __init__(self, **kwargs):
1597+
super().__init__(**kwargs)
15981598
self.allow_blank = True
15991599
self.allow_null = True
16001600

@@ -1615,7 +1615,7 @@ class ListField(Field):
16151615
'max_length': _('Ensure this field has no more than {max_length} elements.')
16161616
}
16171617

1618-
def __init__(self, *args, **kwargs):
1618+
def __init__(self, **kwargs):
16191619
self.child = kwargs.pop('child', copy.deepcopy(self.child))
16201620
self.allow_empty = kwargs.pop('allow_empty', True)
16211621
self.max_length = kwargs.pop('max_length', None)
@@ -1627,7 +1627,7 @@ def __init__(self, *args, **kwargs):
16271627
"Remove `source=` from the field declaration."
16281628
)
16291629

1630-
super().__init__(*args, **kwargs)
1630+
super().__init__(**kwargs)
16311631
self.child.bind(field_name='', parent=self)
16321632
if self.max_length is not None:
16331633
message = lazy_format(self.error_messages['max_length'], max_length=self.max_length)
@@ -1692,7 +1692,7 @@ class DictField(Field):
16921692
'empty': _('This dictionary may not be empty.'),
16931693
}
16941694

1695-
def __init__(self, *args, **kwargs):
1695+
def __init__(self, **kwargs):
16961696
self.child = kwargs.pop('child', copy.deepcopy(self.child))
16971697
self.allow_empty = kwargs.pop('allow_empty', True)
16981698

@@ -1702,7 +1702,7 @@ def __init__(self, *args, **kwargs):
17021702
"Remove `source=` from the field declaration."
17031703
)
17041704

1705-
super().__init__(*args, **kwargs)
1705+
super().__init__(**kwargs)
17061706
self.child.bind(field_name='', parent=self)
17071707

17081708
def get_value(self, dictionary):
@@ -1751,8 +1751,8 @@ def run_child_validation(self, data):
17511751
class HStoreField(DictField):
17521752
child = CharField(allow_blank=True, allow_null=True)
17531753

1754-
def __init__(self, *args, **kwargs):
1755-
super().__init__(*args, **kwargs)
1754+
def __init__(self, **kwargs):
1755+
super().__init__(**kwargs)
17561756
assert isinstance(self.child, CharField), (
17571757
"The `child` argument must be an instance of `CharField`, "
17581758
"as the hstore extension stores values as strings."
@@ -1767,11 +1767,11 @@ class JSONField(Field):
17671767
# Workaround for isinstance calls when importing the field isn't possible
17681768
_is_jsonfield = True
17691769

1770-
def __init__(self, *args, **kwargs):
1770+
def __init__(self, **kwargs):
17711771
self.binary = kwargs.pop('binary', False)
17721772
self.encoder = kwargs.pop('encoder', None)
17731773
self.decoder = kwargs.pop('decoder', None)
1774-
super().__init__(*args, **kwargs)
1774+
super().__init__(**kwargs)
17751775

17761776
def get_value(self, dictionary):
17771777
if html.is_html_input(dictionary) and self.field_name in dictionary:

tests/test_fields.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,11 @@ def test_collection_types_are_invalid_input(self):
19861986
field.to_internal_value(input_value)
19871987
assert exc_info.value.detail == ['Expected a list of items but got type "dict".']
19881988

1989+
def test_constructor_misuse_raises(self):
1990+
# Test that `ListField` can only be instantiated with keyword arguments
1991+
with pytest.raises(TypeError):
1992+
serializers.ListField(serializers.CharField())
1993+
19891994

19901995
class TestNestedListField(FieldValues):
19911996
"""

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy