Skip to content

Commit cd3f81b

Browse files
committed
add typing to the generic IO module
1 parent e6f3453 commit cd3f81b

3 files changed

Lines changed: 18 additions & 6 deletions

File tree

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ jobs:
9999
can/notifier.py
100100
can/player.py
101101
can/thread_safe_bus.py
102+
can/typechecking.py
102103
can/util.py
104+
can/io/generic.py
103105
- stage: linter
104106
name: "Formatting Checks"
105107
python: "3.7"

can/io/generic.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,34 @@
55
"""
66

77
from abc import ABCMeta
8+
from typing import Optional, Union, cast
9+
10+
from can.typechecking import FileLike, PathLike
811

912

1013
class BaseIOHandler(metaclass=ABCMeta):
1114
"""A generic file handler that can be used for reading and writing.
1215
1316
Can be used as a context manager.
1417
15-
:attr file-like file:
18+
:attr Optional[FileLike] file:
1619
the file-like object that is kept internally, or None if none
1720
was opened
1821
"""
1922

20-
def __init__(self, file, mode="rt"):
23+
def __init__(self, file: Optional[Union[FileLike, PathLike]], mode: str = "rt"):
2124
"""
2225
:param file: a path-like object to open a file, a file-like object
2326
to be used as a file or `None` to not use a file at all
24-
:param str mode: the mode that should be used to open the file, see
25-
:func:`open`, ignored if *file* is `None`
27+
:param mode: the mode that should be used to open the file, see
28+
:func:`open`, ignored if *file* is `None`
2629
"""
2730
if file is None or (hasattr(file, "read") and hasattr(file, "write")):
2831
# file is None or some file-like object
29-
self.file = file
32+
self.file = cast(Optional[FileLike], file)
3033
else:
3134
# file is some path-like object
32-
self.file = open(file, mode)
35+
self.file = open(cast(PathLike, file), mode)
3336

3437
# for multiple inheritance
3538
super().__init__()
@@ -41,6 +44,7 @@ def __exit__(self, *args):
4144
self.stop()
4245

4346
def stop(self):
47+
"""Closes the undelying file-like object and flushes it, if it was opened in write mode."""
4448
if self.file is not None:
4549
# this also implies a flush()
4650
self.file.close()

can/typechecking.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Types for mypy type-checking
22
"""
3+
4+
import os
35
import typing
46

57
import mypy_extensions
@@ -18,3 +20,7 @@
1820

1921
# Used for the Abstract Base Class
2022
Channel = typing.Union[int, str]
23+
24+
# Used by the IO module
25+
FileLike = typing.IO[typing.Any]
26+
PathLike = typing.Union[str, bytes, os.PathLike]

0 commit comments

Comments
 (0)