from typing import Any, Callable, Dict

"""
This module helps you set up a bunch
of sequences, similar to how database
sequences work.

You need to be a bit careful here, since
you're dealing with a big singleton, but
for data imports that's usually easy to
manage.
"""


def _seq() -> Callable[[], int]:
    i = 0

    def next_one() -> int:
        nonlocal i
        i += 1
        return i

    return next_one


def sequencer() -> Callable[[str], int]:
    """
    Use like this:

    NEXT_ID = sequencer()
    message_id = NEXT_ID('message')
    """
    seq_dict: Dict[str, Callable[[], int]] = {}

    def next_one(name: str) -> int:
        if name not in seq_dict:
            seq_dict[name] = _seq()
        seq = seq_dict[name]
        return seq()

    return next_one


"""
NEXT_ID is a singleton used by an entire process, which is
almost always reasonable.  If you want to have two parallel
sequences, just use different `name` values.

This object gets created once and only once during the first
import of the file.
"""

NEXT_ID = sequencer()


def is_int(key: Any) -> bool:
    try:
        n = int(key)
    except ValueError:
        return False

    return n <= 999999999


class IdMapper:
    def __init__(self) -> None:
        self.map: Dict[Any, int] = {}
        self.cnt = 0

    def has(self, their_id: Any) -> bool:
        return their_id in self.map

    def get(self, their_id: Any) -> int:
        if their_id in self.map:
            return self.map[their_id]

        if is_int(their_id):
            our_id = int(their_id)
            if self.cnt > 0:
                raise Exception("mixed key styles")
        else:
            self.cnt += 1
            our_id = self.cnt

        self.map[their_id] = our_id
        return our_id

da9abd238d8c207fe04c53f427cb266ffc6a46dd
<mask token>


class IdMapper:

    def __init__(self) ->None:
        self.map: Dict[Any, int] = {}
        self.cnt = 0
    <mask token>

    def get(self, their_id: Any) ->int:
        if their_id in self.map:
            return self.map[their_id]
        if is_int(their_id):
            our_id = int(their_id)
            if self.cnt > 0:
                raise Exception('mixed key styles')
        else:
            self.cnt += 1
            our_id = self.cnt
        self.map[their_id] = our_id
        return our_id

<mask token>


class IdMapper:

    def __init__(self) ->None:
        self.map: Dict[Any, int] = {}
        self.cnt = 0

    def has(self, their_id: Any) ->bool:
        return their_id in self.map

    def get(self, their_id: Any) ->int:
        if their_id in self.map:
            return self.map[their_id]
        if is_int(their_id):
            our_id = int(their_id)
            if self.cnt > 0:
                raise Exception('mixed key styles')
        else:
            self.cnt += 1
            our_id = self.cnt
        self.map[their_id] = our_id
        return our_id

<mask token>


def _seq() ->Callable[[], int]:
    i = 0

    def next_one() ->int:
        nonlocal i
        i += 1
        return i
    return next_one


def sequencer() ->Callable[[str], int]:
    """
    Use like this:

    NEXT_ID = sequencer()
    message_id = NEXT_ID('message')
    """
    seq_dict: Dict[str, Callable[[], int]] = {}

    def next_one(name: str) ->int:
        if name not in seq_dict:
            seq_dict[name] = _seq()
        seq = seq_dict[name]
        return seq()
    return next_one


<mask token>


class IdMapper:

    def __init__(self) ->None:
        self.map: Dict[Any, int] = {}
        self.cnt = 0

    def has(self, their_id: Any) ->bool:
        return their_id in self.map

    def get(self, their_id: Any) ->int:
        if their_id in self.map:
            return self.map[their_id]
        if is_int(their_id):
            our_id = int(their_id)
            if self.cnt > 0:
                raise Exception('mixed key styles')
        else:
            self.cnt += 1
            our_id = self.cnt
        self.map[their_id] = our_id
        return our_id

<mask token>


def _seq() ->Callable[[], int]:
    i = 0

    def next_one() ->int:
        nonlocal i
        i += 1
        return i
    return next_one


def sequencer() ->Callable[[str], int]:
    """
    Use like this:

    NEXT_ID = sequencer()
    message_id = NEXT_ID('message')
    """
    seq_dict: Dict[str, Callable[[], int]] = {}

    def next_one(name: str) ->int:
        if name not in seq_dict:
            seq_dict[name] = _seq()
        seq = seq_dict[name]
        return seq()
    return next_one


<mask token>
NEXT_ID = sequencer()


def is_int(key: Any) ->bool:
    try:
        n = int(key)
    except ValueError:
        return False
    return n <= 999999999


class IdMapper:

    def __init__(self) ->None:
        self.map: Dict[Any, int] = {}
        self.cnt = 0

    def has(self, their_id: Any) ->bool:
        return their_id in self.map

    def get(self, their_id: Any) ->int:
        if their_id in self.map:
            return self.map[their_id]
        if is_int(their_id):
            our_id = int(their_id)
            if self.cnt > 0:
                raise Exception('mixed key styles')
        else:
            self.cnt += 1
            our_id = self.cnt
        self.map[their_id] = our_id
        return our_id

from typing import Any, Callable, Dict

"""
This module helps you set up a bunch
of sequences, similar to how database
sequences work.

You need to be a bit careful here, since
you're dealing with a big singleton, but
for data imports that's usually easy to
manage.
"""


def _seq() -> Callable[[], int]:
    i = 0

    def next_one() -> int:
        nonlocal i
        i += 1
        return i

    return next_one


def sequencer() -> Callable[[str], int]:
    """
    Use like this:

    NEXT_ID = sequencer()
    message_id = NEXT_ID('message')
    """
    seq_dict: Dict[str, Callable[[], int]] = {}

    def next_one(name: str) -> int:
        if name not in seq_dict:
            seq_dict[name] = _seq()
        seq = seq_dict[name]
        return seq()

    return next_one


"""
NEXT_ID is a singleton used by an entire process, which is
almost always reasonable.  If you want to have two parallel
sequences, just use different `name` values.

This object gets created once and only once during the first
import of the file.
"""

NEXT_ID = sequencer()


def is_int(key: Any) -> bool:
    try:
        n = int(key)
    except ValueError:
        return False

    return n <= 999999999


class IdMapper:
    def __init__(self) -> None:
        self.map: Dict[Any, int] = {}
        self.cnt = 0

    def has(self, their_id: Any) -> bool:
        return their_id in self.map

    def get(self, their_id: Any) -> int:
        if their_id in self.map:
            return self.map[their_id]

        if is_int(their_id):
            our_id = int(their_id)
            if self.cnt > 0:
                raise Exception("mixed key styles")
        else:
            self.cnt += 1
            our_id = self.cnt

        self.map[their_id] = our_id
        return our_id
