@@ -7,7 +7,7 @@ from collections import Counter
from datetime import timedelta
from errno import ENOENT
from types import TracebackType
-from typing import Optional, Union
+from typing import Optional, Union, cast
from . import _ext
from ._internal import poll_fd
@@ -97,6 +97,7 @@ class Chip:
longer be used after this method is called.
"""
self._check_closed()
+ self._chip = cast(_ext.Chip, self._chip)
self._chip.close()
self._chip = None
@@ -108,6 +109,7 @@ class Chip:
New gpiod.ChipInfo object.
"""
self._check_closed()
+ self._chip = cast(_ext.Chip, self._chip)
if not self._info:
self._info = self._chip.get_info()
@@ -132,6 +134,7 @@ class Chip:
so - returns it.
"""
self._check_closed()
+ self._chip = cast(_ext.Chip, self._chip)
if not isinstance(id, int):
try:
@@ -154,6 +157,7 @@ class Chip:
def _get_line_info(self, line: Union[int, str], watch: bool) -> LineInfo:
self._check_closed()
+ self._chip = cast(_ext.Chip, self._chip)
return self._chip.get_line_info(self.line_offset_from_id(line), watch)
def get_line_info(self, line: Union[int, str]) -> LineInfo:
@@ -192,6 +196,7 @@ class Chip:
Offset or name of the line to stop watching.
"""
self._check_closed()
+ self._chip = cast(_ext.Chip, self._chip)
return self._chip.unwatch_line_info(self.line_offset_from_id(line))
def wait_info_event(
@@ -226,6 +231,7 @@ class Chip:
This function may block if there are no available events in the queue.
"""
self._check_closed()
+ self._chip = cast(_ext.Chip, self._chip)
return self._chip.read_info_event()
def request_lines(
@@ -258,6 +264,7 @@ class Chip:
New LineRequest object.
"""
self._check_closed()
+ self._chip = cast(_ext.Chip, self._chip)
line_cfg = _ext.LineConfig()
@@ -362,6 +369,7 @@ class Chip:
Filesystem path used to open this chip.
"""
self._check_closed()
+ self._chip = cast(_ext.Chip, self._chip)
return self._chip.path
@property
@@ -370,4 +378,5 @@ class Chip:
File descriptor associated with this chip.
"""
self._check_closed()
+ self._chip = cast(_ext.Chip, self._chip)
return self._chip.fd
Since `Chip._chip` can be `None`, it's necessary to inform type checkers of the state of the object to silence the union-attr errors. Type checkers may not be able to infer that an object is not `None` from an earlier call (such as `_check_closed`). Instead of littering the code with "# type: ignore" comments, use casts to inform type checkers that objects are not `None`. Using `assert` is another option, however this duplicates the logic in `_check_closed` so is redundant at best and, at worst, is not a safe replacement as `assert` can be elided in optimized Python environments and these checks need to be runtime enforced. Signed-off-by: Vincent Fazio <vfazio@xes-inc.com> --- bindings/python/gpiod/chip.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)