Skip to content
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

Add stdlib/_ctypes #8571

Closed
junkmd opened this issue Aug 20, 2022 · 6 comments · Fixed by #8582
Closed

Add stdlib/_ctypes #8571

junkmd opened this issue Aug 20, 2022 · 6 comments · Fixed by #8582
Labels
stubs: incomplete Annotations or sub-modules missing from an existing package or module

Comments

@junkmd
Copy link
Contributor

junkmd commented Aug 20, 2022

My projects use some COM-ffi packages.

I use _ctypes.COMError or _ctypes.CopyComPointer too, but they are not defined in the type stub, so mypy type checker raises Cannot find implementation or library stub for module named "_ctypes" error.

I would like to add type stubs like this.

from ctypes import _CArgObject, _PointerLike
# are they correct?
_COMError_Details = tuple[str | None, str | None, str | None, int | None, int | None]  # Description, Source, HelpFile, HelpContext, scode

class COMError(Exception):
    """Raised when a COM method call failed."""
    hresult: int
    text: str
    details: _COMError_Details

    def __init__(self, hresult: _COMError_HResult, text: str, details: _COMError_Details) -> None: ...


def CopyComPointer(src: _PointerLike, dst: _PointerLike | _CArgObject) -> int: ...  # `dst` sometimes maybe return value of `ctypes.byref`.
    """CopyComPointer(src, dst) -> HRESULT value"""

But other APIs are not clear to me.

  • and where the if sys.platform == "win32": needed.

Any opinions would be appreciated.

@junkmd junkmd changed the title Add stdlib/ctypes/_ctypes.pyi Add stdlib/_ctypes.pyi Aug 20, 2022
@junkmd junkmd changed the title Add stdlib/_ctypes.pyi Add stdlib/_ctypes Aug 20, 2022
@Akuli
Copy link
Collaborator

Akuli commented Aug 20, 2022

Feel free to make a pull request :) There's already lots of other _foo.pyi modules in stdlib/.

Some thoughts:

  • We could mark _ctypes as incomplete. This is explained in CONTRIBUTING.md.
  • Com stuff isn't available on my linux system, so presumably everything except the import should go under if sys.platform == "win32".
  • Can _COMError_Details really be something like ("blah", None, None, 123, None)? If it's not possible for some but not all elements to be None, it should be tuple[str, str, str, int, int] | tuple[None, None, None, None, None].

@AlexWaygood
Copy link
Member

AlexWaygood commented Aug 20, 2022

Most of the stuff that we currently have in stdlib/ctypes/__init__.pyi is actually re-exported from _ctypes at runtime. If we add _ctypes.pyi, we should eventually move those definitions from stdlib/ctypes/__init__.pyi to _ctypes.pyi, to mimic the runtime more precisely. (That doesn't need to be done in the initial PR adding _ctypes.pyi, though.)

@junkmd
Copy link
Contributor Author

junkmd commented Aug 20, 2022

@Akuli

Thanks for your response.
I am motivated to contribute to this repository.

  • We could mark _ctypes as incomplete. This is explained in CONTRIBUTING.md.

I see. I will have to peruse the CONTRIBUTING.md.

  • Com stuff isn't available on my linux system, so presumably everything except the import should go under if sys.platform == "win32".

There was a post on stack overflow about the lack of COMError in a linux environment.
https://stackoverflow.com/questions/37161560/importerror-cannot-import-name-comerror-in-python

I will use if sys.platform == "win32" when defining COM related objects in stubs.

  • Can _COMError_Details really be something like ("blah", None, None, 123, None)? If it's not possible for some but not all elements to be None, it should be tuple[str, str, str, int, int] | tuple[None, None, None, None, None].

Each element of _COMError_Details can be None, int or str.

Searching _ctypes.COMError in github often shows (None, None, None, 0, None).
But there are also cases where we get tuple[str, str, str, int, None] or tuple[str, str, None, int, int].

Therefore, tuple[...] | tuple[...] does not represent the actual situation.

@junkmd
Copy link
Contributor Author

junkmd commented Aug 20, 2022

@AlexWaygood

Thanks for your response.

Most of the stuff that we currently have in stdlib/ctypes/__init__.pyi is actually re-exported from _ctypes at runtime. If we add _ctypes.pyi, we should eventually move those definitions from stdlib/ctypes/__init__.pyi to _ctypes.pyi, to mimic the runtime more precisely. (That doesn't need to be done in the initial PR adding _ctypes.pyi, though.)

Regardless of the relationship at runtime, I will create _ctypes stub using imported stuffs from ctypes for now.

I see that the _Pointer recently added to the ctypes stub is also originally defined in _ctypes.

Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes._Pointer
<class '_ctypes._Pointer'>

But I don't want to make it perfect from the beginning, I want to make it my first priority to get out of the situation where Cannot find ... module named "_ctypes" is displayed for now.

@AlexWaygood
Copy link
Member

@AlexWaygood

Thanks for your response.

Most of the stuff that we currently have in stdlib/ctypes/__init__.pyi is actually re-exported from _ctypes at runtime. If we add _ctypes.pyi, we should eventually move those definitions from stdlib/ctypes/__init__.pyi to _ctypes.pyi, to mimic the runtime more precisely. (That doesn't need to be done in the initial PR adding _ctypes.pyi, though.)

Regardless of the relationship at runtime, I will create _ctypes stub using imported stuffs from ctypes for now.

I see that the _Pointer recently added to the ctypes stub is also originally defined in _ctypes.

Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes._Pointer
<class '_ctypes._Pointer'>

But I don't want to make it perfect from the beginning, I want to make it my first priority to get out of the situation where Cannot find ... module named "_ctypes" is displayed for now.

Sounds good to me!

@hauntsaninja
Copy link
Collaborator

You'll also need to add _ctypes to https://github.com/python/typeshed/blob/master/stdlib/VERSIONS

@AlexWaygood AlexWaygood added the stubs: incomplete Annotations or sub-modules missing from an existing package or module label Aug 20, 2022
@AlexWaygood AlexWaygood linked a pull request Aug 21, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stubs: incomplete Annotations or sub-modules missing from an existing package or module
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants