Что вы думаете об этой ошибке Python?
Вопрос
Вот в чем ошибка.
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
Вот задействованный код на Python.
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)
И вот здесь задействован исходный код Python.
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);
}
Решение
Внутренняя ошибка, очевидно, является ошибкой в самом Python, и если вы заинтересованы в дальнейшем изучении этого и предложении исправления для ядра Python, то правильной стратегией было бы упростить ваш код до того уровня, когда он все еще вызывает ошибку.
Если вы больше заинтересованы в том, чтобы ваш код работал, а не в исправлении ядра Python, тогда я предлагаю вам избегать некоторых из нескольких аномалий в вашем коде, которые могут вносить путаницу в Python.Например, я не знаю, чтобы кому-нибудь когда-либо приходило в голову тестировать свойство для вложенной функции с именем f
содержащий еще одну дополнительно вложенную функцию также названный f
-- это ДОЛЖНО сработать, но это как раз та вещь, которая, возможно, не была хорошо протестирована только потому, что до этого еще никто не додумался, и хотя намеренное провоцирование таких аномалий является очень хорошей стратегией для усиления набора тестов, этого лучше избегать, если вы намеренно не пытаетесь вызвать ошибки во внутренних компонентах Python.
Итак, во-первых, я бы убедился, что вокруг нет омонимии.Если это все еще оставляет ошибку, я бы затем удалил использование объектов cell, превратив то, что в настоящее время является доступом к нелокальным переменным, в "предварительно связанные аргументы", например, ваш "полу-внешний" f
могли бы быть изменения для начала:
def f(self=self):
и ваш "полностью внутренний человек" мог бы стать:
def g(req, self=self):
Это сделало бы доступ к self
в любой из этих функций (в настоящее время осуществляется доступ к нелокальной переменной) осуществляется доступ к локальной переменной.Да, вы не должны были этого делать (в любом программном обеспечении не должно быть ошибок, требующих от вас работы по их обходу), но, увы, совершенство не является характеристикой этого подлунного мира, так что изучение стратегий обхода ошибок является неизбежной частью жизни;-).
Другие советы
Тот самый PyCell_Check
функция проверяет, что ее аргумент на самом деле является объектом cell (внутренний тип, используемый для реализации переменных, на которые ссылаются несколько областей).Если op
это не объект cell, вы бы получили эту ошибку.
Опубликованный вами код не дает достаточного контекста / информации, чтобы точно определить, как был передан неверный параметр.