Skip to content

Commit 79451f5

Browse files
authored
Merge pull request #51 from p1c2u/feature/mypy-static-type-check
Mypy static type check
2 parents a9cf988 + 22b12e7 commit 79451f5

File tree

13 files changed

+796
-716
lines changed

13 files changed

+796
-716
lines changed

.github/workflows/python-test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,8 @@ jobs:
5555
PYTEST_ADDOPTS: "--color=yes"
5656
run: poetry run pytest
5757

58+
- name: Static type check
59+
run: poetry run mypy
60+
5861
- name: Upload coverage
5962
uses: codecov/codecov-action@v1

.pre-commit-config.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
default_stages: [commit, push]
3+
default_language_version:
4+
# force all unspecified python hooks to run python3
5+
python: python3
6+
minimum_pre_commit_version: "1.20.0"
7+
repos:
8+
- repo: meta
9+
hooks:
10+
- id: check-hooks-apply
11+
12+
- repo: https://github.com/asottile/pyupgrade
13+
rev: v2.19.0
14+
hooks:
15+
- id: pyupgrade
16+
args: ["--py36-plus"]
17+
18+
- repo: local
19+
hooks:
20+
- id: flynt
21+
name: Convert to f-strings with flynt
22+
entry: flynt
23+
language: python
24+
additional_dependencies: ['flynt==0.76']
25+
26+
- id: black
27+
name: black
28+
entry: black
29+
language: system
30+
require_serial: true
31+
types: [python]
32+
33+
- id: isort
34+
name: isort
35+
entry: isort
36+
args: ['--filter-files']
37+
language: system
38+
require_serial: true
39+
types: [python]

openapi_schema_validator/__init__.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
# -*- coding: utf-8 -*-
2-
from openapi_schema_validator._format import oas30_format_checker, \
3-
oas31_format_checker
1+
from openapi_schema_validator._format import oas30_format_checker
2+
from openapi_schema_validator._format import oas31_format_checker
43
from openapi_schema_validator.shortcuts import validate
5-
from openapi_schema_validator.validators import OAS30Validator, OAS31Validator
4+
from openapi_schema_validator.validators import OAS30Validator
5+
from openapi_schema_validator.validators import OAS31Validator
66

7-
__author__ = 'Artur Maciag'
8-
__email__ = '[email protected]'
9-
__version__ = '0.3.2'
10-
__url__ = 'https://github.com/p1c2u/openapi-schema-validator'
11-
__license__ = '3-clause BSD License'
7+
__author__ = "Artur Maciag"
8+
__email__ = "[email protected]"
9+
__version__ = "0.3.2"
10+
__url__ = "https://github.com/p1c2u/openapi-schema-validator"
11+
__license__ = "3-clause BSD License"
1212

1313
__all__ = [
14-
'validate',
15-
'OAS30Validator',
16-
'oas30_format_checker',
17-
'OAS31Validator',
18-
'oas31_format_checker',
14+
"validate",
15+
"OAS30Validator",
16+
"oas30_format_checker",
17+
"OAS31Validator",
18+
"oas31_format_checker",
1919
]

openapi_schema_validator/_format.py

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
from base64 import b64encode, b64decode
21
import binascii
2+
from base64 import b64decode
3+
from base64 import b64encode
34
from datetime import datetime
5+
from typing import Any
6+
from typing import Tuple
7+
from typing import Union
48
from uuid import UUID
59

610
from jsonschema._format import FormatChecker
@@ -9,7 +13,7 @@
913
DATETIME_HAS_RFC3339_VALIDATOR = False
1014
DATETIME_HAS_STRICT_RFC3339 = False
1115
DATETIME_HAS_ISODATE = False
12-
DATETIME_RAISES = ()
16+
DATETIME_RAISES: Tuple[Exception, ...] = ()
1317

1418
try:
1519
import isodate
@@ -36,65 +40,67 @@
3640
DATETIME_RAISES += (ValueError, TypeError)
3741

3842

39-
def is_int32(instance):
43+
def is_int32(instance: Any) -> bool:
4044
return isinstance(instance, int)
4145

4246

43-
def is_int64(instance):
47+
def is_int64(instance: Any) -> bool:
4448
return isinstance(instance, int)
4549

4650

47-
def is_float(instance):
51+
def is_float(instance: Any) -> bool:
4852
return isinstance(instance, float)
4953

5054

51-
def is_double(instance):
55+
def is_double(instance: Any) -> bool:
5256
# float has double precision in Python
5357
# It's double in CPython and Jython
5458
return isinstance(instance, float)
5559

5660

57-
def is_binary(instance):
61+
def is_binary(instance: Any) -> bool:
5862
return isinstance(instance, bytes)
5963

6064

61-
def is_byte(instance):
65+
def is_byte(instance: Union[str, bytes]) -> bool:
6266
if isinstance(instance, str):
6367
instance = instance.encode()
6468

