Skip to content

Commit ffe82b8

Browse files
committed
Make Field constructors keyword-only
1 parent 3578683 commit ffe82b8

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):
@@ -1152,14 +1152,14 @@ class DateTimeField(Field):
11521152
}
11531153
datetime_parser = datetime.datetime.strptime
11541154

1155-
def __init__(self, format=empty, input_formats=None, default_timezone=None, *args, **kwargs):
1155+
def __init__(self, format=empty, input_formats=None, default_timezone=None, **kwargs):
11561156
if format is not empty:
11571157
self.format = format
11581158
if input_formats is not None:
11591159
self.input_formats = input_formats
11601160
if default_timezone is not None:
11611161
self.timezone = default_timezone
1162-
super().__init__(*args, **kwargs)
1162+
super().__init__(**kwargs)
11631163

11641164
def enforce_timezone(self, value):
11651165
"""
@@ -1238,12 +1238,12 @@ class DateField(Field):
12381238
}
12391239
datetime_parser = datetime.datetime.strptime
12401240

1241-
def __init__(self, format=empty, input_formats=None, *args, **kwargs):
1241+
def __init__(self, format=empty, input_formats=None, **kwargs):
12421242
if format is not empty:
12431243
self.format = format
12441244
if input_formats is not None:
12451245
self.input_formats = input_formats
1246-
super().__init__(*args, **kwargs)
1246+
super().__init__(**kwargs)
12471247

12481248
def to_internal_value(self, value):
12491249
input_formats = getattr(self, 'input_formats', api_settings.DATE_INPUT_FORMATS)
@@ -1304,12 +1304,12 @@ class TimeField(Field):
13041304
}
13051305
datetime_parser = datetime.datetime.strptime
13061306

1307-
def __init__(self, format=empty, input_formats=None, *args, **kwargs):
1307+
def __init__(self, format=empty, input_formats=None, **kwargs):
13081308
if format is not empty:
13091309
self.format = format
13101310
if input_formats is not None:
13111311
self.input_formats = input_formats
1312-
super().__init__(*args, **kwargs)
1312+
super().__init__(**kwargs)
13131313

13141314
def to_internal_value(self, value):
13151315
input_formats = getattr(self, 'input_formats', api_settings.TIME_INPUT_FORMATS)
@@ -1459,9 +1459,9 @@ class MultipleChoiceField(ChoiceField):
14591459
}
14601460
default_empty_html = []
14611461

1462-
def __init__(self, *args, **kwargs):
1462+
def __init__(self, **kwargs):
14631463
self.allow_empty = kwargs.pop('allow_empty', True)
1464-
super().__init__(*args, **kwargs)
1464+
super().__init__(**kwargs)
14651465

14661466
def get_value(self, dictionary):
14671467
if self.field_name not in dictionary:
@@ -1518,12 +1518,12 @@ class FileField(Field):
15181518
'max_length': _('Ensure this filename has at most {max_length} characters (it has {length}).'),
15191519
}
15201520

1521-
def __init__(self, *args, **kwargs):
1521+
def __init__(self, **kwargs):
15221522
self.max_length = kwargs.pop('max_length', None)
15231523
self.allow_empty_file = kwargs.pop('allow_empty_file', False)
15241524
if 'use_url' in kwargs:
15251525
self.use_url = kwargs.pop('use_url')
1526-
super().__init__(*args, **kwargs)
1526+
super().__init__(**kwargs)
15271527

15281528
def to_internal_value(self, data):
15291529
try:
@@ -1567,9 +1567,9 @@ class ImageField(FileField):
15671567
),
15681568
}
15691569

1570-
def __init__(self, *args, **kwargs):
1570+
def __init__(self, **kwargs):
15711571
self._DjangoImageField = kwargs.pop('_DjangoImageField', DjangoImageField)
1572-
super().__init__(*args, **kwargs)
1572+
super().__init__(**kwargs)
15731573

15741574
def to_internal_value(self, data):
15751575
# Image validation is a bit grungy, so we'll just outright
@@ -1584,8 +1584,8 @@ def to_internal_value(self, data):
15841584
# Composite field types...
15851585

15861586
class _UnvalidatedField(Field):
1587-
def __init__(self, *args, **kwargs):
1588-
super().__init__(*args, **kwargs)
1587+
def __init__(self, **kwargs):
1588+
super().__init__(**kwargs)
15891589
self.allow_blank = True
15901590
self.allow_null = True
15911591

@@ -1606,7 +1606,7 @@ class ListField(Field):
16061606
'max_length': _('Ensure this field has no more than {max_length} elements.')
16071607
}
16081608

1609-
def __init__(self, *args, **kwargs):
1609+
def __init__(self, **kwargs):
16101610
self.child = kwargs.pop('child', copy.deepcopy(self.child))
16111611
self.allow_empty = kwargs.pop('allow_empty', True)
16121612
self.max_length = kwargs.pop('max_length', None)
@@ -1618,7 +1618,7 @@ def __init__(self, *args, **kwargs):
16181618
"Remove `source=` from the field declaration."
16191619
)
16201620

1621-
super().__init__(*args, **kwargs)
1621+
super().__init__(**kwargs)
16221622
self.child.bind(field_name='', parent=self)
16231623
if self.max_length is not None:
16241624
message = lazy_format(self.error_messages['max_length'], max_length=self.max_length)
@@ -1683,7 +1683,7 @@ class DictField(Field):
16831683
'empty': _('This dictionary may not be empty.'),
16841684
}
16851685

1686-
def __init__(self, *args, **kwargs):
1686+
def __init__(self, **kwargs):
16871687
self.child = kwargs.pop('child', copy.deepcopy(self.child))
16881688
self.allow_empty = kwargs.pop('allow_empty', True)
16891689

@@ -1693,7 +1693,7 @@ def __init__(self, *args, **kwargs):
16931693
"Remove `source=` from the field declaration."
16941694
)
16951695

1696-
super().__init__(*args, **kwargs)
1696+
super().__init__(**kwargs)
16971697
self.child.bind(field_name='', parent=self)
16981698

16991699
def get_value(self, dictionary):
@@ -1742,8 +1742,8 @@ def run_child_validation(self, data):
17421742
class HStoreField(DictField):
17431743
child = CharField(allow_blank=True, allow_null=True)
17441744

1745-
def __init__(self, *args, **kwargs):
1746-
super().__init__(*args, **kwargs)
1745+
def __init__(self, **kwargs):
1746+
super().__init__(**kwargs)
17471747
assert isinstance(self.child, CharField), (
17481748
"The `child` argument must be an instance of `CharField`, "
17491749
"as the hstore extension stores values as strings."
@@ -1755,11 +1755,11 @@ class JSONField(Field):
17551755
'invalid': _('Value must be valid JSON.')
17561756
}
17571757

1758-
def __init__(self, *args, **kwargs):
1758+
def __init__(self, **kwargs):
17591759
self.binary = kwargs.pop('binary', False)
17601760
self.encoder = kwargs.pop('encoder', None)
17611761
self.decoder = kwargs.pop('decoder', None)
1762-
super().__init__(*args, **kwargs)
1762+
super().__init__(**kwargs)
17631763

17641764
def get_value(self, dictionary):
17651765
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
@@ -1957,6 +1957,11 @@ def test_collection_types_are_invalid_input(self):
19571957
field.to_internal_value(input_value)
19581958
assert exc_info.value.detail == ['Expected a list of items but got type "dict".']
19591959

1960+
def test_constructor_misuse_raises(self):
1961+
# Test that `ListField` can only be instantiated with keyword arguments
1962+
with pytest.raises(TypeError) as exc_info:
1963+
field = serializers.ListField(serializers.CharField())
1964+
19601965

19611966
class TestNestedListField(FieldValues):
19621967
"""

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