enthought / enthought/comtypes

Type checkers issues a warning when unpacking elements of `_fields_`.

Open
#663 0 comments 0 reactions 0 assignees View on GitHub
good first issue typing
Dominant language
Python
Stars
345
Forks
105
PR merge metrics
No merged PRs in 30d

Description

The following is pointed in https://github.com/python/typeshed/pull/12982#issuecomment-2466920145.

> I did a local comparison using `mypy --strict` and there were only two things that meaningfully changed, both additional findings:
>
> ```diff
> > comtypes/_memberspec.py:191: error: "type[_CData]" has no attribute "from_param" [attr-defined]
> > comtypes/test/find_memleak.py:26: error: Too many values to unpack (2 expected, 3 provided) [misc]
> ```

> The second is from a line like this:
>
> ```python
> for n, _ in self._fields_:
> ```
>
> This is also a correct addition. `_fields_` is typically a list of 2-tuples, and on the class in question within comtypes that's true, but in the general case it's valid for `_fields_` to include 3-tuples (c.f. https://docs.python.org/3/library/ctypes.html#ctypes.Structure._fields_). It's safe because your class doesn't use any 3-tuple fields, but I don't think there's anything that could be done in the stubs that would allow mypy to realize that.

Therefore, the following would be changed as shown.

https://github.com/enthought/comtypes/blob/2b411e539559e682976cad44a1098551d88aa8a3/comtypes/test/test_urlhistory.py#L20-L26

```diff
from comtypes.util import cast_field

result = type(self)()
- for n, _ in self._fields_:
+ for n, *_ in self._fields_:
setattr(result, n, getattr(self, n))
url, title = self.pwcsUrl, self.pwcsTitle
windll.ole32.CoTaskMemFree(cast_field(self, "pwcsUrl", c_void_p))
```

Additionally, similar code exists elsewhere, and `pyright` in my environment was issuing warnings about it. This would be changed as well.

https://github.com/enthought/comtypes/blob/2b411e539559e682976cad44a1098551d88aa8a3/comtypes/test/find_memleak.py#L23-L27

```diff
self.cb = sizeof(self)

def dump(self):
- for n, _ in self._fields_[2:]:
+ for n, *_ in self._fields_[2:]:
print(n, getattr(self, n) / 1e6)
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.