Improved Model.__init__() properties loop.
This improves readability, accumulates unrecognized arguments raise an exception with all of them, and avoids refetching the values.
This commit is contained in:
parent
0a4a5e5bac
commit
08d8bccbf1
|
@ -513,18 +513,27 @@ class Model(metaclass=ModelBase):
|
||||||
|
|
||||||
if kwargs:
|
if kwargs:
|
||||||
property_names = opts._property_names
|
property_names = opts._property_names
|
||||||
for prop in tuple(kwargs):
|
unexpected = ()
|
||||||
try:
|
for prop, value in kwargs.items():
|
||||||
# Any remaining kwargs must correspond to properties or
|
# Any remaining kwargs must correspond to properties or virtual
|
||||||
# virtual fields.
|
# fields.
|
||||||
if prop in property_names or opts.get_field(prop):
|
if prop in property_names:
|
||||||
if kwargs[prop] is not _DEFERRED:
|
if value is not _DEFERRED:
|
||||||
_setattr(self, prop, kwargs[prop])
|
_setattr(self, prop, value)
|
||||||
del kwargs[prop]
|
else:
|
||||||
except (AttributeError, FieldDoesNotExist):
|
try:
|
||||||
pass
|
opts.get_field(prop)
|
||||||
for kwarg in kwargs:
|
except FieldDoesNotExist:
|
||||||
raise TypeError("%s() got an unexpected keyword argument '%s'" % (cls.__name__, kwarg))
|
unexpected += (prop,)
|
||||||
|
else:
|
||||||
|
if value is not _DEFERRED:
|
||||||
|
_setattr(self, prop, value)
|
||||||
|
if unexpected:
|
||||||
|
unexpected_names = ', '.join(repr(n) for n in unexpected)
|
||||||
|
raise TypeError(
|
||||||
|
f'{cls.__name__}() got unexpected keyword arguments: '
|
||||||
|
f'{unexpected_names}'
|
||||||
|
)
|
||||||
super().__init__()
|
super().__init__()
|
||||||
post_init.send(sender=cls, instance=self)
|
post_init.send(sender=cls, instance=self)
|
||||||
|
|
||||||
|
|
|
@ -78,13 +78,23 @@ class ModelInstanceCreationTests(TestCase):
|
||||||
Article(None, 'Seventh article', datetime(2021, 3, 1), pub_date=None)
|
Article(None, 'Seventh article', datetime(2021, 3, 1), pub_date=None)
|
||||||
|
|
||||||
def test_cannot_create_instance_with_invalid_kwargs(self):
|
def test_cannot_create_instance_with_invalid_kwargs(self):
|
||||||
with self.assertRaisesMessage(TypeError, "Article() got an unexpected keyword argument 'foo'"):
|
msg = "Article() got unexpected keyword arguments: 'foo'"
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
Article(
|
Article(
|
||||||
id=None,
|
id=None,
|
||||||
headline='Some headline',
|
headline='Some headline',
|
||||||
pub_date=datetime(2005, 7, 31),
|
pub_date=datetime(2005, 7, 31),
|
||||||
foo='bar',
|
foo='bar',
|
||||||
)
|
)
|
||||||
|
msg = "Article() got unexpected keyword arguments: 'foo', 'bar'"
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
|
Article(
|
||||||
|
id=None,
|
||||||
|
headline='Some headline',
|
||||||
|
pub_date=datetime(2005, 7, 31),
|
||||||
|
foo='bar',
|
||||||
|
bar='baz',
|
||||||
|
)
|
||||||
|
|
||||||
def test_can_leave_off_value_for_autofield_and_it_gets_value_on_save(self):
|
def test_can_leave_off_value_for_autofield_and_it_gets_value_on_save(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -18,7 +18,7 @@ class PropertyTests(TestCase):
|
||||||
setattr(self.a, 'full_name', 'Paul McCartney')
|
setattr(self.a, 'full_name', 'Paul McCartney')
|
||||||
|
|
||||||
# And cannot be used to initialize the class.
|
# And cannot be used to initialize the class.
|
||||||
with self.assertRaisesMessage(TypeError, "Person() got an unexpected keyword argument 'full_name'"):
|
with self.assertRaises(AttributeError):
|
||||||
Person(full_name='Paul McCartney')
|
Person(full_name='Paul McCartney')
|
||||||
|
|
||||||
# But "full_name_2" has, and it can be used to initialize the class.
|
# But "full_name_2" has, and it can be used to initialize the class.
|
||||||
|
|
Loading…
Reference in New Issue