# Path: google/cloud/ndb/exceptions.py
# class Error(Exception):
# class ContextError(Error):
# class BadValueError(Error):
# class BadArgumentError(Error):
# class BadRequestError(Error):
# class Rollback(Error):
# class BadQueryError(Error):
# class BadFilterError(Error):
# class NoLongerImplementedError(NotImplementedError):
# class Cancelled(Error):
# class NestedRetryException(Error):
#     def __init__(self):
#     def __init__(self, filter):
#     def __init__(self):
# 
# Path: google/cloud/ndb/tasklets.py
# class Future(object):
# class _TaskletFuture(Future):
# class _MultiFuture(Future):
# class Return(Exception):
# class QueueFuture(object):
# class ReducingFuture(object):
# class SerialQueueFuture(object):
#     def __init__(self, info="Unknown"):
#     def __repr__(self):
#     def done(self):
#     def running(self):
#     def wait(self):
#     def check_success(self):
#     def set_result(self, result):
#     def set_exception(self, exception):
#     def _finish(self):
#     def result(self):
#     def exception(self):
#     def get_traceback(self):
#     def add_done_callback(self, callback):
#     def cancel(self):
#     def cancelled(self):
#     def wait_any(futures):
#     def wait_all(futures):
#     def __init__(self, generator, context, info="Unknown"):
#     def _advance_tasklet(self, send_value=None, error=None):
#         def done_callback(yielded):
#     def cancel(self):
# def _get_return_value(stop):
#     def __init__(self, dependencies):
#     def __repr__(self):
#     def _dependency_done(self, dependency):
#     def cancel(self):
# def tasklet(wrapped):
#     def tasklet_wrapper(*args, **kwargs):
# def wait_any(futures):
# def wait_all(futures):
# def sleep(seconds):
# def add_flow_exception(*args, **kwargs):
# def make_context(*args, **kwargs):
# def make_default_context(*args, **kwargs):
#     def __init__(self, *args, **kwargs):
#     def __init__(self, *args, **kwargs):
#     def __init__(self, *args, **kwargs):
# def set_context(*args, **kwargs):
# def synctasklet(wrapped):
#     def synctasklet_wrapper(*args, **kwargs):
# def toplevel(wrapped):
#     def toplevel_wrapper(*args, **kwargs):


import functools
import itertools
from google.api_core import retry as core_retry
from google.api_core import exceptions as core_exceptions
from google.cloud.ndb import exceptions
from google.cloud.ndb import tasklets
        from google.cloud.ndb import context as context_module

def wraps_safely(obj, attr_names=functools.WRAPPER_ASSIGNMENTS):
    """Python 2.7 functools.wraps has a bug where attributes like ``module``
    are not copied to the wrappers and thus cause attribute errors. This
    wrapper prevents that problem."""
    return functools.wraps(
        obj, assigned=(name for name in attr_names if hasattr(obj, name))
    )


def retry_async(callback, retries=_DEFAULT_RETRIES):
    """Decorator for retrying functions or tasklets asynchronously.

    The `callback` will be called up to `retries + 1` times. Any transient
    API errors (internal server errors) raised by `callback` will be caught and
    `callback` will be retried until the call either succeeds, raises a
    non-transient error, or the number of retries is exhausted.

    See: :func:`google.api_core.retry.if_transient_error` for information on
    what kind of errors are considered transient.

    Args:
        callback (Callable): The function to be tried. May be a tasklet.
        retries (Integer): Number of times to retry `callback`. Will try up to
            `retries + 1` times.

    Returns:
        tasklets.Future: Result will be the return value of `callback`.
    """


# Path: google/cloud/ndb/exceptions.py
# class Error(Exception):
# class ContextError(Error):
# class BadValueError(Error):
# class BadArgumentError(Error):
# class BadRequestError(Error):
# class Rollback(Error):
# class BadQueryError(Error):
# class BadFilterError(Error):
# class NoLongerImplementedError(NotImplementedError):
# class Cancelled(Error):
# class NestedRetryException(Error):
#     def __init__(self):
#     def __init__(self, filter):
#     def __init__(self):
# 
# Path: google/cloud/ndb/tasklets.py
# class Future(object):
# class _TaskletFuture(Future):
# class _MultiFuture(Future):
# class Return(Exception):
# class QueueFuture(object):
# class ReducingFuture(object):
# class SerialQueueFuture(object):
#     def __init__(self, info="Unknown"):
#     def __repr__(self):
#     def done(self):
#     def running(self):
#     def wait(self):
#     def check_success(self):
#     def set_result(self, result):
#     def set_exception(self, exception):
#     def _finish(self):
#     def result(self):
#     def exception(self):
#     def get_traceback(self):
#     def add_done_callback(self, callback):
#     def cancel(self):
#     def cancelled(self):
#     def wait_any(futures):
#     def wait_all(futures):
#     def __init__(self, generator, context, info="Unknown"):
#     def _advance_tasklet(self, send_value=None, error=None):
#         def done_callback(yielded):
#     def cancel(self):
# def _get_return_value(stop):
#     def __init__(self, dependencies):
#     def __repr__(self):
#     def _dependency_done(self, dependency):
#     def cancel(self):
# def tasklet(wrapped):
#     def tasklet_wrapper(*args, **kwargs):
# def wait_any(futures):
# def wait_all(futures):
# def sleep(seconds):
# def add_flow_exception(*args, **kwargs):
# def make_context(*args, **kwargs):
# def make_default_context(*args, **kwargs):
#     def __init__(self, *args, **kwargs):
#     def __init__(self, *args, **kwargs):
#     def __init__(self, *args, **kwargs):
# def set_context(*args, **kwargs):
# def synctasklet(wrapped):
#     def synctasklet_wrapper(*args, **kwargs):
# def toplevel(wrapped):
#     def toplevel_wrapper(*args, **kwargs):


# Path: google/cloud/ndb/_retry.py
import functools
import itertools
from google.api_core import retry as core_retry
from google.api_core import exceptions as core_exceptions
from google.cloud.ndb import exceptions
from google.cloud.ndb import tasklets
        from google.cloud.ndb import context as context_module


def wraps_safely(obj, attr_names=functools.WRAPPER_ASSIGNMENTS):
    """Python 2.7 functools.wraps has a bug where attributes like ``module``
    are not copied to the wrappers and thus cause attribute errors. This
    wrapper prevents that problem."""
    return functools.wraps(
        obj, assigned=(name for name in attr_names if hasattr(obj, name))
    )


def retry_async(callback, retries=_DEFAULT_RETRIES):
    """Decorator for retrying functions or tasklets asynchronously.

    The `callback` will be called up to `retries + 1` times. Any transient
    API errors (internal server errors) raised by `callback` will be caught and
    `callback` will be retried until the call either succeeds, raises a
    non-transient error, or the number of retries is exhausted.

    See: :func:`google.api_core.retry.if_transient_error` for information on
    what kind of errors are considered transient.

    Args:
        callback (Callable): The function to be tried. May be a tasklet.
        retries (Integer): Number of times to retry `callback`. Will try up to
            `retries + 1` times.

    Returns:
        tasklets.Future: Result will be the return value of `callback`.
    """


    @tasklets.tasklet