Skip to content

Commit

Permalink
Tagging version 0.1.3
Browse files Browse the repository at this point in the history
Things are getting closer and closer to what I would call a stable
release (this will be 0.2.0). In this commit, I've added stub files
which I'm hoping will help out mypy for the plugin modules.
  • Loading branch information
travishathaway committed Jan 14, 2023
1 parent 72abe8b commit bed8f01
Show file tree
Hide file tree
Showing 26 changed files with 202 additions and 28 deletions.
10 changes: 6 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ repos:
exclude: "mkdocs.yml"
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/pre-commit/mirrors-mypy
rev: '' # Use the sha / tag you want to point at
hooks:
- id: mypy
# Disabling mypy until I can figure out how to exclude the "stubs" directory 🤷‍
# - repo: https://github.com/pre-commit/mirrors-mypy
# rev: '' # Use the sha / tag you want to point at
# hooks:
# - id: mypy
# args: ["--exclude=stubs", "--no-strict-optional", "--ignore-missing-imports"]
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
hooks:
Expand Down
2 changes: 1 addition & 1 deletion latz/__version__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__title__ = "latz"
__description__ = "Tool for finding images. Maybe with location 🤷..."
__version__ = "0.1.2"
__version__ = "0.1.3"
3 changes: 1 addition & 2 deletions latz/plugins/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
from .hookspec import hookimpl # noqa: F401
from .types import ImageAPIPlugin # noqa: F401
from .hookspec import hookimpl, ImageAPIPlugin # noqa: F401
16 changes: 14 additions & 2 deletions latz/plugins/hookspec.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
from collections.abc import Iterable
from typing import NamedTuple, Any

import pluggy # type: ignore
from pydantic import BaseModel

from ..constants import APP_NAME
from .types import ImageAPIPlugin
from latz.constants import APP_NAME
from latz.image import ImageAPIContextManager

hookspec = pluggy.HookspecMarker(APP_NAME)
hookimpl = pluggy.HookimplMarker(APP_NAME)


class ImageAPIPlugin(NamedTuple):
"""
Holds the metadata, config fields and context manager for the image search backend
"""

name: str
image_api_context_manager: type[ImageAPIContextManager]
config_fields: dict[str, tuple[type[BaseModel], Any]]


class AppHookSpecs:
"""Holds all hookspecs for this application"""

Expand Down
17 changes: 0 additions & 17 deletions latz/plugins/types.py

This file was deleted.

2 changes: 1 addition & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[mypy]
files=latz/**/*.py
warn_no_return = False
exclude = "stubs/*"
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
[tool.poetry]
name = "latz"
version = "0.1.2"
version = "0.1.3"
description = "CLI Program for downloading images. Maybe by location too..."
authors = ["Travis Hathaway <[email protected]>"]
license = "GNU v3"
readme = "README.md"
packages = [
{ include = "latz/**/*.py" },
{ include = "stubs/**/*.pyi" }
]

[tool.poetry.dependencies]
python = "^3.10"
Expand Down
Empty file added stubs/latz/__init__.pyi
Empty file.
6 changes: 6 additions & 0 deletions stubs/latz/cli.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from .commands import config_group as config_group, search_command as search_command
from .config import BaseAppConfig as BaseAppConfig, ConfigError as ConfigError, get_app_config as get_app_config
from .constants import CONFIG_FILES as CONFIG_FILES
from .plugins.manager import get_plugin_manager as get_plugin_manager

def cli(ctx) -> None: ...
Empty file.
Empty file.
10 changes: 10 additions & 0 deletions stubs/latz/commands/config/commands.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from ...config import ConfigError as ConfigError, parse_config_file_as_json as parse_config_file_as_json, write_config_file as write_config_file
from ...constants import CONFIG_FILE_CWD as CONFIG_FILE_CWD, CONFIG_FILE_HOME_DIR as CONFIG_FILE_HOME_DIR
from .validators import ConfigValuesValidator as ConfigValuesValidator
from _typeshed import Incomplete

validate_and_parse_config_values: Incomplete

def group() -> None: ...
def show_command(ctx) -> None: ...
def set_command(home, config_values) -> None: ...
9 changes: 9 additions & 0 deletions stubs/latz/commands/config/validators.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from typing import Any

class ConfigValuesValidator:
def __init__(self) -> None: ...
def __call__(self, ctx, _, values) -> dict[str, str]: ...
def validate_single_value(self, value: str) -> dict: ...

def get_dotted_path_value(nest: dict, dotted_path: str) -> Any: ...
def get_nested_dict_from_path(path: str, value: Any) -> dict: ...
3 changes: 3 additions & 0 deletions stubs/latz/commands/search.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from ..image import ImageAPI as ImageAPI

def command(ctx, query: str): ...
2 changes: 2 additions & 0 deletions stubs/latz/config/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .main import ConfigError as ConfigError, get_app_config as get_app_config, parse_config_file_as_json as parse_config_file_as_json, write_config_file as write_config_file
from .models import BaseAppConfig as BaseAppConfig
9 changes: 9 additions & 0 deletions stubs/latz/config/errors.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from collections.abc import Sequence
from pathlib import Path
from pydantic import ValidationError as ValidationError

PARSE_ERROR_SUGGESTION: str
CONFIG_ERROR_PREFIX: str

def format_validation_error(exc: ValidationError, path: Path) -> str: ...
def format_all_validation_errors(validation_errors: Sequence[str]) -> str: ...
23 changes: 23 additions & 0 deletions stubs/latz/config/main.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from .errors import format_all_validation_errors as format_all_validation_errors, format_validation_error as format_validation_error
from .models import BaseAppConfig as BaseAppConfig
from _typeshed import Incomplete
from collections.abc import Iterable, Sequence
from pathlib import Path
from typing import Any, NamedTuple

