Skip to content

Commit 4119a57

Browse files
authored
Merge pull request #1226 from muggenhor/testing
ci: check types with mypy
2 parents 9f12c8c + 043e15f commit 4119a57

File tree

11 files changed

+60
-13
lines changed

11 files changed

+60
-13
lines changed

.github/workflows/pythonpackage.yml

+5
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ jobs:
4747
pip install flake8
4848
# stop the build if there are Python syntax errors or undefined names
4949
flake8 --ignore=W293,E265,E266,W503,W504,E731 --count --show-source --statistics
50+
- name: Check types with mypy
51+
run: |
52+
set -x
53+
pip install tox
54+
tox -e type
5055
- name: Test with nose
5156
run: |
5257
set -x

MANIFEST.in

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
include VERSION
2-
include LICENSE
3-
include CHANGES
41
include AUTHORS
2+
include CHANGES
53
include CONTRIBUTING.md
4+
include LICENSE
65
include README.md
6+
include VERSION
77
include requirements.txt
8+
include test-requirements.txt
89

910
recursive-include doc *
1011
recursive-exclude test *

git/cmd.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def dict_to_slots_and__excluded_are_none(self, d, excluded=()):
138138

139139
## CREATE_NEW_PROCESS_GROUP is needed to allow killing it afterwards,
140140
# see https://docs.python.org/3/library/subprocess.html#subprocess.Popen.send_signal
141-
PROC_CREATIONFLAGS = (CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP
141+
PROC_CREATIONFLAGS = (CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore[attr-defined]
142142
if is_win else 0)
143143

144144

git/compat.py

+28-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,16 @@
1818

1919
# typing --------------------------------------------------------------------
2020

21-
from typing import IO, Any, AnyStr, Dict, Optional, Type, Union
21+
from typing import (
22+
Any,
23+
AnyStr,
24+
Dict,
25+
IO,
26+
Optional,
27+
Type,
28+
Union,
29+
overload,
30+
)
2231
from git.types import TBD
2332

2433
# ---------------------------------------------------------------------------
@@ -30,6 +39,12 @@
3039
defenc = sys.getfilesystemencoding()
3140

3241

42+
@overload
43+
def safe_decode(s: None) -> None: ...
44+
45+
@overload
46+
def safe_decode(s: Union[IO[str], AnyStr]) -> str: ...
47+
3348
def safe_decode(s: Union[IO[str], AnyStr, None]) -> Optional[str]:
3449
"""Safely decodes a binary string to unicode"""
3550
if isinstance(s, str):
@@ -42,6 +57,12 @@ def safe_decode(s: Union[IO[str], AnyStr, None]) -> Optional[str]:
4257
raise TypeError('Expected bytes or text, but got %r' % (s,))
4358

4459

60+
@overload
61+
def safe_encode(s: None) -> None: ...
62+
63+
@overload
64+
def safe_encode(s: AnyStr) -> bytes: ...
65+
4566
def safe_encode(s: Optional[AnyStr]) -> Optional[bytes]:
4667
"""Safely encodes a binary string to unicode"""
4768
if isinstance(s, str):
@@ -54,6 +75,12 @@ def safe_encode(s: Optional[AnyStr]) -> Optional[bytes]:
5475
raise TypeError('Expected bytes or text, but got %r' % (s,))
5576

5677

78+
@overload
79+
def win_encode(s: None) -> None: ...
80+
81+
@overload
82+
def win_encode(s: AnyStr) -> bytes: ...
83+
5784
def win_encode(s: Optional[AnyStr]) -> Optional[bytes]:
5885
"""Encode unicodes for process arguments on Windows."""
5986
if isinstance(s, str):
@@ -65,7 +92,6 @@ def win_encode(s: Optional[AnyStr]) -> Optional[bytes]:
6592
return None
6693

6794

68-
6995
def with_metaclass(meta: Type[Any], *bases: Any) -> 'metaclass': # type: ignore ## mypy cannot understand dynamic class creation
7096
"""copied from https://github.com/Byron/bcore/blob/master/src/python/butility/future.py#L15"""
7197

git/config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def get_config_path(config_level: Literal['system', 'global', 'user', 'repositor
216216
raise ValueError("Invalid configuration level: %r" % config_level)
217217

218218

219-
class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser, object)):
219+
class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser, object)): # type: ignore ## mypy does not understand dynamic class creation # noqa: E501
220220

221221
"""Implements specifics required to read git style configuration files.
222222

git/exc.py

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
66
""" Module containing all exceptions thrown throughout the git package, """
77

8+
from gitdb.exc import BadName # NOQA @UnusedWildImport skipcq: PYL-W0401, PYL-W0614
89
from gitdb.exc import * # NOQA @UnusedWildImport skipcq: PYL-W0401, PYL-W0614
910
from git.compat import safe_decode
1011

git/objects/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
from .tree import *
1717
# Fix import dependency - add IndexObject to the util module, so that it can be
1818
# imported by the submodule.base
19-
smutil.IndexObject = IndexObject
20-
smutil.Object = Object
19+
smutil.IndexObject = IndexObject # type: ignore[attr-defined]
20+
smutil.Object = Object # type: ignore[attr-defined]
2121
del(smutil)
2222

2323
# must come after submodule was made available

git/objects/base.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import gitdb.typ as dbtyp
99
import os.path as osp
10+
from typing import Optional # noqa: F401 unused import
1011

1112
from .util import get_object_type_by_name
1213

@@ -24,7 +25,7 @@ class Object(LazyMixin):
2425

2526
TYPES = (dbtyp.str_blob_type, dbtyp.str_tree_type, dbtyp.str_commit_type, dbtyp.str_tag_type)
2627
__slots__ = ("repo", "binsha", "size")
27-
type = None # to be set by subclass
28+
type = None # type: Optional[str] # to be set by subclass
2829

2930
def __init__(self, repo, binsha):
3031
"""Initialize an object by identifying it by its binary sha.

git/refs/reference.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def iter_items(cls, repo, common_path=None):
103103

104104
#{ Remote Interface
105105

106-
@property
106+
@property # type: ignore ## mypy cannot deal with properties with an extra decorator (2021-04-21)
107107
@require_remote_ref_path
108108
def remote_name(self):
109109
"""
@@ -114,7 +114,7 @@ def remote_name(self):
114114
# /refs/remotes/<remote name>/<branch_name>
115115
return tokens[2]
116116

117-
@property
117+
@property # type: ignore ## mypy cannot deal with properties with an extra decorator (2021-04-21)
118118
@require_remote_ref_path
119119
def remote_head(self):
120120
""":return: Name of the remote head itself, i.e. master.

mypy.ini

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11

22
[mypy]
33

4-
disallow_untyped_defs = True
4+
# TODO: enable when we've fully annotated everything
5+
#disallow_untyped_defs = True
6+
7+
# TODO: remove when 'gitdb' is fully annotated
8+
[mypy-gitdb.*]
9+
ignore_missing_imports = True

tox.ini

+8
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ commands = coverage run --omit="git/test/*" -m unittest --buffer {posargs}
1414
[testenv:flake8]
1515
commands = flake8 --ignore=W293,E265,E266,W503,W504,E731 {posargs}
1616

17+
[testenv:type]
18+
description = type check ourselves
19+
deps =
20+
{[testenv]deps}
21+
mypy
22+
commands =
23+
mypy -p git
24+
1725
[testenv:venv]
1826
commands = {posargs}
1927

0 commit comments

Comments
 (0)