Closed junkmd closed 3 months ago
Still an issue with comtypes=1.4.2 installed on python 3.11.09 while trying to access CSI api. comtypes=1.3.1 on python 3.11.09 works fine
Error shown: TypeError('Attempted to reuse key: %r' % key .........
@coderPE
Thank you for the bug report.
I have a few questions for you. Please answer below as long as there are no issues with NDAs or licenses.
GetModule
or CreateObject
, but please tell us the arguments you passed to those functions.…/path/to/your/env/pkgs/comtypes/gen/…
when you encountered the error to your public repository.Since there are theoretically an infinite number of COM type libraries, some may have type information configurations that we have not anticipated before.
I do not know the specifications of all COM type libraries, so I would like you to share the information and knowledge you have with the community to help us solve the problem.
Best regards
Arguments passed: sap_object = comtypes.client.GetActiveObject("CSI.SAP2000.API.SapObject") This is the line that I'm executing, I don't think this has any arguments in it. gen.zip
The gen folder is attached.
API link: https://wiki.csiamerica.com/display/kb/OAPI The API access is bundled with the software license so I don't believe I can share it.
Detailed traceback is below: `--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[2], line 8 6 # Check if a running instance of SAP2000 is already open 7 try: ----> 8 sap_object = comtypes.client.GetActiveObject("CSI.SAP2000.API.SapObject") 9 sap_model = sap_object.SapModel 10 print("Attached to the running instance of SAP2000.")
File c:\Users\
File c:\Users\
File c:\Users\
File c:\Users\
File c:\Users\
File c:\Users\
File c:\Users\
File c:\Users\
File c:\Users\
File
File
File
File
File
File
File c:\Users\
File c:\Users\
File c:\Users\
TypeError: Attempted to reuse key: 'eHingeDistributionType_EqualSpacing'`
Thank you for your information.
The following is my speculation.
TypeError('Attempted to reuse key: ...
is an error that occurs when we define a duplicate member within enum.Enum
(or its subclass).
>>> from enum import IntFlag
>>> class Foo(IntFlag):
... SPAM = 1
... HAM = 2
... SPAM = 1
... BACON = 3
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in Foo
File "...\Python310\lib\enum.py", line 134, in __setitem__
raise TypeError('Attempted to reuse key: %r' % key)
TypeError: Attempted to reuse key: 'SPAM'
I have checked the CSiAPIv1.py
(hereinafter referred to as the friendly module) and _F896D55D_8BDF_4232_B9AB_4B210897A81D_0_1_0.py
(hereinafter referred to as the wrapper module) files you provided.
Surprisingly, it seems that the type information for eHingeDistributionType
in the CSiAPIv1
type library file defines a member with a different value using the same name eHingeDistributionType_EqualSpacing
.
# In `gen/_F896D55D_8BDF_4232_B9AB_4B210897A81D_0_1_0.py`, L102-L108;
# values for enumeration 'eHingeDistributionType'
eHingeDistributionType_NonlinearBeamColumn = 1
eHingeDistributionType_DistributedPlasticity = 2
eHingeDistributionType_EqualSpacing = 3
eHingeDistributionType_EqualSpacing = 4
eHingeDistributionType_EqualSpacing = 5
eHingeDistributionType = c_int # enum
# In `gen/CSiAPIv1.py`, L708-L713;
class eHingeDistributionType(IntFlag):
eHingeDistributionType_NonlinearBeamColumn = 1
eHingeDistributionType_DistributedPlasticity = 2
eHingeDistributionType_EqualSpacing = 3
eHingeDistributionType_EqualSpacing = 4
eHingeDistributionType_EqualSpacing = 5
comtypes
specificationscodegenerator
generates code based on the information of the COM type library.
No error avoidance measures have been taken so far when processing enumeration information with defined duplicate members.
This is because, from the basic principles of COM and the specifications of enumerations in most languages, it is hard to imagine that the same name member is defined in an enumeration.
However, since it is actually happening in CSiAPIv1
, it may be possible to define such an enumeration depending on the language that implemented the behavior of the API, and it may not cause an error when building.
I found a project on GitHub that is "Implementing the CSI api in Rust and using Tauri for the GUI".
https://github.com/PaoloLupo/albars
The enumeration eHingeDistributionType
was defined in the codebase of that project.
https://github.com/PaoloLupo/albars/blob/3b5cbfbe773318f250160a1ff8332966b436e7f4/src-tauri/crates/alba-api/src/bindings.rs#L11488-L11494
According to this, the members with the value 4 and 5 of eHingeDistributionType
are assigned the names eHingeDistributionType_ContinuousSupport
and eHingeDistributionType_UserDefined
.
The name eHingeDistributionType_EqualSpacing
is used only for the member with the value 3.
Information about eHingeDistributionType
could not be found on GitHub other than this project and this thread, and it was not found even when googled.
I don't know whether the cause of this name duplication is a discrepancy in the definition and specification of CSiAPIv1.tlb
, or a bug due to the implementation of the software.
I am considering the solution that comtypes
should take, so please wait for a while.
@coderPE
In the following branch, to prevent the TypeError('Attempted to reuse key: ...')
error, I have added workarounds to codegenerator
to comment out members of the enumeration type that have duplicate names.
https://github.com/junkmd/comtypes/tree/fix_525_attempted_to_reuse_key
Please execute the following command to install it and try it in your environment.
pip install https://github.com/junkmd/comtypes/archive/refs/heads/fix_525_attempted_to_reuse_key.zip
I have confirmed that this change has no impact on the COM type libraries used in CI and the environments I can verify. And I have checked how the enumeration type is defined in doctest.
On the other hand, I do not have the CSI-API. I also do not know of any COM type libraries that have type information for an enumeration type that defines members with the same name. Therefore, I can only rely on you to try this in your environment whether this change will work properly.
Whether this change works or not, please share the contents of …/path/to/your/env/pkgs/comtypes/gen/…
after running your script.
Best regards
@coderPE
Is there an update on this?
If we can confirm that this patch does not cause any errors in your script, I am considering including it in the next release scheduled for early June.
This is a patch to prevent the
TypeError
reported in https://github.com/enthought/comtypes/issues/524#issuecomment-2045252482.In
comtypes
, names of enumeration members are also used as names for constants at the wrapper module level. Leveraging this feature, the functionality to define enumeration types within friendly modules was implemented in #475.However, some COM libraries have duplicated names between enumeration members and CoClass or Interface names. In other words, integers may not be assigned to these names, they may actually be of a different type. When such a situation occurs and
comtypes
attempt to assign a non-integer object to the value of an enumeration member, aTypeError
is raised.In this PR, for resolving the aforementioned issue,
comtypes
assigns the integer literal values to the members of the enumeration types instead of referencing the namespace defined within the wrapper module.