6569
try:
66-
return b64encode(b64decode(instance)) == instance
70+
encoded = b64encode(b64decode(instance))
6771
except TypeError:
6872
return False
73+
else:
74+
return encoded == instance
6975

7076

71-
def is_datetime(instance):
77+
def is_datetime(instance: str) -> bool:
7278
if not isinstance(instance, (bytes, str)):
7379
return False
7480

7581
if DATETIME_HAS_RFC3339_VALIDATOR:
76-
return validate_rfc3339(instance)
82+
return bool(validate_rfc3339(instance))
7783

7884
if DATETIME_HAS_STRICT_RFC3339:
79-
return strict_rfc3339.validate_rfc3339(instance)
85+
return bool(strict_rfc3339.validate_rfc3339(instance))
8086

8187
if DATETIME_HAS_ISODATE:
82-
return isodate.parse_datetime(instance)
88+
return bool(isodate.parse_datetime(instance))
8389

8490
return True
8591

8692

87-
def is_date(instance):
93+
def is_date(instance: Any) -> bool:
8894
if not isinstance(instance, (bytes, str)):
8995
return False
9096

9197
if isinstance(instance, bytes):
9298
instance = instance.decode()
9399

94-
return datetime.strptime(instance, "%Y-%m-%d")
100+
return bool(datetime.strptime(instance, "%Y-%m-%d"))
95101

96102

97-
def is_uuid(instance):
103+
def is_uuid(instance: Any) -> bool:
98104
if not isinstance(instance, (bytes, str)):
99105
return False
100106

@@ -104,41 +110,43 @@ def is_uuid(instance):
104110
return str(UUID(instance)).lower() == instance.lower()
105111

106112

107-
def is_password(instance):
113+
def is_password(instance: Any) -> bool:
108114
return True
109115

110116

111-
class OASFormatChecker(FormatChecker):
117+
class OASFormatChecker(FormatChecker): # type: ignore
112118

113119
checkers = {
114-
'int32': (is_int32, ()),
115-
'int64': (is_int64, ()),
116-
'float': (is_float, ()),
117-
'double': (is_double, ()),
118-
'byte': (is_byte, (binascii.Error, TypeError)),
119-
'binary': (is_binary, ()),
120-
'date': (is_date, (ValueError, )),
121-
'date-time': (is_datetime, DATETIME_RAISES),
122-
'password': (is_password, ()),
120+
"int32": (is_int32, ()),
121+
"int64": (is_int64, ()),
122+
"float": (is_float, ()),
123+
"double": (is_double, ()),
124+
"byte": (is_byte, (binascii.Error, TypeError)),
125+
"binary": (is_binary, ()),
126+
"date": (is_date, (ValueError,)),
127+
"date-time": (is_datetime, DATETIME_RAISES),
128+
"password": (is_password, ()),
123129
# non standard
124-
'uuid': (is_uuid, (AttributeError, ValueError)),
130+
"uuid": (is_uuid, (AttributeError, ValueError)),
125131
}
126132

127-
def check(self, instance, format):
133+
def check(self, instance: Any, format: str) -> Any:
128134
if format not in self.checkers:
129135
raise FormatError(
130-
"Format checker for %r format not found" % (format, ))
136+
f"Format checker for {format!r} format not found"
137+
)
131138

132139
func, raises = self.checkers[format]
133140
result, cause = None, None
134141
try:
135142
result = func(instance)
136-
except raises as e:
143+
except raises as e: # type: ignore
137144
cause = e
138145

139146
if not result:
140147
raise FormatError(
141-
"%r is not a %r" % (instance, format), cause=cause,
148+
f"{instance!r} is not a {format!r}",
149+
cause=cause,
142150
)
143151
return result
144152

openapi_schema_validator/_types.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
1-
from jsonschema._types import (
2-
TypeChecker, is_array, is_bool, is_integer,
3-
is_object, is_number, draft202012_type_checker,
4-
)
1+
from typing import Any
2+
3+
from jsonschema._types import TypeChecker
4+
from jsonschema._types import draft202012_type_checker
5+
from jsonschema._types import is_array
6+
from jsonschema._types import is_bool
7+
from jsonschema._types import is_integer
8+
from jsonschema._types import is_number
9+
from jsonschema._types import is_object
510

611

7-
def is_string(checker, instance):
12+
def is_string(checker: TypeChecker, instance: Any) -> bool:
813
return isinstance(instance, (str, bytes))
914

1015

1116
oas30_type_checker = TypeChecker(
1217
{
13-
u"string": is_string,
14-
u"number": is_number,
15-
u"integer": is_integer,
16-
u"boolean": is_bool,
17-
u"array": is_array,
18-
u"object": is_object,
18+
"string": is_string,
19+
"number": is_number,
20+
"integer": is_integer,
21+
"boolean": is_bool,
22+
"array": is_array,
23+
"object": is_object,
1924
},
2025
)
2126
oas31_type_checker = draft202012_type_checker

0 commit comments

Comments
 (0)