Skip to content

Commit

Permalink
install mypy + update dev deps + update pre commit + begin type hinti…
Browse files Browse the repository at this point in the history
…ng (#292)

* update all dev dependencies to latest version

* install mypy, update pre commit, fix minimal required type hints

* fix tests

* fix python 3.8

* trailing line breaks

* another 3.8 fix

* run pyupgrade to python 3.8

* trailing empty line

* comment

* move to pyproject
  • Loading branch information
dekim24 authored Aug 1, 2023
1 parent 03e660c commit 9dcd5e4
Show file tree
Hide file tree
Showing 31 changed files with 86 additions and 90 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,6 @@ man/
#vscode
.vscode/
pip-wheel-metadata

#mypy
.mypy_cache
10 changes: 7 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ repos:
# NOTE: it is not recommended to use mutable revs e.g. "stable" - run pre-commit autoupdate instead
# ref: https://github.com/ambv/black/issues/420
- repo: https://github.com/ambv/black
rev: 23.3.0
rev: 23.7.0
hooks:
- id: black
- id: black
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.4.1
hooks:
- id: mypy
2 changes: 1 addition & 1 deletion examples/todo/generate_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def main():

output.extend(["```", ""])

print("Writing output to {}".format(todo_output_filepath))
print(f"Writing output to {todo_output_filepath}")

with open(todo_output_filepath, "w") as f:
f.write("\n".join(output))
Expand Down
2 changes: 1 addition & 1 deletion examples/todo/todo/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __init__(self, **kwargs):
partial_arg = super_kwargs.pop("partial", True)
# Note: if you only want to mark some fields as partial, pass partial= a collection of field names, e.g.,:
# partial_arg = super_kwargs.pop('partial', ('description', ))
super(UpdateTodoSchema, self).__init__(partial=partial_arg, **super_kwargs)
super().__init__(partial=partial_arg, **super_kwargs)


class GetTodoListSchema(RequestSchema):
Expand Down
2 changes: 0 additions & 2 deletions flask_rebar/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from __future__ import unicode_literals

from flask_rebar.utils.request_utils import marshal, response

from flask_rebar.rebar import (
Expand Down
2 changes: 1 addition & 1 deletion flask_rebar/authenticators/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""


class Authenticator(object):
class Authenticator:
"""
Abstract authenticator class. Custom authentication methods should
extend this class.
Expand Down
7 changes: 3 additions & 4 deletions flask_rebar/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
:copyright: Copyright 2018 PlanGrid, Inc., see AUTHORS.
:license: MIT, see LICENSE for details.
"""
from __future__ import unicode_literals


class HttpJsonError(Exception):
Expand All @@ -28,13 +27,13 @@ class HttpJsonError(Exception):
response, not nested under "additional_data".
"""

default_message = None
http_status_code = None
default_message: str
http_status_code: int

def __init__(self, msg=None, additional_data=None):
self.error_message = msg or self.default_message
self.additional_data = additional_data
super(HttpJsonError, self).__init__(self.error_message)
super().__init__(self.error_message)


class BadRequest(HttpJsonError):
Expand Down
4 changes: 2 additions & 2 deletions flask_rebar/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ class ErrorCode:

def required_field_missing(field_name):
return ErrorMessage(
"Required field missing: {}".format(field_name),
f"Required field missing: {field_name}",
ErrorCode.REQUIRED_FIELD_MISSING,
)


def required_field_empty(field_name):
return ErrorMessage(
"Value for required field cannot be None: {}".format(field_name),
f"Value for required field cannot be None: {field_name}",
ErrorCode.REQUIRED_FIELD_EMPTY,
)

Expand Down
17 changes: 5 additions & 12 deletions flask_rebar/rebar.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
:copyright: Copyright 2018 PlanGrid, Inc., see AUTHORS.
:license: MIT, see LICENSE for details.
"""
from __future__ import unicode_literals

import sys
from collections import defaultdict
from collections import namedtuple
from collections.abc import Mapping
from copy import copy
from functools import wraps
from flask import current_app, g, jsonify, request
Expand All @@ -35,12 +34,6 @@
from flask_rebar.swagger_generation import SwaggerV2Generator
from flask_rebar.swagger_ui import create_swagger_ui_blueprint

# Deal with maintaining (for now at least) support for 2.7+:
try:
from collections.abc import Mapping # 3.3+
except ImportError:
from collections import Mapping # 2.7+


MOVED_PERMANENTLY_ERROR = RequestRedirect
PERMANENT_REDIRECT_ERROR = RequestRedirect
Expand Down Expand Up @@ -218,7 +211,7 @@ def prefix_url(prefix, url):
"""
prefix = normalize_prefix(prefix)
url = url[1:] if url.startswith("/") else url
return "/{}/{}".format(prefix, url)
return f"/{prefix}/{url}"


# Metadata about a declared handler function. This can be used to both
Expand Down Expand Up @@ -252,15 +245,15 @@ class PathDefinition(
)
)
def __new__(cls, *args, **kwargs):
return super(PathDefinition, cls).__new__(cls, *args, **kwargs)
return super().__new__(cls, *args, **kwargs)

@property
@deprecated("authenticator", "3.0")
def authenticator(self):
return self.authenticators[0] if self.authenticators else None


class HandlerRegistry(object):
class HandlerRegistry:
"""
Registry for request handlers.
Expand Down Expand Up @@ -635,7 +628,7 @@ def _register_swagger_ui(self, app):
)


class Rebar(object):
class Rebar:
"""
The main entry point for the Flask-Rebar extension.
Expand Down
7 changes: 4 additions & 3 deletions flask_rebar/swagger_generation/authenticator_to_swagger.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collections import namedtuple
from typing import Type

from flask_rebar.authenticators import HeaderApiKeyAuthenticator, Authenticator
from .marshmallow_to_swagger import ConverterRegistry
Expand All @@ -14,7 +15,7 @@
)


class AuthenticatorConverter(object):
class AuthenticatorConverter:
"""
Abstract class for objects that convert Authenticator objects to
security JSONSchema.
Expand All @@ -35,7 +36,7 @@ class AuthenticatorConverter(object):
"""

AUTHENTICATOR_TYPE = None
AUTHENTICATOR_TYPE: Type[Authenticator]

def get_security_schemes(self, obj, context):
"""
Expand Down Expand Up @@ -152,7 +153,7 @@ def register_types(self, converters):
:param iterable[AuthenticatorConverter] converters:
"""
super(AuthenticatorConverterRegistry, self).register_types(converters)
super().register_types(converters)

def get_security_schemes(self, authenticator, openapi_version=2):
"""
Expand Down
7 changes: 3 additions & 4 deletions flask_rebar/swagger_generation/generator_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,12 @@ def get_unique_schema_definitions(


def get_unique_authenticators(registry):
authenticators = set(
authenticators = {
authenticator
for d in iterate_path_definitions(paths=registry.paths)
for authenticator in d.authenticators
if authenticator is not None and authenticator is not USE_DEFAULT
)
}

for authenticator in registry.default_authenticators:
if authenticator is not None:
Expand All @@ -264,8 +264,7 @@ def iterate_path_definitions(paths):
:return Iterator[PathDefinition]
"""
for methods in paths.values():
for definition in methods.values():
yield definition
yield from methods.values()


def recursively_convert_dict_to_ordered_dict(obj):
Expand Down
23 changes: 11 additions & 12 deletions flask_rebar/swagger_generation/marshmallow_to_swagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
:copyright: Copyright 2018 PlanGrid, Inc., see AUTHORS.
:license: MIT, see LICENSE for details.
"""
from __future__ import unicode_literals

import copy
import inspect
import logging
import sys
from collections import namedtuple
from typing import Any, Optional, Type, Union

import marshmallow as m
from marshmallow.validate import Range
Expand All @@ -29,16 +28,16 @@

LoadDumpOptions = None
try:
EnumField = m.fields.Enum
EnumField: Optional[Type[m.fields.Field]] = m.fields.Enum
except AttributeError:
try:
from marshmallow_enum import EnumField, LoadDumpOptions
from marshmallow_enum import EnumField, LoadDumpOptions # type: ignore
except ImportError:
EnumField = None


# Special value to signify that a JSONSchema field should be left unset
class UNSET(object):
class UNSET:
pass


Expand Down Expand Up @@ -142,13 +141,13 @@ def get_schema_fields(schema):
return sorted(fields)


class MarshmallowConverter(object):
class MarshmallowConverter:
"""
Abstract class for objects that convert Marshmallow objects to
JSONSchema dictionaries.
"""

MARSHMALLOW_TYPE = None
MARSHMALLOW_TYPE: Any = None

def convert(self, obj, context):
"""
Expand Down Expand Up @@ -264,10 +263,10 @@ class FieldConverter(MarshmallowConverter):
This should be extended for specific Field types.
"""

MARSHMALLOW_TYPE = m.fields.Field
MARSHMALLOW_TYPE: Type[m.fields.Field] = m.fields.Field

def convert(self, obj, context):
jsonschema_obj = super(FieldConverter, self).convert(obj, context)
jsonschema_obj = super().convert(obj, context)

if obj.dump_only:
jsonschema_obj["readOnly"] = True
Expand Down Expand Up @@ -339,7 +338,7 @@ class ValidatorConverter(MarshmallowConverter):
This should be extended for specific Validator types.
"""

MARSHMALLOW_TYPE = Validator
MARSHMALLOW_TYPE: Union[Type[Validator], Type[OneOf]] = Validator


class NestedConverter(FieldConverter):
Expand Down Expand Up @@ -561,7 +560,7 @@ def get_maximum_length(self, obj, context):
return UNSET


class ConverterRegistry(object):
class ConverterRegistry:
"""
Registry for MarshmallowConverters.
Expand Down Expand Up @@ -650,7 +649,7 @@ def convert(self, obj, openapi_version=2):


class EnumConverter(FieldConverter):
MARSHMALLOW_TYPE = EnumField
MARSHMALLOW_TYPE = EnumField # type: ignore

@sets_swagger_attr(sw.type_)
def get_type(self, obj, context):
Expand Down
2 changes: 1 addition & 1 deletion flask_rebar/swagger_generation/swagger_generator_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class SwaggerGenerator(SwaggerGeneratorI):
:param marshmallow.Schema default_response_schema: Schema to use as the default of all responses
"""

_open_api_version = None
_open_api_version: str

def __init__(
self,
Expand Down
4 changes: 1 addition & 3 deletions flask_rebar/swagger_generation/swagger_generator_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
:copyright: Copyright 2019 PlanGrid, Inc., see AUTHORS.
:license: MIT, see LICENSE for details.
"""
from __future__ import unicode_literals

import copy

from flask_rebar.swagger_generation import swagger_words as sw
Expand Down Expand Up @@ -77,7 +75,7 @@ def __init__(
default_response_schema=Error(),
authenticator_converter_registry=None,
):
super(SwaggerV2Generator, self).__init__(
super().__init__(
openapi_major_version=2,
version=version,
title=title,
Expand Down
4 changes: 1 addition & 3 deletions flask_rebar/swagger_generation/swagger_generator_v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
:copyright: Copyright 2019 PlanGrid, Inc., see AUTHORS.
:license: MIT, see LICENSE for details.
"""
from __future__ import unicode_literals

from flask_rebar.utils.defaults import USE_DEFAULT
from flask_rebar.swagger_generation import swagger_words as sw
from flask_rebar.swagger_generation.swagger_generator import SwaggerGenerator
Expand Down Expand Up @@ -66,7 +64,7 @@ def __init__(
authenticator_converter_registry=None,
include_hidden=False,
):
super(SwaggerV3Generator, self).__init__(
super().__init__(
openapi_major_version=3,
version=version,
title=title,
Expand Down
8 changes: 4 additions & 4 deletions flask_rebar/swagger_generation/swagger_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from flask_rebar.swagger_generation import swagger_words as sw


class ExternalDocumentation(object):
class ExternalDocumentation:
"""Represents a Swagger "External Documentation Object"
:param str url: The URL for the target documentation. Value MUST be in the format of a URL
Expand All @@ -35,7 +35,7 @@ def as_swagger(self):
return doc


class Tag(object):
class Tag:
"""Represents a Swagger "Tag Object"
:param str name: The name of the tag
Expand All @@ -61,7 +61,7 @@ def as_swagger(self):
return doc


class ServerVariable(object):
class ServerVariable:
"""Represents a Swagger "Server Variable Object"
:param str default:
Expand All @@ -87,7 +87,7 @@ def as_swagger(self):
return doc


class Server(object):
class Server:
"""Represents a Swagger "Server Object"
:param str url:
Expand Down
Loading

0 comments on commit 9dcd5e4

Please sign in to comment.