# Path: alembic/util/compat.py
# class EncodedIO(io.TextIOWrapper):
#     def close(self) -> None:
# def importlib_metadata_get(group: str) -> Tuple[EntryPoint, ...]:
# def formatannotation_fwdref(annotation, base_module=None):
# 
# Path: alembic/util/compat.py
# class EncodedIO(io.TextIOWrapper):
#     def close(self) -> None:
# def importlib_metadata_get(group: str) -> Tuple[EntryPoint, ...]:
# def formatannotation_fwdref(annotation, base_module=None):


import collections
import textwrap
import uuid
import warnings
from collections.abc import Iterable
from typing import Any
from typing import Callable
from typing import Dict
from typing import List
from typing import Optional
from typing import overload
from typing import Sequence
from typing import Tuple
from typing import TypeVar
from typing import Union
from sqlalchemy.util import asbool  # noqa
from sqlalchemy.util import immutabledict  # noqa
from sqlalchemy.util import memoized_property  # noqa
from sqlalchemy.util import to_list  # noqa
from sqlalchemy.util import unique_list  # noqa
from .compat import inspect_getfullargspec
from .compat import string_types
    elif isinstance(x, Iterable):
        return tuple(x)
    else:
        return (x,)


def dedupe_tuple(tup: Tuple[str, ...]) -> Tuple[str, ...]:
    return tuple(unique_list(tup))


class Dispatcher:
    def __init__(self, uselist: bool = False) -> None:
        self._registry: Dict[tuple, Any] = {}
        self.uselist = uselist

    def dispatch_for(
        self, target: Any, qualifier: str = "default"
    ) -> Callable:
        def decorate(fn):
            if self.uselist:
                self._registry.setdefault((target, qualifier), []).append(fn)
            else:
                assert (target, qualifier) not in self._registry
                self._registry[(target, qualifier)] = fn
            return fn

        return decorate

    def dispatch(self, obj: Any, qualifier: str = "default") -> Any:


# Path: alembic/util/compat.py
# class EncodedIO(io.TextIOWrapper):
#     def close(self) -> None:
# def importlib_metadata_get(group: str) -> Tuple[EntryPoint, ...]:
# def formatannotation_fwdref(annotation, base_module=None):
# 
# Path: alembic/util/compat.py
# class EncodedIO(io.TextIOWrapper):
#     def close(self) -> None:
# def importlib_metadata_get(group: str) -> Tuple[EntryPoint, ...]:
# def formatannotation_fwdref(annotation, base_module=None):


# Path: alembic/util/langhelpers.py
import collections
import textwrap
import uuid
import warnings
from collections.abc import Iterable
from typing import Any
from typing import Callable
from typing import Dict
from typing import List
from typing import Optional
from typing import overload
from typing import Sequence
from typing import Tuple
from typing import TypeVar
from typing import Union
from sqlalchemy.util import asbool  # noqa
from sqlalchemy.util import immutabledict  # noqa
from sqlalchemy.util import memoized_property  # noqa
from sqlalchemy.util import to_list  # noqa
from sqlalchemy.util import unique_list  # noqa
from .compat import inspect_getfullargspec
from .compat import string_types

    elif isinstance(x, Iterable):
        return tuple(x)
    else:
        return (x,)


def dedupe_tuple(tup: Tuple[str, ...]) -> Tuple[str, ...]:
    return tuple(unique_list(tup))


class Dispatcher:
    def __init__(self, uselist: bool = False) -> None:
        self._registry: Dict[tuple, Any] = {}
        self.uselist = uselist

    def dispatch_for(
        self, target: Any, qualifier: str = "default"
    ) -> Callable:
        def decorate(fn):
            if self.uselist:
                self._registry.setdefault((target, qualifier), []).append(fn)
            else:
                assert (target, qualifier) not in self._registry
                self._registry[(target, qualifier)] = fn
            return fn

        return decorate

    def dispatch(self, obj: Any, qualifier: str = "default") -> Any:


        if isinstance(obj, string_types):