from collections.abc import Callable, Iterable
from hashlib import _Hash
from typing import Any
import functools
import re

from django.contrib.contenttypes.models import ContentType
from django.db.models import Model
from django.db.models.base import ModelBase
from django.http import HttpRequest
from wagtail.models import Page, Site

WAGTAIL_APPEND_SLASH: bool

def camelcase_to_underscore(str: str) -> str: ...
def string_to_ascii(value: str) -> str: ...
def get_model_string(model: type[Model]) -> str: ...
def resolve_model_string(model_string: str | type, default_app: str | None = None) -> type[Model]: ...

SLUGIFY_RE: re.Pattern[str]

def cautious_slugify(value: str) -> str: ...
def safe_snake_case(value: str) -> str: ...
def get_content_type_label(content_type: ContentType) -> str: ...
def accepts_kwarg(func: Callable[..., Any], kwarg: str) -> bool: ...

class InvokeViaAttributeShortcut:
    obj: Any
    method_name: str
    def __init__(self, obj: Any, method_name: str) -> None: ...
    def __getattr__(self, name: str) -> Any: ...

def find_available_slug(parent: Page, requested_slug: str, ignore_page_id: int | None = None) -> str: ...
@functools.cache
def get_content_languages() -> dict[str, str]: ...
def get_supported_content_language_variant(lang_code: str, strict: bool = False) -> str: ...
def get_locales_display_names() -> dict[int, str]: ...
def reset_cache(**kwargs: Any) -> None: ...
def multigetattr(item: Any, accessor: str) -> Any: ...
def get_dummy_request(*, path: str = "/", site: Site | None = None) -> HttpRequest: ...
def safe_md5(data: bytes = b"", usedforsecurity: bool = True) -> _Hash: ...

class BatchProcessor:
    max_size: int
    items: list[Any]
    added_count: int
    def __init__(self, max_size: int) -> None: ...
    def __len__(self) -> int: ...
    def add(self, item: Any) -> None: ...
    def extend(self, iterable: Iterable[Any]) -> None: ...
    def process(self) -> None: ...
    def pre_process(self) -> None: ...
    def post_process(self) -> None: ...

class BatchCreator(BatchProcessor):
    model: ModelBase | None
    ignore_conflicts: bool
    created_count: int
    def __init__(self, max_size: int, *, model: ModelBase | None = None, ignore_conflicts: bool = False) -> None: ...
    def initialize_instance(self, kwargs: dict[str, Any]) -> Model: ...
    def add(self, *, instance: Model | None = None, **kwargs: Any) -> None: ...
    def extend(self, iterable: Iterable[Model | dict[str, Any]]) -> None: ...
    def get_summary(self) -> str: ...

def make_wagtail_template_fragment_key(
    fragment_name: str, page: Page, site: Site, vary_on: list[str] | None = None
) -> str: ...
