From ab3c4f42cce01e83ffa7cb6dc026a5712098b46c Mon Sep 17 00:00:00 2001 From: Felix Divo Date: Sat, 5 Jun 2021 22:42:10 +0200 Subject: [PATCH 1/7] improve IO module typing --- can/io/generic.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/can/io/generic.py b/can/io/generic.py index de8e91700..b8650e80d 100644 --- a/can/io/generic.py +++ b/can/io/generic.py @@ -3,19 +3,20 @@ """ from abc import ABCMeta -from typing import Any, Optional, cast, Union, TextIO, BinaryIO, Type +from typing import Any, Optional, cast, Iterable, Union, TextIO, BinaryIO, Type, ContextManager +from typing_extensions import Literal import can import can.typechecking -class BaseIOHandler(metaclass=ABCMeta): +class BaseIOHandler(ContextManager, metaclass=ABCMeta): """A generic file handler that can be used for reading and writing. Can be used as a context manager. :attr Optional[FileLike] file: - the file-like object that is kept internally, or None if none + the file-like object that is kept internally, or `None` if none was opened """ @@ -39,7 +40,7 @@ def __init__(self, file: can.typechecking.AcceptedIOType, mode: str = "rt") -> N def __enter__(self) -> "BaseIOHandler": return self - def __exit__(self, exc_type: Type, exc_val: Any, exc_tb: Any) -> Any: + def __exit__(self, exc_type: Type, exc_val: Any, exc_tb: Any) -> Literal[False]: self.stop() return False @@ -63,5 +64,5 @@ class FileIOMessageWriter(MessageWriter, metaclass=ABCMeta): # pylint: disable=too-few-public-methods -class MessageReader(BaseIOHandler, metaclass=ABCMeta): +class MessageReader(BaseIOHandler, Iterable, metaclass=ABCMeta): """The base class for all readers.""" From 44d1a6ffaeb61ce9a20b85e9859d02cc92aa7197 Mon Sep 17 00:00:00 2001 From: Felix Divo Date: Sun, 6 Jun 2021 00:01:25 +0200 Subject: [PATCH 2/7] Add missing typing_extensions dependency --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index d8b76b250..38ffaf497 100644 --- a/setup.py +++ b/setup.py @@ -85,6 +85,7 @@ "wrapt~=1.10", 'windows-curses;platform_system=="Windows" and platform_python_implementation=="CPython"', "mypy_extensions>=0.4.0,<0.5.0", + "typing_extensions>=3.10.0.0", 'pywin32;platform_system=="Windows" and platform_python_implementation=="CPython"', 'msgpack~=1.0.0;platform_system!="Windows"', ], From d388dcf3b55f30a43bf0b4b099c5feeed32adde9 Mon Sep 17 00:00:00 2001 From: Felix Divo Date: Sun, 6 Jun 2021 00:03:58 +0200 Subject: [PATCH 3/7] Remove the now unnesesary mypy_extensions --- can/typechecking.py | 8 ++++---- setup.py | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/can/typechecking.py b/can/typechecking.py index d29f1ccaf..1aaf03ac4 100644 --- a/can/typechecking.py +++ b/can/typechecking.py @@ -6,10 +6,10 @@ if typing.TYPE_CHECKING: import os -import mypy_extensions +import typing_extensions -CanFilter = mypy_extensions.TypedDict("CanFilter", {"can_id": int, "can_mask": int}) -CanFilterExtended = mypy_extensions.TypedDict( +CanFilter = typing_extensions.TypedDict("CanFilter", {"can_id": int, "can_mask": int}) +CanFilterExtended = typing_extensions.TypedDict( "CanFilterExtended", {"can_id": int, "can_mask": int, "extended": bool} ) CanFilters = typing.Sequence[typing.Union[CanFilter, CanFilterExtended]] @@ -33,7 +33,7 @@ BusConfig = typing.NewType("BusConfig", typing.Dict[str, typing.Any]) -AutoDetectedConfig = mypy_extensions.TypedDict( +AutoDetectedConfig = typing_extensions.TypedDict( "AutoDetectedConfig", {"interface": str, "channel": Channel} ) diff --git a/setup.py b/setup.py index 38ffaf497..1b56379cf 100644 --- a/setup.py +++ b/setup.py @@ -84,7 +84,6 @@ # "setuptools", "wrapt~=1.10", 'windows-curses;platform_system=="Windows" and platform_python_implementation=="CPython"', - "mypy_extensions>=0.4.0,<0.5.0", "typing_extensions>=3.10.0.0", 'pywin32;platform_system=="Windows" and platform_python_implementation=="CPython"', 'msgpack~=1.0.0;platform_system!="Windows"', From 2a403b337d299b8e5437c8f7035e7e0888398a9c Mon Sep 17 00:00:00 2001 From: Felix Divo Date: Sat, 5 Jun 2021 22:35:54 +0000 Subject: [PATCH 4/7] Format code with black --- can/io/generic.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/can/io/generic.py b/can/io/generic.py index b8650e80d..dc4b2f782 100644 --- a/can/io/generic.py +++ b/can/io/generic.py @@ -3,7 +3,17 @@ """ from abc import ABCMeta -from typing import Any, Optional, cast, Iterable, Union, TextIO, BinaryIO, Type, ContextManager +from typing import ( + Any, + Optional, + cast, + Iterable, + Union, + TextIO, + BinaryIO, + Type, + ContextManager, +) from typing_extensions import Literal import can From 51ede04edf4322df21d1f93f9e32f59f6f385d95 Mon Sep 17 00:00:00 2001 From: Felix Divo Date: Sun, 6 Jun 2021 10:50:36 +0200 Subject: [PATCH 5/7] fix ContextManager signature in BaseIOHandler --- can/io/generic.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/can/io/generic.py b/can/io/generic.py index dc4b2f782..fbba7a213 100644 --- a/can/io/generic.py +++ b/can/io/generic.py @@ -4,7 +4,6 @@ from abc import ABCMeta from typing import ( - Any, Optional, cast, Iterable, @@ -15,6 +14,7 @@ ContextManager, ) from typing_extensions import Literal +from types import TracebackType import can import can.typechecking @@ -50,7 +50,12 @@ def __init__(self, file: can.typechecking.AcceptedIOType, mode: str = "rt") -> N def __enter__(self) -> "BaseIOHandler": return self - def __exit__(self, exc_type: Type, exc_val: Any, exc_tb: Any) -> Literal[False]: + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> Literal[False]: self.stop() return False From dac06f44c0a8de6d65213c4c8899fbec688bd167 Mon Sep 17 00:00:00 2001 From: Felix Divo Date: Sun, 6 Jun 2021 11:01:14 +0200 Subject: [PATCH 6/7] move type annotation of BaseIOHandler::file to actual annotation and out of the docstring --- can/io/generic.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/can/io/generic.py b/can/io/generic.py index fbba7a213..daead706e 100644 --- a/can/io/generic.py +++ b/can/io/generic.py @@ -1,6 +1,4 @@ -""" -Contains a generic class for file IO. -""" +"""Contains generic base classes for file IO.""" from abc import ABCMeta from typing import ( @@ -25,11 +23,13 @@ class BaseIOHandler(ContextManager, metaclass=ABCMeta): Can be used as a context manager. - :attr Optional[FileLike] file: + :attr file: the file-like object that is kept internally, or `None` if none was opened """ + file: Optional[can.typechecking.FileLike] + def __init__(self, file: can.typechecking.AcceptedIOType, mode: str = "rt") -> None: """ :param file: a path-like object to open a file, a file-like object From dc9a7593ae2b6e2d9d012e0066f922b3cc55aba8 Mon Sep 17 00:00:00 2001 From: Felix Divo Date: Sun, 6 Jun 2021 11:21:16 +0200 Subject: [PATCH 7/7] ignore pylint false positive --- examples/simple_log_converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple_log_converter.py b/examples/simple_log_converter.py index f01546375..e82669f54 100755 --- a/examples/simple_log_converter.py +++ b/examples/simple_log_converter.py @@ -18,7 +18,7 @@ def main(): with can.LogReader(sys.argv[1]) as reader: with can.Logger(sys.argv[2]) as writer: - for msg in reader: + for msg in reader: # pylint: disable=not-an-iterable writer.on_message_received(msg)