Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve type hints nullable parameters #1972

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ ci:
autoupdate_branch: "main"
autoupdate_schedule: monthly
repos:
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
- repo: https://github.com/pycqa/flake8
rev: 7.1.1
hooks:
- id: flake8
files: "^connexion/"
Expand Down
8 changes: 6 additions & 2 deletions connexion/apps/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,11 @@ def add_api(
)

def add_url_rule(
self, rule, endpoint: str = None, view_func: t.Callable = None, **options
self,
rule,
endpoint: t.Optional[str] = None,
view_func: t.Optional[t.Callable] = None,
**options,
):
"""
Connects a URL rule. Works exactly like the `route` decorator.
Expand Down Expand Up @@ -271,7 +275,7 @@ def test_client(self, **kwargs):
passed to the ``StarletteClient``."""
return TestClient(self, **kwargs)

def run(self, import_string: str = None, **kwargs):
def run(self, import_string: t.Optional[str] = None, **kwargs):
"""Run the application using uvicorn.

:param import_string: application as import string (eg. "main:app"). This is needed to run
Expand Down
12 changes: 8 additions & 4 deletions connexion/apps/asynchronous.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def __init__(self) -> None:
self.router = Router()
super().__init__(self.router)

def add_api(self, *args, name: str = None, **kwargs):
def add_api(self, *args, name: t.Optional[str] = None, **kwargs):
api = super().add_api(*args, **kwargs)

if name is not None:
Expand All @@ -112,8 +112,8 @@ def add_api(self, *args, name: str = None, **kwargs):
def add_url_rule(
self,
rule,
endpoint: str = None,
view_func: t.Callable = None,
endpoint: t.Optional[str] = None,
view_func: t.Optional[t.Callable] = None,
methods: t.List[str] = None,
**options,
):
Expand Down Expand Up @@ -200,7 +200,11 @@ def __init__(
)

def add_url_rule(
self, rule, endpoint: str = None, view_func: t.Callable = None, **options
self,
rule,
endpoint: t.Optional[str] = None,
view_func: t.Optional[t.Callable] = None,
**options,
):
self._middleware_app.add_url_rule(
rule, endpoint=endpoint, view_func=view_func, **options
Expand Down
26 changes: 21 additions & 5 deletions connexion/apps/flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,20 @@ def _framework_path_and_name(
return flask_path, endpoint_name

def _add_operation_internal(
self, method: str, path: str, operation: t.Callable, name: str = None
self,
method: str,
path: str,
operation: t.Callable,
name: t.Optional[str] = None,
) -> None:
self.blueprint.add_url_rule(path, name, operation, methods=[method])

def add_url_rule(
self, rule, endpoint: str = None, view_func: t.Callable = None, **options
self,
rule,
endpoint: t.Optional[str] = None,
view_func: t.Optional[t.Callable] = None,
**options,
):
return self.blueprint.add_url_rule(rule, endpoint, view_func, **options)

Expand All @@ -132,7 +140,7 @@ def __init__(self, import_name, server_args: dict, **kwargs):

self.asgi_app = WSGIMiddleware(self.app.wsgi_app)

def add_api(self, specification, *, name: str = None, **kwargs):
def add_api(self, specification, *, name: t.Optional[str] = None, **kwargs):
api = FlaskApi(specification, **kwargs)

if name is not None:
Expand All @@ -143,7 +151,11 @@ def add_api(self, specification, *, name: str = None, **kwargs):
return api

def add_url_rule(
self, rule, endpoint: str = None, view_func: t.Callable = None, **options
self,
rule,
endpoint: t.Optional[str] = None,
view_func: t.Optional[t.Callable] = None,
**options,
):
return self.app.add_url_rule(rule, endpoint, view_func, **options)

Expand Down Expand Up @@ -245,7 +257,11 @@ def _http_exception(self, exc: werkzeug.exceptions.HTTPException):
raise starlette.exceptions.HTTPException(exc.code, detail=exc.description)

def add_url_rule(
self, rule, endpoint: str = None, view_func: t.Callable = None, **options
self,
rule,
endpoint: t.Optional[str] = None,
view_func: t.Optional[t.Callable] = None,
**options,
):
self._middleware_app.add_url_rule(
rule, endpoint=endpoint, view_func=view_func, **options
Expand Down
8 changes: 7 additions & 1 deletion connexion/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,13 @@ class ClientProblem(ProblemException):
"""Base exception for any 4XX error. Returns 400 by default, however
:class:`BadRequestProblem` should be preferred for 400 errors."""

def __init__(self, status: int = 400, title: str = None, *, detail: str = None):
def __init__(
self,
status: int = 400,
title: t.Optional[str] = None,
*,
detail: t.Optional[str] = None,
):
super().__init__(status=status, title=title, detail=detail)


Expand Down
4 changes: 2 additions & 2 deletions connexion/frameworks/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ def build_response(
cls,
data: t.Any,
*,
content_type: str = None,
headers: dict = None,
content_type: t.Optional[str] = None,
headers: t.Optional[dict] = None,
status_code: int = None
):
raise NotImplementedError
Expand Down
4 changes: 2 additions & 2 deletions connexion/frameworks/flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ def build_response(
cls,
data: t.Any,
*,
content_type: str = None,
headers: dict = None,
content_type: t.Optional[str] = None,
headers: t.Optional[dict] = None,
status_code: int = None
):
if cls.is_framework_response(data):
Expand Down
4 changes: 2 additions & 2 deletions connexion/frameworks/starlette.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ def build_response(
cls,
data: t.Any,
*,
content_type: str = None,
headers: dict = None,
content_type: t.Optional[str] = None,
headers: t.Optional[dict] = None,
status_code: int = None,
):
if isinstance(data, dict) or isinstance(data, list):
Expand Down
2 changes: 1 addition & 1 deletion connexion/middleware/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def _framework_path_and_name(

@abc.abstractmethod
def _add_operation_internal(
self, method: str, path: str, operation: OP, name: str = None
self, method: str, path: str, operation: OP, name: t.Optional[str] = None
) -> None:
"""
Adds the operation according to the user framework in use.
Expand Down
2 changes: 1 addition & 1 deletion connexion/middleware/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ def add_error_handler(
error_handler = (code_or_exception, function)
self.error_handlers.append(error_handler)

def run(self, import_string: str = None, **kwargs):
def run(self, import_string: t.Optional[str] = None, **kwargs):
"""Run the application using uvicorn.

:param import_string: application as import string (eg. "main:app"). This is needed to run
Expand Down
6 changes: 5 additions & 1 deletion connexion/middleware/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ def _framework_path_and_name(
return starlette_path, starlette_path

def _add_operation_internal(
self, method: str, path: str, operation: RoutingOperation, name: str = None
self,
method: str,
path: str,
operation: RoutingOperation,
name: t.Optional[str] = None,
) -> None:
self.router.add_route(path, operation, methods=[method])

Expand Down
6 changes: 5 additions & 1 deletion connexion/middleware/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,11 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:

class SecurityAPI(RoutedAPI[SecurityOperation]):
def __init__(
self, *args, auth_all_paths: bool = False, security_map: dict = None, **kwargs
self,
*args,
auth_all_paths: bool = False,
security_map: t.Optional[dict] = None,
**kwargs,
):
super().__init__(*args, **kwargs)

Expand Down
5 changes: 3 additions & 2 deletions connexion/operations/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import abc
import logging
import typing as t

from connexion.utils import all_json

Expand Down Expand Up @@ -168,13 +169,13 @@ def body_name(self, content_type: str) -> str:
"""

@abc.abstractmethod
def body_schema(self, content_type: str = None) -> dict:
def body_schema(self, content_type: t.Optional[str] = None) -> dict:
"""
The body schema definition for this operation.
"""

@abc.abstractmethod
def body_definition(self, content_type: str = None) -> dict:
def body_definition(self, content_type: t.Optional[str] = None) -> dict:
"""
The body definition for this operation.
:rtype: dict
Expand Down
5 changes: 3 additions & 2 deletions connexion/operations/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

import logging
import typing as t

from connexion.datastructures import MediaTypeDict
from connexion.operations.abstract import AbstractOperation
Expand Down Expand Up @@ -212,13 +213,13 @@ def get_path_parameter_types(self):
def body_name(self, _content_type: str) -> str:
return self.request_body.get("x-body-name", "body")

def body_schema(self, content_type: str = None) -> dict:
def body_schema(self, content_type: t.Optional[str] = None) -> dict:
"""
The body schema definition for this operation.
"""
return self.body_definition(content_type).get("schema", {})

def body_definition(self, content_type: str = None) -> dict:
def body_definition(self, content_type: t.Optional[str] = None) -> dict:
"""
The body complete definition for this operation.

Expand Down
6 changes: 3 additions & 3 deletions connexion/operations/swagger2.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,17 +215,17 @@ def example_response(self, status_code=None, *args, **kwargs):

return (build_example_from_schema(schema), status_code)

def body_name(self, content_type: str = None) -> str:
def body_name(self, content_type: t.Optional[str] = None) -> str:
return self.body_definition(content_type).get("name", "body")

def body_schema(self, content_type: str = None) -> dict:
def body_schema(self, content_type: t.Optional[str] = None) -> dict:
"""
The body schema definition for this operation.
"""
body_definition = self.body_definition(content_type)
return self.with_definitions(body_definition).get("schema", {})

def body_definition(self, content_type: str = None) -> dict:
def body_definition(self, content_type: t.Optional[str] = None) -> dict:
"""
The body complete definition for this operation.

Expand Down
8 changes: 4 additions & 4 deletions connexion/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ class TestContext:
def __init__(
self,
*,
context: dict = None,
operation: AbstractOperation = None,
receive: Receive = None,
scope: Scope = None,
context: t.Optional[dict] = None,
operation: t.Optional[AbstractOperation] = None,
receive: t.Optional[Receive] = None,
scope: t.Optional[Scope] = None,
) -> None:
self.context = context if context is not None else self.build_context()
self.operation = operation if operation is not None else self.build_operation()
Expand Down