Opened 3 years ago

Last modified 3 years ago

#23895 new Bug

ResolverMatch with some views is not pickleable

Reported by: Keryn Knight Owned by: nobody
Component: Core (URLs) Version: 1.7
Severity: Normal Keywords:
Cc: django@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

given something like the following:

def my_fbv(request):
    return HttpResponse('yay')

# urls.py
urlpatterns = [
    url('whatever', my_fbv, name='my_fbv'),
]

It is possible to do the following:

from django.core.urlresolvers import resolve
from pickle import dumps, loads
loads(dumps(resolve('whatever')))

and end up with a working ResolverMatch

However, given a Class Based View (mapped to a urlconf via MyView.as_view()), or something like contrib.admin, you get something like the following:

dumps(resolve('/admin/myapp/'))
[...]
# for the admin ...
PicklingError: Can't pickle <function app_index at 0x109f05de8>: it's not found as django.contrib.admin.sites.app_index
# for a CBV:
PicklingError: Can't pickle <function Homepage at 0x109f16b90>: it's not the same object as myapp.views.Homepage

Both of which are raised by pickle's save_global(self, obj, name, pack) which recognises that it's a module+name combo (thus should be in scope) but isn't the same object in identity (if x is not y)

Ordinarily, this is not a problem, but resolver_match is set onto a request, and I'm using the django.test.client.Client with multiprocessing, which requires the ability to pickle data to send back and forth, and evidently somewhere within the TemplateResponses I'm dealing with, the request is being serialised (if I had to guess -- probably in the context) and is sometimes failing (depending on the type of view mounted)

Ideally, every ResolverMatch should be serialisable, or none should be, instead of the current situation where the project's urlconf may denote success or failure.

Change History (2)

comment:1 Changed 3 years ago by Tim Graham

Triage Stage: UnreviewedAccepted

comment:2 Changed 3 years ago by Tom Christie

Haven't had a chance to confirm this much but appears that on 1.8-alpha this is consistently an issue, making responses non-cachable with CacheMiddleware. Alternative take would be for HttpResponse to take a more structured approach to caching - rather than simply dumping all attributes to pickle, just store the basics that allow a fresh HttpResponse with correct content, status code and headers to be reconstructed. (Eg. we shouldn't expect ResolverMatch instances to be picklable, but we *should* be constraining what we pickle for responses)

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