O que você acha deste erro Python?
Pergunta
Aqui está o erro.
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
Aqui está o código Python envolvidos.
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)
E aqui está a fonte Python envolvidos.
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);
}
Solução
Um erro interno é claramente um bug no próprio Python, e se você estiver interessado em explorar mais profundamente esta e oferecendo uma correção para o núcleo Python, então simplificando seu código até onde ele ainda aciona o erro seria a estratégia correta .
Se você está mais interessado em ter seu código de trabalho, em vez de fixar o núcleo Python, então eu sugiro que você evite alguns dos várias anomalias em seu código que pode estar contribuindo para confundir Python. Por exemplo, eu não sei que alguém já pensou em propriedade de teste para uma função aninhada chamado f
contendo ainda uma outra função além-nested também chamado f
- ele deve funcionar, mas é exatamente o tipo de coisa que pode não ter sido bem testado apenas porque ninguém pensou nisso ainda, e enquanto deliberadamente provocar tais anomalias é uma estratégia muito boa de reforço de um conjunto de testes, pode ser melhor evitar se você não está deliberadamente para fora para erros de gatilho em internos do Python.
Assim, em primeiro lugar, gostaria de certificar-se de que não há em torno homonimy. Se isso ainda deixa o bug, eu seria o próximo a remover o uso de objetos celulares, transformando o que atualmente acessos a variáveis ??não-locais em "argumentos pré-ligado", por exemplo, o f
"semi-externa" poderia haver mudanças para começar com:
def f(self=self):
e seu "one totalmente interior" poderia tornar-se:
def g(req, self=self):
Isso tornaria acessos ao self
em qualquer dessas funções (atualmente não locais acessos variáveis) em acessos de variáveis ??locais. Sim, você não deve ter que fazer isso (não deve haver erros em qualquer software, que exige que você trabalhe em torno deles), mas infelizmente a perfeição não é uma característica deste mundo sublunar, de modo que aprender estratégias bug-solução é uma inevitável parte da vida; -).
Outras dicas
A função PyCell_Check
verifica que o seu argumento, na verdade, é um objecto da célula (um tipo interno usado para implementar variáveis ??referenciadas por vários âmbitos). Se op
não é um objeto de célula, você receber esse erro.
O código que você postou não dá contexto suficiente / informações para determinar exatamente como o parâmetro ruim veio a ser aprovada.