# Path: hypebot/core/params_lib.py
# def _ParseChannel(channel):
# def _ParseChannels(channels):
#   def __init__(self, defaults=None):
#   def __str__(self):
#   def Override(self, params):
#   def _AssignValueConvertDict(self, key, value):
#   def _ParseDict(self, params):
#   def __setattr__(self, key, value):
#   def get(self, key, default_value=None):  # pylint: disable=invalid-name
#   def AsDict(self):
#   def Lock(self):
#   def _RaiseIfLocked(self):
# def MergeParams(defaults, *overrides):
# class HypeParams(object):
#   SPECIAL_ATTRS = ['_locked']
#   HAS_DYNAMIC_ATTRIBUTES = True
# 
# Path: hypebot/core/schedule_lib.py
# class HypeScheduler(object):
#   def __init__(self, local_tz: str = None):
#   def StartScheduler(self):
#   def InSeconds(self, seconds: int, fn: Callable, *args, **kwargs) -> Job:
#   def DailyCallback(self,
#                     schedule_time: arrow.Arrow,
#                     fn: Callable, *args, **kwargs) -> Job:
#   def FixedRate(self,
#                 initial_delay: int,
#                 period: int,
#                 fn: Callable, *args, **kwargs) -> Job:
#   def UnscheduleJob(self, job: Job) -> None:
# 
# Path: hypebot/hype_types.py



import abc
import json
import threading
import retrying
from typing import Any, AnyStr, Callable, List, Optional, Text, Tuple, Union
from absl import logging
from hypebot.core import params_lib
from hypebot.core import schedule_lib
from hypebot.hype_types import JsonType
    super(SyncedDict, self).update(*args, **kwargs)
    self._FlushToStorage()

  def _FlushToStorage(self):
    self._store.SetJsonValue(self._storage_key, self._subkey,
                             super(SyncedDict, self).__self__)  # pytype: disable=attribute-error

  def Sync(self):
    """(Re)loads all data from the backing storage."""
    store = self._store.GetJsonValue(self._storage_key, self._subkey)
    self.clear()
    # Do not use SyncedDict.update since it will FlushToStorage unnecessarily.
    super(SyncedDict, self).update(store or {})


class HypeQueue:
  """A durable message queue built on top of an existing HypeStore.

  Any JSONType can be added to the queue via Enqueue(), and will be processes
  in a best-effort FIFO order at a later time. Messages are processed with a
  user-provided function that should be idempotent as it may be called more than
  once.

  Note that while HypeQueue is designed to be thread-safe, it is not meant to be
  used across processes. Put another way, for a given queue_name, only one
  HypeQueue object should be created globally.
  """
  _SUBKEY = 'hype_queue'

  def __init__(self, store: HypeStore, name: Text,

# Path: hypebot/core/params_lib.py
# def _ParseChannel(channel):
# def _ParseChannels(channels):
#   def __init__(self, defaults=None):
#   def __str__(self):
#   def Override(self, params):
#   def _AssignValueConvertDict(self, key, value):
#   def _ParseDict(self, params):
#   def __setattr__(self, key, value):
#   def get(self, key, default_value=None):  # pylint: disable=invalid-name
#   def AsDict(self):
#   def Lock(self):
#   def _RaiseIfLocked(self):
# def MergeParams(defaults, *overrides):
# class HypeParams(object):
#   SPECIAL_ATTRS = ['_locked']
#   HAS_DYNAMIC_ATTRIBUTES = True
# 
# Path: hypebot/core/schedule_lib.py
# class HypeScheduler(object):
#   def __init__(self, local_tz: str = None):
#   def StartScheduler(self):
#   def InSeconds(self, seconds: int, fn: Callable, *args, **kwargs) -> Job:
#   def DailyCallback(self,
#                     schedule_time: arrow.Arrow,
#                     fn: Callable, *args, **kwargs) -> Job:
#   def FixedRate(self,
#                 initial_delay: int,
#                 period: int,
#                 fn: Callable, *args, **kwargs) -> Job:
#   def UnscheduleJob(self, job: Job) -> None:
# 
# Path: hypebot/hype_types.py



# Path: hypebot/storage/storage_lib.py
import abc
import json
import threading
import retrying
from typing import Any, AnyStr, Callable, List, Optional, Text, Tuple, Union
from absl import logging
from hypebot.core import params_lib
from hypebot.core import schedule_lib
from hypebot.hype_types import JsonType

    super(SyncedDict, self).update(*args, **kwargs)
    self._FlushToStorage()

  def _FlushToStorage(self):
    self._store.SetJsonValue(self._storage_key, self._subkey,
                             super(SyncedDict, self).__self__)  # pytype: disable=attribute-error

  def Sync(self):
    """(Re)loads all data from the backing storage."""
    store = self._store.GetJsonValue(self._storage_key, self._subkey)
    self.clear()
    # Do not use SyncedDict.update since it will FlushToStorage unnecessarily.
    super(SyncedDict, self).update(store or {})


class HypeQueue:
  """A durable message queue built on top of an existing HypeStore.

  Any JSONType can be added to the queue via Enqueue(), and will be processes
  in a best-effort FIFO order at a later time. Messages are processed with a
  user-provided function that should be idempotent as it may be called more than
  once.

  Note that while HypeQueue is designed to be thread-safe, it is not meant to be
  used across processes. Put another way, for a given queue_name, only one
  HypeQueue object should be created globally.
  """
  _SUBKEY = 'hype_queue'

  def __init__(self, store: HypeStore, name: Text,

               scheduler: schedule_lib.HypeScheduler,