Que pensez-vous de cette erreur Python?
Question
Voici l'erreur.
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 295, in 'calling callback function'
File "USB2.py", line 454, in ff
self.drv_locked = False
SystemError: Objects/cellobject.c:24: bad argument to internal function
Voici le code Python impliqué.
def drv_send(self, data, size):
if not self.Connected():
return
def f():
self.drv_locked = True
buffer = ''.join(chr(c) for c in data[:size])
out_buffer = cast(buffer, POINTER(c_uint8))
request_handle = (OPENUSB_REQUEST_HANDLE * 1)()
request = (OPENUSB_INTR_REQUEST * 1)()
request_handle[0].dev = self.usbhandle
request_handle[0].interface = INTERFACE_ID
request_handle[0].endpoint = LIBUSB_ENDPOINT_OUT + 1
request_handle[0].type = USB_TYPE_INTERRUPT
request_handle[0].req.intr = request
def f(req):
print req[0].req.intr[0].result.status, req[0].req.intr[0].result.transferred_bytes
self.drv_locked = False # Line 454
request_handle[0].cb = REQUEST_CALLBACK(f)
request_handle[0].arg = None
request[0].payload = out_buffer
request[0].length = size
request[0].timeout = 5000
request[0].flags = 0
request[0].next = None
r = lib.openusb_xfer_aio(request_handle)
print "result", r
self.command_queue.put(f)
Et voici la source Python impliqués.
PyObject *
PyCell_Get(PyObject *op)
{
if (!PyCell_Check(op)) {
PyErr_BadInternalCall(); // Line 24
return NULL;
}
Py_XINCREF(((PyCellObject*)op)->ob_ref);
return PyCell_GET(op);
}
La solution
Une erreur interne est clairement un bogue dans Python lui-même, et si vous êtes intéressés à explorer davantage cette offre et une solution pour le noyau Python, ce qui simplifie alors votre code à l'endroit où il déclenche toujours le bug serait la bonne stratégie .
Si vous êtes plus intéressé à avoir votre travail de code, plutôt que dans la fixation du noyau Python, alors je vous suggère d'éviter certains des plusieurs anomalies dans votre code qui pourraient contribuer à confondre Python. Par exemple, je ne sais pas que tout le monde n'a jamais pensé à tester la propriété d'une fonction imbriquée appelée f
contenant une autre fonction supplémentaire imbriquée aussi nom f
- il devrait fonctionner, mais c'est exactement le genre de chose qui pourrait ne pas avoir été bien testé juste parce que personne ne pensait encore, et tout en provoquant délibérément de telles anomalies est une très bonne stratégie pour une suite d'renforçant les tests, il pourrait être préférable d'éviter si vous n'êtes pas délibérément pour déclencher des bugs dans les parties internes Python.
Alors, d'abord, je voudrais vous assurer qu'il n'y a pas homonimy autour. Si cela laisse encore le bug, je prochaine supprimer l'utilisation d'objets cellulaires en tournant ce sont actuellement accès à des variables non locales en « arguments de Prebound », par exemple votre « semi-extérieur » f
modifications pourraient être apportées pour commencer:
def f(self=self):
et votre « une entièrement intérieure » pourrait devenir:
def g(req, self=self):
Cela rendrait les accès à self
dans l'une de ces fonctions (actuellement variables nonlocal accès) dans la variable locale accède. Oui, vous ne devriez pas avoir à faire cela (il devrait y avoir pas de bugs dans un logiciel, qui vous oblige à travailler autour d'eux), mais hélas la perfection n'est pas une caractéristique de ce monde sublunaire, de sorte que l'apprentissage des stratégies bug-contournement est inévitable partie de la vie; -).
Autres conseils
La fonction PyCell_Check
vérifie que son argument est en fait un objet de cellule (un type interne utilisé pour mettre en oeuvre les variables référencées par plusieurs étendues). Si op
n'est pas un objet cellulaire, vous obtenez cette erreur.
Le code affiché ne donne pas suffisamment le contexte / informations pour déterminer exactement comment le mauvais paramètre est venu à passer.