Ne peut pas pickle < "type de fonction" >: attribut de recherche __builtin__.la fonction a échoué
Je reçois cette erreur dans mon application Django, cependant, il arrive seulement une fois par jour ou moins et il s'avère extrêmement difficile à déboguer.
Environment:
Request Method: POST
Django Version: 1.3.1
Python Version: 2.6.6
Installed Applications:
['django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'fimedlabs',
'data',
'djcelery']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'fimedlabs.auth.userMiddleWare')
Traceback:
File "/usr/local/lib/python2.6/dist-packages/django/core/handlers/base.py" in get_response
178. response = middleware_method(request, response)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/middleware.py" in process_response
36. request.session.save()
File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/db.py" in save
57. session_data = self.encode(self._get_session(no_load=must_create)),
File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/base.py" in encode
93. pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL)
Exception Type: PicklingError at /
Exception Value: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
J'ai essayé de répondre à ceci:
Comment dire pour lequel des attributs de l'objet pickle échoue?
par l'ajout de l'auto à l'erreur réelle pour voir si cela permettrait d'imprimer quoi que ce soit dans le Django d'erreur en vain.
Où puis-je imprimer l'objet est de donner à des questions à partir de cette erreur afin qu'il apparaisse dans la Django page d'erreur?
Merci!
~Matt
EDIT: Le seul objet que je suis stocker dans le cache, est un objet utilisateur avec le code:
class user(object):
username = str()
userid = uuid.UUID(int=0)
client = models.Client()
clientid = uuid.UUID(int=0)
clientname = ''
data = models.User()
accesslevel = models.AccessLevel()
active = False
client_active = False
isFimed = False
isFimedAdmin = False
isClientAdmin = False
isFimedManager = False
mysettingsform = None
viewingas = False
menu = []
_exists = False
_authenticated = False
def __str__(self):
return str(self.__dict__.copy())
def __getstate__(self):
return self.__dict__.copy()
def __setstate__(self, dict):
self.__dict__ = dict
def __init__(self, username=None):
if username:
self.initialize(username)
def initialize(self, username):
self.username = username
model = models.User.objects.filter(username=username).all()
if len(model) == 1:
model = model[0]
self.data = model
self._exists = True
self.userid = self.data.id
self.active = self.data.active
self.isFimed = self.data.isFimed()
self.isFimedAdmin = self.data.isFimedAdmin()
self.isClientAdmin = self.data.isClientAdmin()
self.isFimedManager = self.data.isFimedManager()
self.mysettingsform = UserFormSelf(initial={"id":model.id, "username":model.username, "name":model.name, "email":model.email, "phone":model.phone})
self.accesslevel = models.AccessLevel.objects.filter(id=self.data.accesslevel_id)[:1][0].level
cli = self.data.client
self.client = cli
self.clientid = cli.id
self.clientname = cli.name
if cli.active:
self.client_active = True
model.lastlogin = datetime.datetime.now()
model.save()
self.menu = getMenu(self.data)
else:
self._exists = False
def authenticate(self, password):
self._authenticated = False
if (self.active == False or self.client_active == False):
return False
if self._exists:
import hashlib
hash = hashlib.md5('%s%s' % (str(password), self.data.pwsalt)).hexdigest()
if hash == self.data.pwhash:
self._authenticated = True
return True
return False
def updateUser(self):
self.initialize(models.User.objects.filter(id=self.userid).get().username)
def mkContext(self):
c = Context()
c['menu'] = self.menu
c['user'] = self
c['language'] = language
c['colors'] = colors
c["isFimed"] = self.isFimed
c["isFimedAdmin"] = self.isFimedAdmin
c["isClientAdmin"] = self.isClientAdmin
c["isFimedManager"] = self.isFimedManager
c["mysettingsform"] = self.mysettingsform
return c
EDIT: fichier WSGI après Werkzeug:
import django.core.handlers.wsgi
djangoapplication = django.core.handlers.wsgi.WSGIHandler()
def application(environ, start_response):
if 'SCRIPT_NAME' in environ:
del environ['SCRIPT_NAME']
return djangoapplication(environ, start_response)
# The following lines enable the werkzeug debugger
import django.views.debug
def null_technical_500_response(request, exc_type, exc_value, tb):
raise exc_type, exc_value, tb
django.views.debug.technical_500_response = null_technical_500_response
from werkzeug.debug import DebuggedApplication
application = DebuggedApplication(application, evalex=True)
OriginalL'auteur MatthewKremer | 2012-06-05
Vous devez vous connecter pour publier un commentaire.
La réponse courte - sans recompiler
cPickle
, vous ne pouvez pas.Plus réponse: C'est le morceau de code qui soulève l'exception:
Si vous regardez d'assez près, il y a un morceau qui dit
Maintenant, si vous téléchargez des sources Python, vous pouvez facilement trouver le morceau de code responsable de la levée de l'exception dans la fonction
static int save_global(Picklerobject *self, PyObject *args, PyObject *name)
de./Modules/cPickle.c
:Donc, le meilleur que vous pouvez faire pour corriger de cette erreur, c'est le format de la chaîne différemment (probablement fournir
PyString_AS_STRING((PyStringObject *)name)
, recompilez et installez la version modifiée de Python.Oui, je sais, c'est trop mauvais. J'ai juste eu le même problème moi-même.
OriginalL'auteur
Dans mon cas (pas de Django connexes) cette exception a été levée par
multiprocessing.Pool.map
lorsqu'un lambda a été adoptée comme la fonction cible. La création d'un nom de fonction et en passant le besoin de structures de données du contexte via lainitargs
paramètre (plutôt que par le biais de la fermeture) a résolu le problème.Pour résumer, le mauvais de cas d'utilisation qui a déclenché l'exception a été:
worker_func = lambda x: work(x, context)
ne fonctionne pas dans Python2.7, maisdef worker_func(x): return work(x, context)
. Et devrait mettre la fonction avantpool = mp.Pool()
OriginalL'auteur alexei
Utiliser quelque chose comme
django-extensions
pour installer le werkzeug débogueur. Vous serez en mesure d'interagir avec chaque structure de pile. À ce stade, vous pouvez essayer de décapage de l'ensemble des clés et des valeurs dans la session dict.Cela signifie généralement que le débogueur de choses ont déjà été supprimés sur le serveur. Pouvez-vous reproduire l'erreur en utilisant le serveur de développement de django (invoquer avec
runserver_plus
)? Il se pourrait bien travailler un peu mieux là.Est-il un moyen de le faire tourner avec runserver_plus lorsqu'il démarre au lieu de runserver? Il est presque impossible à reproduire, il arrive juste au hasard (il me semble), donc je ne peux pas exécuter cette commande, puis essayez de déboguer vraiment.
Courir avec runserver_plus, puis utilisent quel que soit le régime d'essai vous avez jusqu'au déclenchement de l'erreur.
OriginalL'auteur Marcin
Si vous êtes le stockage d'un objet utilisateur, vous pouvez être affecté par ce bug:
https://code.djangoproject.com/ticket/16563
Cela dit, votre meilleur pari est d'aller d'être juste modifier le Django code source à la ligne 93 de /usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/base.py lorsque l'exception se produit.
Suffit de vous connecter session_dict. Dans la plupart des cas, il est vraiment évident que ce qui est mauvais. (En effet, si votre traceback montre Local Vars, vous avez déjà ce)
OriginalL'auteur UsAaR33