comtypes icon indicating copy to clipboard operation
comtypes copied to clipboard

Invalid Syntax error for CoClass with numbers only name.

Open ijb-ijb opened this issue 5 years ago • 4 comments

When connecting to a third party COM server I get the following error:

Traceback (most recent call last):
  File "v:/dev/Projekte3/inventsim_py/basic.py", line 4, in <module>
    app = comtypes.client.CreateObject("EMInvent.InventSim.App")
  File "C:\Users\jan\AppData\Roaming\Python\Python38\site-packages\comtypes\client\__init__.py", 
line 250, in CreateObject
    return _manage(obj, clsid, interface=interface)
  File "C:\Users\jan\AppData\Roaming\Python\Python38\site-packages\comtypes\client\__init__.py", 
line 188, in _manage
    obj = GetBestInterface(obj)
  File "C:\Users\jan\AppData\Roaming\Python\Python38\site-packages\comtypes\client\__init__.py", 
line 110, in GetBestInterface
    mod = GetModule(tlib)
  File "C:\Users\jan\AppData\Roaming\Python\Python38\site-packages\comtypes\client\_generate.py", line 110, in GetModule
    mod = _CreateWrapper(tlib, pathname)
  File "C:\Users\jan\AppData\Roaming\Python\Python38\site-packages\comtypes\client\_generate.py", line 184, in _CreateWrapper
    mod = _my_import(fullname)
  File "C:\Users\jan\AppData\Roaming\Python\Python38\site-packages\comtypes\client\_generate.py", line 24, in _my_import
    return __import__(fullname, globals(), locals(), ['DUMMY'])
  File "C:\Users\jan\AppData\Roaming\Python\Python38\site-packages\comtypes\gen\_1447D2FE_3193_49E8_BAB7_A56CE38BC9D8_0_2_0.py", line 21
    class 103205609(CoClass):
          ^
SyntaxError: invalid syntax

The cause of the problem is a coclass named with numbers only:

grafik

ParseCoClass of tlbparser.py uses the coclass name as an identifier. The generated generic module has an invalid syntax therefore.

I fixed it by modifying tlbparser.py. I modify the coclass name if necessary. It works for me but I don't know if there may be side effects.

def ParseCoClass(self, tinfo, ta):
        # possible ta.wTypeFlags: helpstring, helpcontext, licensed,
        #        version, control, hidden, and appobject
        coclass_name, doc = tinfo.GetDocumentation(-1)[0:2]

        coclass_name = self.make_valid_identifier(coclass_name) # ijb

        tlibattr = tinfo.GetContainingTypeLib()[0].GetLibAttr()
        coclass = typedesc.CoClass(coclass_name,
                                   str(ta.guid),
                                   self.coclass_type_flags(ta.wTypeFlags),
                                   tlibattr)
...

ijb-ijb avatar Aug 27 '20 18:08 ijb-ijb

Hi @ijb-ijb it seems there is no make_valid_identifier implementation in the code you posted. Is it possible to provide it as well?

vasily-v-ryabov avatar Dec 25 '20 13:12 vasily-v-ryabov

Well, I can handle this situation this way: class 103205609 will become class _103205609. So the interface of typelib will change, but it could be imported at least.

vasily-v-ryabov avatar Dec 25 '20 13:12 vasily-v-ryabov

Can you try this branch with your case?

pip install https://github.com/vasily-v-ryabov/comtypes/archive/tlb_parse_digits_only.zip

vasily-v-ryabov avatar Dec 25 '20 13:12 vasily-v-ryabov

Hello @vasily-v-ryabov , thank you for your help.

Here is the missing quick and dirty function I added:

def make_valid_identifier(name):
    regexp = "^[A-Za-z_][A-Za-z0-9_]*"
    match = re.search(regexp,name)
    if match is None:
        name = "_" + name
    return name

As you can see, I added an underscore too. That fixed my problem.

Unfortunately I currently have no access to the com server making troubles so I can't test your fix.

Adding an underscore by comtypes seems to be the only sensible solution for the problem.

ijb-ijb avatar Jan 04 '21 18:01 ijb-ijb