Opened 7 years ago
Closed 7 years ago
#28894 closed Bug (wontfix)
Invalid migrations caused by incorrect serialization of functools.partial()
Reported by: | Nick Pope | Owned by: | Nick Pope |
---|---|---|---|
Component: | Migrations | Version: | 1.9 |
Severity: | Normal | Keywords: | functools partial migrations serialization |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
So this one was interesting... I ended up with a migration that contained something like this (reduced to a trivial example):
models.CharField(default=functools.partial(int, *('123', ), **None), ...)
The expected output should have been:
models.CharField(default=functools.partial(int, *('123', ), **{}), ...)
It boils down to the following issue:
# Python 2.7.6: Empty args working, empty keywords broken. >>> import functools >>> print(functools.partial(int, base=10).args) () >>> print(functools.partial(int, '123').keywords) None
# Python 2.7.14: Empty args working, empty keywords working. >>> import functools >>> print(functools.partial(int, base=10).args) () >>> print(functools.partial(int, '123').keywords) {}
Scouring the release notes for Python, I found the following:
"The keywords attribute of functools.partial is now always a dictionary."
This was resolved in 2.7.10, 3.4.4 & 3.5.0.
As Django 2.1 will only support Python 3.5 or later, this only needs to be backported to 1.11 and 2.0 and need not be applied to master.
Pull request incoming...
Change History (5)
comment:1 by , 7 years ago
comment:2 by , 7 years ago
Indeed - I know of the policies, it's just an awkward problem. I'm not sure... It might be possible to force everything through as keyword arguments because args
is unaffected.
I've updated the PR anyway so that it has a proper test...
comment:3 by , 7 years ago
How about adding **{}
to your code?
>>> print(functools.partial(int, '123', **{}).keywords) {}
comment:4 by , 7 years ago
Cool. Nice hack!
I've just tried changing things to always have at least one keyword argument anyway.
comment:5 by , 7 years ago
Resolution: | → wontfix |
---|---|
Status: | assigned → closed |
All right, I don't think it's worth adding a workaround to Django then.
I'm not sure if this merits fixing considering
functools.partial
support was added in Django 1.9 so this isn't a new or common (apparently) regression. Also, regarding Python support, Django's policy is "We highly recommend and only officially support the latest release of each series." Can you workaround it in your project?