Skip to content

Commit 697e14f

Browse files
authored
add mypy type hints to all non-test code + update mypy config (#300)
* begin adding type hints * fixes * more hints * 1 * 1 * 1 * type hint marshmallow converters * 1 * revert * change import to hopefully make compatible with older python * more fixes for old python * fix for old marshmallow * generator v2 * v3 generator * swagger objects * more typing * add a few missing hints * add typed * minor fixes * update type + rerun black * more type hints * finish adding type hints * fix tests * address comments * fix * minor fix * fix typo
1 parent d4ebdb0 commit 697e14f

27 files changed

+961
-497
lines changed

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repos:
1010
hooks:
1111
- id: flake8
1212
- repo: https://github.com/pre-commit/mirrors-mypy
13-
rev: v1.4.1
13+
rev: v1.8.0
1414
hooks:
1515
- id: mypy
1616
- repo: https://github.com/Lucas-C/pre-commit-hooks-markup

flask_rebar/__init__.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
from flask_rebar.validation import ResponseSchema, RequestSchema
1414

15-
from flask_rebar.swagger_generation import (
15+
from flask_rebar.swagger_generation.swagger_generator_v2 import SwaggerV2Generator
16+
from flask_rebar.swagger_generation.swagger_generator_v3 import SwaggerV3Generator
17+
from flask_rebar.swagger_generation.swagger_objects import (
1618
ExternalDocumentation,
17-
SwaggerV2Generator,
18-
SwaggerV3Generator,
1919
Tag,
2020
Server,
2121
ServerVariable,

flask_rebar/authenticators/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Authenticator:
1515
extend this class.
1616
"""
1717

18-
def authenticate(self):
18+
def authenticate(self) -> None:
1919
"""
2020
Implementations of :class:`Authenticator` should override this method.
2121

flask_rebar/authenticators/header_api_key.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@
77
:copyright: Copyright 2018 PlanGrid, Inc., see AUTHORS.
88
:license: MIT, see LICENSE for details.
99
"""
10+
from typing import Dict
11+
1012
from flask import request, g
1113
from hmac import compare_digest
1214

1315
from flask_rebar import errors, messages
1416
from flask_rebar.authenticators.base import Authenticator
1517

1618

17-
def get_authenticated_app_name():
19+
def get_authenticated_app_name() -> str:
1820
return g.authenticated_app_name
1921

2022

@@ -39,16 +41,16 @@ class HeaderApiKeyAuthenticator(Authenticator):
3941
# This is the default name, if someone doesn't need about this feature.
4042
DEFAULT_APP_NAME = "default"
4143

42-
def __init__(self, header, name="sharedSecret"):
44+
def __init__(self, header: str, name: str = "sharedSecret") -> None:
4345
self.header = header
44-
self.keys = {}
46+
self.keys: Dict[str, str] = {}
4547
self.name = name
4648

4749
@property
48-
def authenticated_app_name(self):
50+
def authenticated_app_name(self) -> str:
4951
return get_authenticated_app_name()
5052

51-
def register_key(self, key, app_name=DEFAULT_APP_NAME):
53+
def register_key(self, key: str, app_name: str = DEFAULT_APP_NAME) -> None:
5254
"""
5355
Register a client application's shared secret.
5456
@@ -60,7 +62,7 @@ def register_key(self, key, app_name=DEFAULT_APP_NAME):
6062
"""
6163
self.keys[key] = app_name
6264

63-
def authenticate(self):
65+
def authenticate(self) -> None:
6466
if self.header not in request.headers:
6567
raise errors.Unauthorized(messages.missing_auth_token)
6668

flask_rebar/compat.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
1+
from typing import Any
2+
from typing import Dict
3+
14
import marshmallow
5+
from marshmallow.fields import Field
6+
from marshmallow.schema import Schema
27

38
from flask import current_app
49
from flask_rebar.validation import filter_dump_only, RequireOnDumpMixin
510

611

7-
def set_data_key(field, key):
12+
def set_data_key(field: Field, key: str) -> Field:
813
field.data_key = key
914
return field
1015

1116

12-
def get_data_key(field):
17+
def get_data_key(field: Field) -> str:
1318
if field.data_key:
1419
return field.data_key
20+
if field.name is None:
21+
raise ValueError("Field name cannot be None")
1522
return field.name
1623

1724

18-
def load(schema, data):
25+
def load(schema: Schema, data: Dict[str, Any]) -> Dict[str, Any]:
1926
return schema.load(data)
2027

2128

22-
def dump(schema, data):
29+
def dump(schema: Schema, data: Dict[str, Any]) -> Dict[str, Any]:
2330
"""
2431
Our wrapper for Schema.dump that includes optional validation.
2532
Note that as of Flask-Rebar 2.x (hence Marshmallow 3.x), Marshmallow's default behavior is to NOT validate on dump
@@ -54,6 +61,6 @@ def dump(schema, data):
5461
return result
5562

5663

57-
def exclude_unknown_fields(schema):
64+
def exclude_unknown_fields(schema: Schema) -> Schema:
5865
schema.unknown = marshmallow.EXCLUDE
5966
return schema

flask_rebar/errors.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
:copyright: Copyright 2018 PlanGrid, Inc., see AUTHORS.
88
:license: MIT, see LICENSE for details.
99
"""
10+
from flask_rebar.messages import ErrorMessage
11+
from typing import Any, Dict, Optional, Union
1012

1113

1214
class HttpJsonError(Exception):
@@ -30,7 +32,11 @@ class HttpJsonError(Exception):
3032
default_message: str
3133
http_status_code: int
3234

33-
def __init__(self, msg=None, additional_data=None):
35+
def __init__(
36+
self,
37+
msg: Optional[Union[str, ErrorMessage]] = None,
38+
additional_data: Optional[Dict[str, Any]] = None,
39+
) -> None:
3440
self.error_message = msg or self.default_message
3541
self.additional_data = additional_data
3642
super().__init__(self.error_message)

flask_rebar/messages.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,21 @@ class ErrorCode:
6565
)
6666

6767

68-
def required_field_missing(field_name):
68+
def required_field_missing(field_name: str) -> ErrorMessage:
6969
return ErrorMessage(
7070
f"Required field missing: {field_name}",
7171
ErrorCode.REQUIRED_FIELD_MISSING,
7272
)
7373

7474

75-
def required_field_empty(field_name):
75+
def required_field_empty(field_name: str) -> ErrorMessage:
7676
return ErrorMessage(
7777
f"Value for required field cannot be None: {field_name}",
7878
ErrorCode.REQUIRED_FIELD_EMPTY,
7979
)
8080

8181

82-
def unsupported_fields(field_names):
82+
def unsupported_fields(field_names: str) -> ErrorMessage:
8383
return ErrorMessage(
8484
"Unexpected field: {}".format(",".join(field_names)),
8585
ErrorCode.UNSUPPORTED_FIELDS,

flask_rebar/py.typed

Whitespace-only changes.

0 commit comments

Comments
 (0)