Code

Opened 7 years ago

Last modified 3 years ago

#6237 new Bug

PicklingError: Can't pickle <class 'django.template.SimpleNode'>: attribute lookup django.template.SimpleNode failed

Reported by: Simon Law <simon@…> Owned by: nobody
Component: Template system Version: master
Severity: Normal Keywords: pickle SimpleNode
Cc: simon@…, martin@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Code to reproduce:

import pickle
from django import template
t = template.Template("{% load adminmedia %}{% admin_media_prefix %}")
p = pickle.dumps(t)
print pickle.loads(p).render(template.Context({}))

Expected result:

u'/admin/media/'

Bug:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/pickle.py", line 1366, in dumps
    Pickler(file, protocol).dump(obj)
  File "/usr/lib/python2.5/pickle.py", line 224, in dump
    self.save(obj)
  File "/usr/lib/python2.5/pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "/usr/lib/python2.5/pickle.py", line 419, in save_reduce
    save(state)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/usr/lib/python2.5/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/usr/lib/python2.5/pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "/usr/lib/python2.5/pickle.py", line 401, in save_reduce
    save(args)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 562, in save_tuple
    save(element)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 600, in save_list
    self._batch_appends(iter(obj))
  File "/usr/lib/python2.5/pickle.py", line 615, in _batch_appends
    save(x)
  File "/usr/lib/python2.5/pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "/usr/lib/python2.5/pickle.py", line 401, in save_reduce
    save(args)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 562, in save_tuple
    save(element)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <class 'django.template.SimpleNode'>: it's not found as django.template.SimpleNode

Notes:
A hacky fix is attached, which preserves the semantics of SimpleNode. Since django.template.Library.simple_tag() is the only function that uses it, this may not be the optimal solution.

Attachments (2)

django-picking-simplenode.patch (1.7 KB) - added by Simon Law <simon@…> 7 years ago.
django-pickling-template-nodes.patch (4.9 KB) - added by Simon Law <simon@…> 7 years ago.

Download all attachments as: .zip

Change History (9)

Changed 7 years ago by Simon Law <simon@…>

comment:1 Changed 7 years ago by mtredinnick

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement set
  • Triage Stage changed from Unreviewed to Accepted

This patch can't be right. Each call to simple_tag() changes the module-level object, so they'll interfere with each other in subtle ways.

comment:2 Changed 7 years ago by Simon Law <simon@…>

The patch is horribly kludgy, in order to capture the closure on func, but it should totally work properly.

I am not advocating that you actually apply this patch. :P It's just a minimally invasive change for you to use in developing a proper fix.

comment:3 Changed 7 years ago by Simon Law <simon@…>

OK, so I bumped into those subtle errors that you were talking about.

Here is a revised patch where I've pulled the state out of the closures and made them explicit. This required changes to django.template.generic_tag_compiler(), but I think this is quite reasonable.

Changed 7 years ago by Simon Law <simon@…>

comment:4 Changed 6 years ago by anonymous

  • Cc martin@… added

comment:5 Changed 3 years ago by julien

  • Severity set to Normal
  • Type set to Bug

comment:6 Changed 2 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:7 Changed 2 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as new
The owner will be changed from nobody to anonymous. Next status will be 'assigned'
as The resolution will be set. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.