Skip to content

comtypes.gen.Friendly's __file__, __repr__, ... are not what they really are #328

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
junkmd opened this issue Jul 19, 2022 · 4 comments · Fixed by #469
Closed

comtypes.gen.Friendly's __file__, __repr__, ... are not what they really are #328

junkmd opened this issue Jul 19, 2022 · 4 comments · Fixed by #469
Labels
drop_py2 dev based on supporting only Python3, see #392
Milestone

Comments

@junkmd
Copy link
Collaborator

junkmd commented Jul 19, 2022

Some dunder methods or attributes in a friendly named module under comtypes.gen return non-intuitive values.

>>> from comtypes.client import GetModule
>>> Scripting = GetModule("scrrun.dll")
>>> Scripting  # expected is `<module 'comtypes.gen.Scripting' from '...\\comtypes\\gen\\Scripting.py'>`, However ...
<module 'comtypes.gen._420B2830_E718_11CF_893D_00A0C9054228_0_1_0' from '...\\comtypes\\gen\\_420B2830_E718_11CF_893D_00A0C9054228_0_1_0.py'>

I wish fixing it.

@junkmd junkmd changed the title comtypes.gen.Friendly's __file__, __repr__ are not what they really are comtypes.gen.Friendly's __file__, __repr__, ... are not what they really are Jul 19, 2022
@junkmd
Copy link
Collaborator Author

junkmd commented Jan 9, 2023

For this issue, I feel that it would be better in terms of readability (for both humans and type-hints) to simply import the symbols used in the wrapper-module one by one, rather than manipulate the objects related to the namespace.

For example, comtypes.gen.stdole,

from comtypes.gen import _00020430_0000_0000_C000_000000000046_0_2_0
globals().update(_00020430_0000_0000_C000_000000000046_0_2_0.__dict__)
__name__ = 'comtypes.gen.stdole'

from comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0 import (
    IEnumVARIANT, FONTNAME, Unchecked, _lcid, OLE_YSIZE_CONTAINER,
    GUID, Checked, FONTITALIC, EXCEPINFO, _check_version,
    OLE_XPOS_CONTAINER, OLE_YPOS_PIXELS, OLE_HANDLE, IFont, HRESULT,
    FONTSTRIKETHROUGH, IFontEventsDisp, OLE_OPTEXCLUSIVE, Monochrome,
    Picture, OLE_YPOS_CONTAINER, IPicture, BSTR, StdFont,
    OLE_XPOS_HIMETRIC, DISPMETHOD, IUnknown, DISPPROPERTY, StdPicture,
    OLE_YSIZE_HIMETRIC, CoClass, OLE_XSIZE_HIMETRIC, FontEvents, Gray,
    COMMETHOD, FONTBOLD, Font, FONTSIZE, VgaColor, typelib_path,
    dispid, OLE_XSIZE_CONTAINER, OLE_CANCELBOOL, OLE_COLOR,
    OLE_TRISTATE, IDispatch, Library, OLE_YPOS_HIMETRIC,
    OLE_XPOS_PIXELS, Color, DISPPARAMS, VARIANT_BOOL,
    OLE_ENABLEDEFAULTBOOL, Default, FONTUNDERSCORE,
    LoadPictureConstants, IFontDisp, OLE_XSIZE_PIXELS, IPictureDisp,
    OLE_YSIZE_PIXELS
)


__all__ = [
    'IEnumVARIANT', 'FONTNAME', 'Unchecked', '_lcid',
    'OLE_YSIZE_CONTAINER', 'GUID', 'Checked', 'FONTITALIC',
    'EXCEPINFO', '_check_version', 'OLE_XPOS_CONTAINER',
    'OLE_YPOS_PIXELS', 'OLE_HANDLE', 'IFont', 'HRESULT',
    'FONTSTRIKETHROUGH', 'IFontEventsDisp', 'OLE_OPTEXCLUSIVE',
    'Monochrome', 'Picture', 'OLE_YPOS_CONTAINER', 'IPicture', 'BSTR',
    'StdFont', 'OLE_XPOS_HIMETRIC', 'DISPMETHOD', 'IUnknown',
    'DISPPROPERTY', 'StdPicture', 'OLE_YSIZE_HIMETRIC', 'CoClass',
    'OLE_XSIZE_HIMETRIC', 'FontEvents', 'Gray', 'COMMETHOD',
    'FONTBOLD', 'Font', 'FONTSIZE', 'VgaColor', 'typelib_path',
    'dispid', 'OLE_XSIZE_CONTAINER', 'OLE_CANCELBOOL', 'OLE_COLOR',
    'OLE_TRISTATE', 'IDispatch', 'Library', 'OLE_YPOS_HIMETRIC',
    'OLE_XPOS_PIXELS', 'Color', 'DISPPARAMS', 'VARIANT_BOOL',
    'OLE_ENABLEDEFAULTBOOL', 'Default', 'FONTUNDERSCORE',
    'LoadPictureConstants', 'IFontDisp', 'OLE_XSIZE_PIXELS',
    'IPictureDisp', 'OLE_YSIZE_PIXELS'
]

@junkmd
Copy link
Collaborator Author

junkmd commented Jan 9, 2023

I noticed during working on the drop_py2 plan that the __all__ did not include the Library class, even though it is a public symbol.

def TypeLib(self, lib: typedesc.TypeLib) -> None:
# Hm, in user code we have to write:
# class MyServer(COMObject, ...):
# _com_interfaces_ = [MyTypeLib.IInterface]
# _reg_typelib_ = MyTypeLib.Library._reg_typelib_
# ^^^^^^^
# Should the '_reg_typelib_' attribute be at top-level in the
# generated code, instead as being an attribute of the
# 'Library' symbol?
if not self.last_item_class:
print(file=self.stream)
print(file=self.stream)
self.last_item_class = True
print("class Library(object):", file=self.stream)
if lib.doc:
print(self._to_docstring(lib.doc), file=self.stream)
if lib.name:
print(" name = %r" % lib.name, file=self.stream)
print(
" _reg_typelib_ = (%r, %r, %r)" % (lib.guid, lib.major, lib.minor),
file=self.stream,
)
print(file=self.stream)
print(file=self.stream)

self.names.add("Library") should be needed.

@junkmd
Copy link
Collaborator Author

junkmd commented Jan 11, 2023

Suppose that typelib_path and Library are now included in CodeGenerator.names.

If only the symbols specified in CodeGenerator.names are imported into the friendly module from the wrapper module, how would it differ from the current friendly module?
If this were to be done, symbols that imported from known_symbols and alias definitions such as STRING = c_char_p would not be imported to friendly modules.

However, for example, it is unlikely that you will import comtypes.gen.stdole.IUnknown when you want to use IUnknown, and even if you did such things, you can easily fix them by simply changing the import.

@junkmd
Copy link
Collaborator Author

junkmd commented Jan 17, 2023

See #469

@junkmd junkmd closed this as completed Jan 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
drop_py2 dev based on supporting only Python3, see #392
Projects
None yet
1 participant