Opened 4 months ago

Closed 4 months ago

#36383 closed Cleanup/optimization (fixed)

Improve migration serialization of functools.partial and functools.partialmethod

Reported by: Adam Johnson Owned by: Adam Johnson
Component: Migrations Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Currently, the migration serialization framework serializes functools.partial() and functools.partialmethod() in a quite confusing, hard-to-read way. For example, a source object constructed with:

functools.partial(datetime.timedelta, 1, seconds=2)

…is serialized as:

functools.partial(datetime.timedelta, *(1,), **{'seconds': 2})

The source includes unnecessary unpacking of a tuple into positional arguments and a dict into keyword arguments.

The tuple and dict are included even when arguments are empty, for example:

functools.partial(int)

…is serialized as:

functools.partial(int, *(), **{})

The result is quite a advanced Python syntax, the kind that I believe deters people from inspecting and understanding their migration files.

It seems partial serialization has been like this since support was added in #25185.

I propose that we reuse the logic for deconstructible objects.

While working on this ticket, I realized one gap in this idea: the **{} syntax allows keyword arguments that are not Python identifiers, but that is not supported by the current deconstructable serialization. Therefore, the associated PR also adds support for that.

Change History (7)

comment:1 by Adam Johnson, 4 months ago

Owner: set to Adam Johnson
Status: newassigned

comment:2 by Sarah Boyce, 4 months ago

Triage Stage: UnreviewedAccepted

Thank you for the suggestion. I think this is a desirable clean up which makes the serialization logic more consistent

comment:3 by Natalia Bidart, 4 months ago

Triage Stage: AcceptedReady for checkin

comment:4 by nessita <124304+nessita@…>, 4 months ago

In 0f94ecd4:

Refs #36383, #26151 -- Corrected spelling of DeconstructibleSerializer.

"Deconstructible" is the spelling that Django has settled on, such as
for django.utils.deconstruct. This commit normalizes a
previously-inconsistent class to match the rest of the codebase.

comment:5 by nessita <124304+nessita@…>, 4 months ago

In 4647e2b:

Refs #36383 -- Extended DeconstructibleSerializer to support non-identifier keyword arguments.

In Python, keyword arguments must normally be valid identifiers (i.e.,
variable names that follow Python's naming rules). However, Python dicts
can have keys that aren't valid identifiers, like "foo-bar" or "123foo".

This commit ensures that keyword arguments that are nt valid
identifiers, are properly handled when deconstructing an object.

comment:6 by nessita <124304+nessita@…>, 4 months ago

In 57fdc104:

Refs #36383 -- Added extra tests for serializing functools.partial in tests/migrations/test_writer.py.

This includes a test helper to better assert over the expected output.

Co-authored-by: Natalia <124304+nessita@…>

comment:7 by nessita <124304+nessita@…>, 4 months ago

Resolution: fixed
Status: assignedclosed

In 6e36f7f7:

Fixed #36383 -- Improved migration serialization for functools.partial objects.

Note: See TracTickets for help on using tickets.
Back to Top