comtypes метод объекта com возвращает: объект 'tuple' не имеет атрибута '__ctypes_from_outparam__'

Я вызываю метод COM-объекта со строковым аргументом, используя comtypes, и метод возвращает (он должен возвращать строку COM):

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-102-009507ff0086> in <module>()
----> 1 obj1=xobjData.GetDataType('string_name')

C:\Python\Python27\lib\site-packages\comtypes\__init__.pyc in call_with_inout(self_, *args, **kw)
    657             # be iterable.
    658             if len(outargs) == 1:  # rescode is not iterable
--> 659                 return rescode.__ctypes_from_outparam__()
    660 
    661             rescode = list(rescode)

AttributeError: 'tuple' object has no attribute '__ctypes_from_outparam__'

Кажется очень загадочной ошибкой, любая помощь?

%debug магия показывает следующее:

> c:\python\python27\lib\site-packages\comtypes\__init__.py(659)call_with_inout()
    658             if len(outargs) == 1:  # rescode is not iterable
--> 659                 return rescode.__ctypes_from_outparam__()
    660 

ipdb> outargs
{0: VARIANT(vt=0x8, u'string_name')}
ipdb> rescode
(VARIANT(vt=0x8, u'string_name'), u'Long')
ipdb> print(dir(outargs))
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues']
ipdb> print(dir(rescode))
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
ipdb> u
> <ipython-input-112-83ed14b8961f>(1)<module>()
----> 1 xobjData.GetDataType(u'string_name')

ipdb> d
> c:\python\python27\lib\site-packages\comtypes\__init__.py(659)call_with_inout()
    658             if len(outargs) == 1:  # rescode is not iterable
--> 659                 return rescode.__ctypes_from_outparam__()
    660 

ipdb> exit

person denfromufa    schedule 30.09.2015    source источник
comment
github.com/enthought/comtypes/issues/87   -  person denfromufa    schedule 30.09.2015


Ответы (2)


В пакете comtype есть ошибка, которая приводит к ошибке атрибута, связанной с кортежами. Это можно исправить, заменив небольшой фрагмент кода, выполнив следующие шаги:

  1. В корневой папке Python перейдите в Lib\site-packages\comtypes\ и откройте файл __init__.py

  2. Перейдите к строке номер 658, вы найдете следующий фрагмент кода"

        if len(outargs) == 1:  # rescode is not iterable
                return rescode.__ctypes_from_outparam__()
        rescode = list(rescode)
        for outnum, o in list(outargs.items()):
            try:
                rescode[outnum] = o.__ctypes_from_outparam__()
    
  3. Замените приведенный выше фрагмент кода следующим:

        if len(outargs) == 1:  # rescode is not iterable
            try:
                return rescode.__ctypes_from_outparam__()
            except:
                return rescode
        rescode = list(rescode)
        for outnum, o in list(outargs.items()):
            try:
                rescode[outnum] = o.__ctypes_from_outparam__()
            except:
                rescode[outnum] = o
    
  4. Сохраните файл __init__.py и снова запустите программу.

person Naseef Ummer    schedule 06.11.2017

Это ошибка в comtypes, см. исправление здесь:

https://github.com/enthought/comtypes/issues/87

person denfromufa    schedule 30.09.2015
comment
Под родным я подразумевал встроенные типы, такие как str и int. В любом случае, я думаю, что ошибка в строке 658. Она должна проверять, является ли outnum == 1 and len(outargs) == 1 вместо len(outargs) == 1. Словарь outargs имеет только аргументы ввода/вывода, а не аргументы только вывода. В начальном цикле outnum увеличивается для обоих типов выходных аргументов. - person Eryk Sun; 30.09.2015
comment
@eryksun, тогда, пожалуйста, покажите фрагмент, который можно рассматривать как ответ - person denfromufa; 30.09.2015
comment
Я не собираюсь тянуть исходники и создавать патч. Вместо 658-659 попробуйте следующее: pastebin.com/SQN4gqZ0 - person Eryk Sun; 01.10.2015
comment
@eryksun ваше решение лучше! пожалуйста, добавьте ответ, чтобы я мог его принять. - person denfromufa; 01.10.2015