logger: Incomplete

class ConfigError(Exception): ...

class ParsedConfigFile(NamedTuple):
path: Path
data: Union[dict, None]
error: Union[str, None]
model: Union[BaseAppConfig, None]

def merge_app_configs(app_configs: Iterable[BaseAppConfig], model_class: type[BaseAppConfig]) -> BaseAppConfig: ...
def parse_config_file_as_json(path: Path) -> ParsedConfigFile: ...
def parse_app_config_model(parsed_config: ParsedConfigFile, model_class: type[BaseAppConfig]) -> ParsedConfigFile: ...
def parse_config_files(paths: Sequence[Path]) -> Union[tuple[ParsedConfigFile, ...], None]: ...
def get_app_config(paths: Sequence[Path], model_class: type[BaseAppConfig]) -> BaseAppConfig: ...
def write_config_file(config_file_data: dict[str, Any], config_file: Path) -> None: ...
8 changes: 8 additions & 0 deletions stubs/latz/config/models.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ..constants import ENV_PREFIX as ENV_PREFIX
from _typeshed import Incomplete
from pydantic import BaseSettings

class BaseAppConfig(BaseSettings):
backend: str
class Config:
env_prefix: Incomplete
8 changes: 8 additions & 0 deletions stubs/latz/constants.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from _typeshed import Incomplete

APP_NAME: str
ENV_PREFIX: str
CONFIG_FILE_NAME: str
CONFIG_FILE_CWD: Incomplete
CONFIG_FILE_HOME_DIR: Incomplete
CONFIG_FILES: Incomplete
17 changes: 17 additions & 0 deletions stubs/latz/image.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import NamedTuple, Protocol

class ImageSearchResult(NamedTuple):
url: Union[str, None]
width: Union[int, None]
height: Union[int, None]

class ImageSearchResultSet(NamedTuple):
results: tuple[ImageSearchResult, ...]
total_number_results: Union[int, None]

class ImageAPIContextManager(Protocol):
def __enter__(self) -> ImageAPI: ...
def __exit__(self, exc_type, exc_val, exc_tb) -> None: ...

class ImageAPI(Protocol):
def search(self, query: str) -> ImageSearchResultSet: ...
1 change: 1 addition & 0 deletions stubs/latz/plugins/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .hookspec import ImageAPIPlugin as ImageAPIPlugin, hookimpl as hookimpl
17 changes: 17 additions & 0 deletions stubs/latz/plugins/hookspec.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from _typeshed import Incomplete
from collections.abc import Iterable
from latz.constants import APP_NAME as APP_NAME
from latz.image import ImageAPIContextManager as ImageAPIContextManager
from pydantic import BaseModel as BaseModel
from typing import Any, NamedTuple

hookspec: Incomplete
hookimpl: Incomplete

class ImageAPIPlugin(NamedTuple):
name: str
image_api_context_manager: type[ImageAPIContextManager]
config_fields: dict[str, tuple[type[BaseModel], Any]]

class AppHookSpecs:
def image_api(self) -> Iterable[ImageAPIPlugin]: ...
Empty file.
20 changes: 20 additions & 0 deletions stubs/latz/plugins/image/placeholder.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from .. import ImageAPIPlugin as ImageAPIPlugin, hookimpl as hookimpl
from ...image import ImageSearchResult as ImageSearchResult, ImageSearchResultSet as ImageSearchResultSet
from _typeshed import Incomplete
from collections.abc import Generator
from pydantic import BaseModel
from typing import Literal

PLUGIN_NAME: str

class PlaceholderBackendConfig(BaseModel):
type: Literal['bear', 'kitten']

CONFIG_FIELDS: Incomplete

class PlaceholderImageAPI:
def __init__(self, placeholder_type: str) -> None: ...
def search(self, query: str) -> ImageSearchResultSet: ...

def placeholder_context_manager(config) -> Generator[Incomplete, None, None]: ...
def image_api(): ...
22 changes: 22 additions & 0 deletions stubs/latz/plugins/image/unsplash.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from .. import ImageAPIPlugin as ImageAPIPlugin, hookimpl as hookimpl
from ...image import ImageSearchResult as ImageSearchResult, ImageSearchResultSet as ImageSearchResultSet
from _typeshed import Incomplete
from collections.abc import Iterator
from httpx import Client
from pydantic import BaseModel

PLUGIN_NAME: str

class UnsplashBackendConfig(BaseModel):
access_key: str

CONFIG_FIELDS: Incomplete
BASE_URL: str
SEARCH_ENDPOINT: str

class UnsplashImageAPI:
def __init__(self, client: Client) -> None: ...
def search(self, query: str) -> ImageSearchResultSet: ...

def unsplash_context_manager(config) -> Iterator[UnsplashImageAPI]: ...
def image_api(): ...
19 changes: 19 additions & 0 deletions stubs/latz/plugins/manager.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from ..config.models import BaseAppConfig as BaseAppConfig
from ..constants import APP_NAME as APP_NAME
from ..image import ImageAPI as ImageAPI
from .hookspec import AppHookSpecs as AppHookSpecs
from .image import placeholder as placeholder, unsplash as unsplash
from collections.abc import Callable as Callable
from pluggy import PluginManager

class AppPluginManager(PluginManager):
def __init__(self, *args, **kwargs) -> None: ...
def reset_cache(self) -> None: ...
@property
def image_api_names(self) -> tuple[str, ...]: ...
@property
def image_api_config_fields(self) -> dict: ...
def get_image_api_context_manager(self, app_config: BaseAppConfig) -> ImageAPI: ...
def get_backend_validator_func(self) -> Callable: ...

def get_plugin_manager() -> AppPluginManager: ...

0 comments on commit bed8f01

Please sign in to comment.