Skip to content

Commit b80c6af

Browse files
Merge pull request #78 from source-foundry/static-type-checks
Add type annotations and static type checks
2 parents 087a082 + 9076f6e commit b80c6af

File tree

11 files changed

+148
-96
lines changed

11 files changed

+148
-96
lines changed

.github/workflows/py-typecheck.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Python Type Checks
2+
3+
on: [push]
4+
5+
jobs:
6+
build:
7+
runs-on: ${{ matrix.os }}
8+
strategy:
9+
matrix:
10+
os: [ubuntu-latest]
11+
python-version: [3.8]
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
- name: Set up Python ${{ matrix.python-version }}
16+
uses: actions/setup-python@v2
17+
with:
18+
python-version: ${{ matrix.python-version }}
19+
- name: Install Python testing dependencies
20+
run: pip install --upgrade mypy
21+
- name: Static type checks
22+
run: mypy lib/fdiff

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,7 @@ venv.bak/
109109
.idea
110110

111111
# pytype
112-
.pytype
112+
.pytype
113+
114+
# VSCode
115+
.vscode

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
all: install
22

33
black:
4-
black lib/fdiff/*.py
4+
black -l 90 lib/fdiff/*.py
55

66
clean:
77
- rm dist/*.whl dist/*.tar.gz dist/*.zip
@@ -29,10 +29,10 @@ test-coverage:
2929
# coverage html
3030

3131
test-lint:
32-
flake8 --ignore=E501,W50 lib/fdiff
32+
flake8 --ignore=W50 lib/fdiff
3333

3434
test-type-check:
35-
pytype lib/fdiff
35+
mypy lib/fdiff
3636

3737
test-unit:
3838
tox

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
[![GitHub license](https://img.shields.io/github/license/source-foundry/fdiff?color=blue)](https://github.com/source-foundry/fdiff/blob/master/LICENSE)
88
![Python CI](https://github.com/source-foundry/fdiff/workflows/Python%20CI/badge.svg)
99
![Python Lints](https://github.com/source-foundry/fdiff/workflows/Python%20Lints/badge.svg)
10+
![Python Type Checks](https://github.com/source-foundry/fdiff/workflows/Python%20Type%20Checks/badge.svg)
1011
[![codecov](https://codecov.io/gh/source-foundry/fdiff/branch/master/graph/badge.svg)](https://codecov.io/gh/source-foundry/fdiff)
1112
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/b58954eda44b4fd88ad8f4fa06e8010b)](https://www.codacy.com/app/SourceFoundry/fdiff)
1213

lib/fdiff/__main__.py

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
#!/usr/bin/env python3
22

3+
import argparse
34
import os
45
import sys
5-
import argparse
6+
from typing import Iterable, Iterator, List, Optional, Text, Tuple
67

7-
from fdiff import __version__
8-
from fdiff.color import color_unified_diff_line
9-
from fdiff.diff import external_diff, u_diff
10-
from fdiff.textiter import head, tail
11-
from fdiff.utils import file_exists, get_tables_argument_list
8+
from . import __version__
9+
from .color import color_unified_diff_line
10+
from .diff import external_diff, u_diff
11+
from .textiter import head, tail
12+
from .utils import file_exists, get_tables_argument_list
1213

1314

14-
def main(): # pragma: no cover
15+
def main() -> None: # pragma: no cover
1516
# try/except block rationale:
1617
# handles "premature" socket closure exception that is
1718
# raised by Python when stdout is piped to tools like
@@ -27,13 +28,11 @@ def main(): # pragma: no cover
2728
sys.exit(0)
2829

2930

30-
def run(argv):
31+
def run(argv: List[Text]) -> None:
3132
# ------------------------------------------
3233
# argparse command line argument definitions
3334
# ------------------------------------------
34-
parser = argparse.ArgumentParser(
35-
description="An OpenType table diff tool for fonts."
36-
)
35+
parser = argparse.ArgumentParser(description="An OpenType table diff tool for fonts.")
3736
parser.add_argument("--version", action="version", version=f"fdiff v{__version__}")
3837
parser.add_argument(
3938
"-c",
@@ -66,7 +65,7 @@ def run(argv):
6665
parser.add_argument("PREFILE", help="Font file path/URL 1")
6766
parser.add_argument("POSTFILE", help="Font file path/URL 2")
6867

69-
args = parser.parse_args(argv)
68+
args: argparse.Namespace = parser.parse_args(argv)
7069

7170
# /////////////////////////////////////////////////////////
7271
#
@@ -110,12 +109,12 @@ def run(argv):
110109
# the command line arguments
111110
# set as a Python list if it was defined on the command line
112111
# or as None if it was not set on the command line
113-
include_list = get_tables_argument_list(args.include)
114-
exclude_list = get_tables_argument_list(args.exclude)
112+
include_list: Optional[List[Text]] = get_tables_argument_list(args.include)
113+
exclude_list: Optional[List[Text]] = get_tables_argument_list(args.exclude)
115114

116115
# flip logic of the command line flag for multi process
117116
# optimization use
118-
use_mp = not args.nomp
117+
use_mp: bool = not args.nomp
119118

120119
if args.external:
121120
# ------------------------------
@@ -138,7 +137,7 @@ def run(argv):
138137
sys.exit(1)
139138

140139
try:
141-
diff = external_diff(
140+
ext_diff: Iterable[Tuple[Text, Optional[int]]] = external_diff(
142141
args.external,
143142
args.PREFILE,
144143
args.POSTFILE,
@@ -148,7 +147,7 @@ def run(argv):
148147
)
149148

150149
# write stdout from external tool
151-
for line, exit_code in diff:
150+
for line, exit_code in ext_diff:
152151
# format with color if color flag is entered on command line
153152
if args.color:
154153
sys.stdout.write(color_unified_diff_line(line))
@@ -165,7 +164,7 @@ def run(argv):
165164
# ---------------
166165
# perform the unified diff analysis
167166
try:
168-
diff = u_diff(
167+
uni_diff: Iterator[Text] = u_diff(
169168
args.PREFILE,
170169
args.POSTFILE,
171170
context_lines=args.lines,
@@ -180,11 +179,11 @@ def run(argv):
180179
# re-define the line contents of the diff iterable
181180
# if head or tail is requested
182181
if args.head:
183-
iterable = head(diff, args.head)
182+
iterable = head(uni_diff, args.head)
184183
elif args.tail:
185-
iterable = tail(diff, args.tail)
184+
iterable = tail(uni_diff, args.tail)
186185
else:
187-
iterable = diff
186+
iterable = uni_diff
188187

189188
# print unified diff results to standard output stream
190189
has_diff = False

lib/fdiff/aio.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
#!/usr/bin/env python3
22

3-
import aiofiles
3+
import os
4+
from typing import AnyStr, Text, Union
45

6+
import aiofiles # type: ignore
57

6-
async def async_write_bin(path, binary):
8+
9+
async def async_write_bin(
10+
path: Union[AnyStr, "os.PathLike[Text]"], binary: bytes
11+
) -> None:
712
"""Asynchronous IO writes of binary data `binary` to disk on the file path `path`"""
8-
async with aiofiles.open(path, "wb") as f:
13+
async with aiofiles.open(path, "wb") as f: # type: ignore
914
await f.write(binary)

lib/fdiff/color.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python3
22

3-
ansicolors = {
3+
from typing import Dict, Text
4+
5+
ansicolors: Dict[Text, Text] = {
46
"BLACK": "\033[30m",
57
"RED": "\033[31m",
68
"GREEN": "\033[32m",
@@ -13,13 +15,13 @@
1315
"RESET": "\033[0m",
1416
}
1517

16-
green_start = ansicolors["GREEN"]
17-
red_start = ansicolors["RED"]
18-
cyan_start = ansicolors["CYAN"]
19-
reset = ansicolors["RESET"]
18+
green_start: Text = ansicolors["GREEN"]
19+
red_start: Text = ansicolors["RED"]
20+
cyan_start: Text = ansicolors["CYAN"]
21+
reset: Text = ansicolors["RESET"]
2022

2123

22-
def color_unified_diff_line(line):
24+
def color_unified_diff_line(line: Text) -> Text:
2325
"""Returns an ANSI escape code colored string with color based
2426
on the unified diff line type."""
2527
if line[0:2] == "+ ":

0 commit comments

Comments
 (0)