Skip to content
This repository has been archived by the owner on Sep 12, 2023. It is now read-only.

Commit

Permalink
chore(types): from __future__ import annotations (#66)
Browse files Browse the repository at this point in the history
Applied the forward ref annotations wherever possible. Issues with
starlite dependencies and handlers, and with sqlalchemy orm, so not
applied to those modules.
  • Loading branch information
peterschutt authored Oct 31, 2022
1 parent 3133774 commit 647c34b
Show file tree
Hide file tree
Showing 25 changed files with 75 additions and 39 deletions.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ repos:
[
"flake8-bugbear",
"flake8-comprehensions",
"flake8-future-annotations",
"flake8-mutable",
"flake8-print",
"flake8-simplify",
Expand Down
4 changes: 3 additions & 1 deletion src/starlite_saqlalchemy/cache.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Application cache config."""
from __future__ import annotations

from typing import TYPE_CHECKING

from starlite import CacheConfig
Expand All @@ -10,7 +12,7 @@
from starlite.connection import Request


def cache_key_builder(request: "Request") -> str:
def cache_key_builder(request: Request) -> str:
"""
Args:
request: Current request instance.
Expand Down
2 changes: 2 additions & 0 deletions src/starlite_saqlalchemy/compression.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Compression configuration for the application."""
from __future__ import annotations

from starlite.config.compression import CompressionConfig

config = CompressionConfig(backend="gzip")
Expand Down
1 change: 1 addition & 0 deletions src/starlite_saqlalchemy/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Application dependency providers."""

from datetime import datetime
from typing import TYPE_CHECKING
from uuid import UUID
Expand Down
7 changes: 4 additions & 3 deletions src/starlite_saqlalchemy/dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
`SQLAlchemy.Column.info` field, which allows demarcation of fields that
should always be private, or read-only at the model declaration layer.
"""
from __future__ import annotations

from enum import Enum, auto
from typing import TYPE_CHECKING, Any, cast, get_args, get_origin, get_type_hints
Expand Down Expand Up @@ -55,7 +56,7 @@ class Purpose(Enum):
WRITE = auto()


def _construct_field_info(column: "Column", purpose: Purpose) -> FieldInfo:
def _construct_field_info(column: Column, purpose: Purpose) -> FieldInfo:
default = column.default
if purpose is Purpose.READ or default is None:
return FieldInfo(...)
Expand All @@ -66,7 +67,7 @@ def _construct_field_info(column: "Column", purpose: Purpose) -> FieldInfo:
raise ValueError("Unexpected default type")


def _should_exclude_field(purpose: Purpose, column: "Column", exclude: set[str]) -> bool:
def _should_exclude_field(purpose: Purpose, column: Column, exclude: set[str]) -> bool:
if column.key in exclude:
return True
mode = column.info.get(DTO_INFO_KEY)
Expand All @@ -78,7 +79,7 @@ def _should_exclude_field(purpose: Purpose, column: "Column", exclude: set[str])


def factory(
name: str, model: type["DeclarativeBase"], purpose: Purpose, exclude: set[str] | None = None
name: str, model: type[DeclarativeBase], purpose: Purpose, exclude: set[str] | None = None
) -> type[BaseModel]:
"""Create a pydantic model class from a SQLAlchemy declarative ORM class.
Expand Down
1 change: 1 addition & 0 deletions src/starlite_saqlalchemy/endpoint_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
from __future__ import annotations

import inspect
from typing import Any
Expand Down
14 changes: 6 additions & 8 deletions src/starlite_saqlalchemy/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
Also, defines functions that translate service and repository exceptions
into HTTP exceptions.
"""
from __future__ import annotations

import logging
from typing import TYPE_CHECKING

Expand Down Expand Up @@ -44,7 +46,7 @@ class ForbiddenException(HTTPException):
status_code = 403


def after_exception_hook_handler(exc: Exception, scope: "Scope", state: "State") -> None:
def after_exception_hook_handler(exc: Exception, scope: Scope, state: State) -> None:
"""Logs exception and returns appropriate response.
Args:
Expand All @@ -60,18 +62,14 @@ def after_exception_hook_handler(exc: Exception, scope: "Scope", state: "State")
)


def _create_error_response_from_starlite_middleware(
request: "Request", exc: Exception
) -> "Response":
def _create_error_response_from_starlite_middleware(request: Request, exc: Exception) -> Response:
server_middleware = ServerErrorMiddleware(app=request.app) # type: ignore[arg-type]
return server_middleware.debug_response( # type: ignore[return-value]
request=request, exc=exc # type:ignore[arg-type]
)


def repository_exception_to_http_response(
request: "Request", exc: RepositoryException
) -> "Response":
def repository_exception_to_http_response(request: Request, exc: RepositoryException) -> Response:
"""Transform repository exceptions to HTTP exceptions.
Args:
Expand All @@ -93,7 +91,7 @@ def repository_exception_to_http_response(
return create_exception_response(http_exc())


def service_exception_to_http_response(request: "Request", exc: ServiceException) -> "Response":
def service_exception_to_http_response(request: Request, exc: ServiceException) -> Response:
"""Transform service exceptions to HTTP exceptions.
Args:
Expand Down
2 changes: 2 additions & 0 deletions src/starlite_saqlalchemy/http.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Async HTTP request client implementation built on `httpx`."""
from __future__ import annotations

from typing import Any

import httpx
Expand Down
32 changes: 17 additions & 15 deletions src/starlite_saqlalchemy/init_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def example_handler() -> dict:
The `PluginConfig` has switches to disable every aspect of the plugin behavior.
"""
from __future__ import annotations

from typing import TYPE_CHECKING

from pydantic import BaseModel
Expand Down Expand Up @@ -70,7 +72,7 @@ class PluginConfig(BaseModel):
application.
"""

worker_functions: "list[WorkerFunction | tuple[str, WorkerFunction]]" = []
worker_functions: list[WorkerFunction | tuple[str, WorkerFunction]] = []
"""
Queue worker functions.
"""
Expand Down Expand Up @@ -153,7 +155,7 @@ class ConfigureApp:
def __init__(self, config: PluginConfig = PluginConfig()) -> None:
self.config = config

def __call__(self, app_config: "AppConfig") -> "AppConfig":
def __call__(self, app_config: AppConfig) -> AppConfig:
"""Entrypoint to the app config plugin.
Receives the [`AppConfig`][starlite.config.app.AppConfig] object and modifies it.
Expand All @@ -180,7 +182,7 @@ def __call__(self, app_config: "AppConfig") -> "AppConfig":
app_config.on_shutdown.extend([http.Client.close, redis.client.close])
return app_config

def configure_after_exception(self, app_config: "AppConfig") -> None:
def configure_after_exception(self, app_config: AppConfig) -> None:
"""Add the logging after exception hook handler.
Args:
Expand All @@ -191,7 +193,7 @@ def configure_after_exception(self, app_config: "AppConfig") -> None:
app_config.after_exception = [app_config.after_exception]
app_config.after_exception.append(exceptions.after_exception_hook_handler)

def configure_cache(self, app_config: "AppConfig") -> None:
def configure_cache(self, app_config: AppConfig) -> None:
"""Configure the application cache.
We only overwrite if [`DEFAULT_CACHE_CONFIG`][starlite.app.DEFAULT_CACHE_CONFIG] is the
Expand All @@ -203,7 +205,7 @@ def configure_cache(self, app_config: "AppConfig") -> None:
if self.config.do_cache and app_config.cache_config is DEFAULT_CACHE_CONFIG:
app_config.cache_config = cache.config

def configure_collection_dependencies(self, app_config: "AppConfig") -> None:
def configure_collection_dependencies(self, app_config: AppConfig) -> None:
"""Add the required [`Provide`][starlite.datastructures.Provide]
instances to the app dependency mapping.
Expand All @@ -216,7 +218,7 @@ def configure_collection_dependencies(self, app_config: "AppConfig") -> None:
for key, value in dependencies.create_collection_dependencies().items():
app_config.dependencies.setdefault(key, value)

def configure_compression(self, app_config: "AppConfig") -> None:
def configure_compression(self, app_config: AppConfig) -> None:
"""Configure application compression.
No-op if [`AppConfig.compression_config`][starlite.config.app.AppConfig.compression_config]
Expand All @@ -228,7 +230,7 @@ def configure_compression(self, app_config: "AppConfig") -> None:
if self.config.do_compression and app_config.compression_config is None:
app_config.compression_config = compression.config

def configure_exception_handlers(self, app_config: "AppConfig") -> None:
def configure_exception_handlers(self, app_config: AppConfig) -> None:
"""Add the handlers that translate service and repository exceptions
into HTTP exceptions.
Expand All @@ -247,7 +249,7 @@ def configure_exception_handlers(self, app_config: "AppConfig") -> None:
ServiceException, exceptions.service_exception_to_http_response
)

def configure_health_check(self, app_config: "AppConfig") -> None:
def configure_health_check(self, app_config: AppConfig) -> None:
"""Adds the health check controller.
Args:
Expand All @@ -256,7 +258,7 @@ def configure_health_check(self, app_config: "AppConfig") -> None:
if self.config.do_health_check:
app_config.route_handlers.append(health_check)

def configure_logging(self, app_config: "AppConfig") -> None:
def configure_logging(self, app_config: AppConfig) -> None:
"""Configures application logging if it has not already been
configured.
Expand All @@ -266,7 +268,7 @@ def configure_logging(self, app_config: "AppConfig") -> None:
if self.config.do_logging and app_config.logging_config is None:
app_config.logging_config = logging.config

def configure_openapi(self, app_config: "AppConfig") -> None:
def configure_openapi(self, app_config: AppConfig) -> None:
"""Configures the OpenAPI docs if they have not already been
configured.
Expand All @@ -278,7 +280,7 @@ def configure_openapi(self, app_config: "AppConfig") -> None:
if self.config.do_openapi and app_config.openapi_config is DEFAULT_OPENAPI_CONFIG:
app_config.openapi_config = openapi.config

def configure_response_class(self, app_config: "AppConfig") -> None:
def configure_response_class(self, app_config: AppConfig) -> None:
"""Add the custom response class.
No-op if the [`AppConfig.response_class`][starlite.config.app.AppConfig.response_class]
Expand All @@ -290,7 +292,7 @@ def configure_response_class(self, app_config: "AppConfig") -> None:
if self.config.do_response_class and app_config.response_class is None:
app_config.response_class = response.Response

def configure_sentry(self, app_config: "AppConfig") -> None:
def configure_sentry(self, app_config: AppConfig) -> None:
"""Add handler to configure Sentry integration.
Args:
Expand All @@ -299,7 +301,7 @@ def configure_sentry(self, app_config: "AppConfig") -> None:
if self.config.do_sentry:
app_config.on_startup.append(sentry.configure)

def configure_sqlalchemy_plugin(self, app_config: "AppConfig") -> None:
def configure_sqlalchemy_plugin(self, app_config: AppConfig) -> None:
"""Configure `SQLAlchemy` for the application.
Adds a configured [`SQLAlchemyPlugin`][starlite.plugins.sql_alchemy.SQLAlchemyPlugin] to
Expand All @@ -311,7 +313,7 @@ def configure_sqlalchemy_plugin(self, app_config: "AppConfig") -> None:
if self.config.do_sqlalchemy_plugin:
app_config.plugins.append(SQLAlchemyPlugin(config=sqlalchemy_plugin.config))

def configure_static_files(self, app_config: "AppConfig") -> None:
def configure_static_files(self, app_config: AppConfig) -> None:
"""Configure static files for the application.
No-op if
Expand All @@ -324,7 +326,7 @@ def configure_static_files(self, app_config: "AppConfig") -> None:
if self.config.do_static_files and app_config.static_files_config is not None:
app_config.static_files_config = static_files.config

def configure_worker(self, app_config: "AppConfig") -> None:
def configure_worker(self, app_config: AppConfig) -> None:
"""Configure the `SAQ` async worker.
No-op if there are no worker functions set on
Expand Down
2 changes: 2 additions & 0 deletions src/starlite_saqlalchemy/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
Adds a filter for health check route logs.
"""
from __future__ import annotations

import logging
import re
from typing import Any
Expand Down
1 change: 1 addition & 0 deletions src/starlite_saqlalchemy/openapi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Application OpenAPI config."""
from __future__ import annotations

from pydantic_openapi_schema.v3_1_0 import Contact
from starlite import OpenAPIConfig
Expand Down
1 change: 1 addition & 0 deletions src/starlite_saqlalchemy/redis.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Application redis instance."""
from __future__ import annotations

from redis.asyncio import Redis

Expand Down
2 changes: 2 additions & 0 deletions src/starlite_saqlalchemy/repository/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Abstraction over the data storage for the application."""
from __future__ import annotations

from . import abc, exceptions, filters, sqlalchemy, types

__all__ = [
Expand Down
4 changes: 3 additions & 1 deletion src/starlite_saqlalchemy/repository/abc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""AbstractRepository defines the interface for interacting with the
application persistent data."""
from __future__ import annotations

from abc import ABCMeta, abstractmethod
from typing import TYPE_CHECKING, Any, Generic, TypeVar

Expand All @@ -24,7 +26,7 @@ class AbstractRepository(Generic[T], metaclass=ABCMeta):
id_attribute = "id"
"""Name of the primary identifying attribute on `model_type`."""

def __init__(self, session: "AsyncSession") -> None:
def __init__(self, session: AsyncSession) -> None:
self.session = session

@abstractmethod
Expand Down
1 change: 1 addition & 0 deletions src/starlite_saqlalchemy/repository/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Repository exception types."""
from __future__ import annotations


class RepositoryException(Exception):
Expand Down
2 changes: 2 additions & 0 deletions src/starlite_saqlalchemy/repository/filters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Datastructures used by repository to apply filtering to collection
queries."""
from __future__ import annotations

from collections import abc
from dataclasses import dataclass
from datetime import datetime
Expand Down
10 changes: 5 additions & 5 deletions src/starlite_saqlalchemy/repository/sqlalchemy.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""SQLAlchemy-based implementation of the repository protocol."""
from __future__ import annotations

from contextlib import contextmanager
from typing import TYPE_CHECKING, Any, Literal, TypeVar

Expand Down Expand Up @@ -67,9 +69,7 @@ class SQLAlchemyRepository(AbstractRepository[ModelT]):

model_type: type[ModelT]

def __init__(
self, session: "AsyncSession", select_: "Select[tuple[ModelT]] | None" = None
) -> None:
def __init__(self, session: AsyncSession, select_: Select[tuple[ModelT]] | None = None) -> None:
super().__init__(session)
self._select = select(self.model_type) if select_ is None else select_

Expand Down Expand Up @@ -181,13 +181,13 @@ async def _attach_to_session(
async def _execute(self) -> "Result[tuple[ModelT, ...]]":
return await self.session.execute(self._select)

def _filter_in_collection(self, field_name: str, values: "abc.Collection[Any]") -> None:
def _filter_in_collection(self, field_name: str, values: abc.Collection[Any]) -> None:
if not values:
return
self._select = self._select.where(getattr(self.model_type, field_name).in_(values))

def _filter_on_datetime_field(
self, field_name: str, before: "datetime | None", after: "datetime | None"
self, field_name: str, before: datetime | None, after: datetime | None
) -> None:
field = getattr(self.model_type, field_name)
if before is not None:
Expand Down
2 changes: 2 additions & 0 deletions src/starlite_saqlalchemy/repository/types.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Repository type definitions."""
from __future__ import annotations

from starlite_saqlalchemy.repository.filters import (
BeforeAfter,
CollectionFilter,
Expand Down
2 changes: 2 additions & 0 deletions src/starlite_saqlalchemy/response.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Custom response class for the application that handles serialization of pg
UUID values."""
from __future__ import annotations

from typing import Any

import starlite
Expand Down
2 changes: 2 additions & 0 deletions src/starlite_saqlalchemy/sentry.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
See: https://github.com/getsentry/sentry-python/issues/1549
"""
from __future__ import annotations

import sentry_sdk
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration

Expand Down
Loading

0 comments on commit 647c34b

Please sign in to comment.