Opened 9 years ago

Closed 9 months ago

#6237 closed Bug (needsinfo)

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@…> 9 years ago.
django-pickling-template-nodes.patch (4.9 KB) - added by Simon Law <simon@…> 9 years ago.

Download all attachments as: .zip

Change History (10)

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

comment:1 Changed 9 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 9 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 9 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 9 years ago by Simon Law <simon@…>

comment:4 Changed 8 years ago by anonymous

  • Cc martin@… added

comment:5 Changed 5 years ago by julien

  • Severity set to Normal
  • Type set to Bug

comment:6 Changed 4 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:7 Changed 4 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:8 Changed 9 months ago by timgraham

  • Resolution set to needsinfo
  • Status changed from new to closed

It's unclear to me how to move forward with this ticket or if it remains an issue as the file modified by the proposed patch has changed quite a bit in 8 years.

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