Вопрос

Вот в чем ошибка.

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, вы бы получили эту ошибку.

Опубликованный вами код не дает достаточного контекста / информации, чтобы точно определить, как был передан неверный параметр.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top