[Django] #28894: Invalid migrations caused by incorrect serialization of functools.partial()

18 views
Skip to first unread message

Django

unread,
Dec 5, 2017, 12:36:04 PM12/5/17
to django-...@googlegroups.com
#28894: Invalid migrations caused by incorrect serialization of functools.partial()
-------------------------------------+-------------------------------------
Reporter: Nick Pope | Owner: Nick Pope
Type: Bug | Status: assigned
Component: | Version: 1.9
Migrations | Keywords: functools partial
Severity: Normal | migrations serialization
Triage Stage: | Has patch: 1
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
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...

--
Ticket URL: <https://code.djangoproject.com/ticket/28894>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 5, 2017, 1:01:13 PM12/5/17
to django-...@googlegroups.com
#28894: Invalid migrations caused by incorrect serialization of functools.partial()
-------------------------------------+-------------------------------------
Reporter: Nick Pope | Owner: Nick Pope
Type: Bug | Status: assigned
Component: Migrations | Version: 1.9
Severity: Normal | Resolution:
Keywords: functools partial | Triage Stage:
migrations serialization | Unreviewed
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

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?

--
Ticket URL: <https://code.djangoproject.com/ticket/28894#comment:1>

Django

unread,
Dec 5, 2017, 1:22:34 PM12/5/17
to django-...@googlegroups.com
#28894: Invalid migrations caused by incorrect serialization of functools.partial()
-------------------------------------+-------------------------------------
Reporter: Nick Pope | Owner: Nick Pope
Type: Bug | Status: assigned
Component: Migrations | Version: 1.9
Severity: Normal | Resolution:
Keywords: functools partial | Triage Stage:
migrations serialization | Unreviewed
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Nick Pope):

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 [[https://github.com/django/django/pull/9428|PR]] anyway
so that it has a proper test...

--
Ticket URL: <https://code.djangoproject.com/ticket/28894#comment:2>

Django

unread,
Dec 5, 2017, 1:42:56 PM12/5/17
to django-...@googlegroups.com
#28894: Invalid migrations caused by incorrect serialization of functools.partial()
-------------------------------------+-------------------------------------
Reporter: Nick Pope | Owner: Nick Pope
Type: Bug | Status: assigned
Component: Migrations | Version: 1.9
Severity: Normal | Resolution:
Keywords: functools partial | Triage Stage:
migrations serialization | Unreviewed
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

How about adding `**{}` to your code?
{{{
>>> print(functools.partial(int, '123', **{}).keywords)
{}
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/28894#comment:3>

Django

unread,
Dec 5, 2017, 1:46:09 PM12/5/17
to django-...@googlegroups.com
#28894: Invalid migrations caused by incorrect serialization of functools.partial()
-------------------------------------+-------------------------------------
Reporter: Nick Pope | Owner: Nick Pope
Type: Bug | Status: assigned
Component: Migrations | Version: 1.9
Severity: Normal | Resolution:
Keywords: functools partial | Triage Stage:
migrations serialization | Unreviewed
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Nick Pope):

Cool. Nice hack!

I've just tried changing things to always have at least one keyword
argument anyway.

--
Ticket URL: <https://code.djangoproject.com/ticket/28894#comment:4>

Django

unread,
Dec 5, 2017, 2:51:01 PM12/5/17
to django-...@googlegroups.com
#28894: Invalid migrations caused by incorrect serialization of functools.partial()
-------------------------------------+-------------------------------------
Reporter: Nick Pope | Owner: Nick Pope
Type: Bug | Status: closed
Component: Migrations | Version: 1.9
Severity: Normal | Resolution: wontfix

Keywords: functools partial | Triage Stage:
migrations serialization | Unreviewed
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* status: assigned => closed
* resolution: => wontfix


Comment:

All right, I don't think it's worth adding a workaround to Django then.

--
Ticket URL: <https://code.djangoproject.com/ticket/28894#comment:5>

Reply all
Reply to author
Forward
0 new messages