# Path: k8s/base.py
# LOG = logging.getLogger(__name__)
#     ADDED = "ADDED"
#     MODIFIED = "MODIFIED"
#     DELETED = "DELETED"
# class MetaModel(type):
# class ApiMixIn(object):
# class Model(six.with_metaclass(MetaModel)):
# class WatchEvent(object):
# class LabelSelector(object):
# class Equality(LabelSelector):
# class Inequality(LabelSelector):
# class LabelSetSelector(LabelSelector):
# class In(LabelSetSelector):
# class NotIn(LabelSetSelector):
# class Exists(LabelSelector):
# class SelfModel:
#     def __new__(mcs, cls, bases, attrs):
#     def _build_url(cls, **kwargs):
#     def find(cls, name="", namespace="default", labels=None):
#     def list(cls, namespace="default"):
#     def watch_list(cls, namespace=None):
#     def get(cls, name, namespace="default"):
#     def get_or_create(cls, **kwargs):
#     def delete(cls, name, namespace="default", **kwargs):
#     def delete_list(cls, namespace="default", labels=None, delete_options=None, **kwargs):
#     def save(self):
#     def _label_selector(labels):
#     def __init__(self, new=True, **kwargs):
#     def _validate_fields(self):
#     def as_dict(self):
#     def merge(self, other):
#     def update_from_dict(self, d):
#     def from_dict(cls, d):
#     def __repr__(self):
#     def __eq__(self, other):
# def _api_name(name):
#     def __init__(self, event_json, cls):
#     def __repr__(self):
#     def __init__(self, value=""):
#     def __str__(self):
#     def __str__(self):
#     def __init__(self):
#     def __str__(self):
# 
# Path: k8s/models/common.py
# class ObjectMeta(Model):
#     annotations = Field(dict)
#     creationTimestamp = ReadOnlyField(datetime.datetime)
#     deletionGracePeriodSeconds = ReadOnlyField(int)
#     deletionTimestamp = ReadOnlyField(datetime.datetime)
#     finalizers = ListField(six.text_type)
#     generateName = Field(six.text_type)
#     generation = ReadOnlyField(int)
#     labels = Field(dict)
#     name = Field(six.text_type)
#     namespace = Field(six.text_type, "default")
#     ownerReferences = ListField(OwnerReference)
#     resourceVersion = ReadOnlyField(six.text_type)
#     selfLink = ReadOnlyField(six.text_type)
#     uid = ReadOnlyField(six.text_type)
# 
# Path: k8s/watcher.py
# class Watcher(object):
#     """Higher-level interface to watch for changes in objects
# 
#     The low-level :py:meth:`~.watch_list` method will stop when the API-server drops the connection.
#     When reconnecting, the API-server will send a list of :py:const:`~k8s.base.WatchEvent.ADDED`
#     events for all objects, even if they have been seen before.
# 
#     The Watcher will hide this complexity for you, and make sure to reconnect when the
#     connection drops, and skip events that have already been seen.
# 
#     :param Model model: The model class to watch
#     :param int capacity: How many seen objects to keep track of
#     """
#     def __init__(self, model, capacity=DEFAULT_CAPACITY):
#         self._seen = cachetools.LRUCache(capacity)
#         self._model = model
#         self._run_forever = True
# 
#     def watch(self, namespace=None):
#         """Watch for events
# 
#         :param str namespace: the namespace to watch for events in. The default (None) results in
#             watching for events in all namespaces.
#         :return: a generator that yields :py:class:`~.WatchEvent` objects not seen before
#         """
#         while self._run_forever:
#             for event in self._model.watch_list(namespace=namespace):
#                 o = event.object
#                 key = (o.metadata.name, o.metadata.namespace)
#                 if self._seen.get(key) == o.metadata.resourceVersion and event.type != WatchEvent.DELETED:
#                     continue
#                 self._seen[key] = o.metadata.resourceVersion
#                 yield event


import mock
import pytest
import six
from k8s.base import Model, Field, WatchEvent
from k8s.models.common import ObjectMeta
from k8s.watcher import Watcher
        assert list(gen) == []

        api_watch_list.assert_called_with(namespace=namespace)


def _event(id, event_type, rv, namespace="default"):
    metadict = {"name": "name{}".format(id), "namespace": namespace, "resourceVersion": rv}
    metadata = ObjectMeta.from_dict(metadict)
    wle = WatchListExample(metadata=metadata, value=(id * 100) + rv)
    return mock.NonCallableMagicMock(type=event_type, object=wle)


def _assert_event(event, id, event_type, rv, namespace="default"):
    assert event.type == event_type
    o = event.object
    assert o.kind == "Example"
    assert o.metadata.name == "name{}".format(id)
    assert o.metadata.namespace == namespace
    assert o.value == (id * 100) + rv


class WatchListExample(Model):
    class Meta:
        url_template = '/example'
        watch_list_url = '/watch/example'
        watch_list_url_template = '/watch/{namespace}/example'

    apiVersion = Field(six.text_type, "example.com/v1")
    kind = Field(six.text_type, "Example")
    metadata = Field(ObjectMeta)

# Path: k8s/base.py
# LOG = logging.getLogger(__name__)
#     ADDED = "ADDED"
#     MODIFIED = "MODIFIED"
#     DELETED = "DELETED"
# class MetaModel(type):
# class ApiMixIn(object):
# class Model(six.with_metaclass(MetaModel)):
# class WatchEvent(object):
# class LabelSelector(object):
# class Equality(LabelSelector):
# class Inequality(LabelSelector):
# class LabelSetSelector(LabelSelector):
# class In(LabelSetSelector):
# class NotIn(LabelSetSelector):
# class Exists(LabelSelector):
# class SelfModel:
#     def __new__(mcs, cls, bases, attrs):
#     def _build_url(cls, **kwargs):
#     def find(cls, name="", namespace="default", labels=None):
#     def list(cls, namespace="default"):
#     def watch_list(cls, namespace=None):
#     def get(cls, name, namespace="default"):
#     def get_or_create(cls, **kwargs):
#     def delete(cls, name, namespace="default", **kwargs):
#     def delete_list(cls, namespace="default", labels=None, delete_options=None, **kwargs):
#     def save(self):
#     def _label_selector(labels):
#     def __init__(self, new=True, **kwargs):
#     def _validate_fields(self):
#     def as_dict(self):
#     def merge(self, other):
#     def update_from_dict(self, d):
#     def from_dict(cls, d):
#     def __repr__(self):
#     def __eq__(self, other):
# def _api_name(name):
#     def __init__(self, event_json, cls):
#     def __repr__(self):
#     def __init__(self, value=""):
#     def __str__(self):
#     def __str__(self):
#     def __init__(self):
#     def __str__(self):
# 
# Path: k8s/models/common.py
# class ObjectMeta(Model):
#     annotations = Field(dict)
#     creationTimestamp = ReadOnlyField(datetime.datetime)
#     deletionGracePeriodSeconds = ReadOnlyField(int)
#     deletionTimestamp = ReadOnlyField(datetime.datetime)
#     finalizers = ListField(six.text_type)
#     generateName = Field(six.text_type)
#     generation = ReadOnlyField(int)
#     labels = Field(dict)
#     name = Field(six.text_type)
#     namespace = Field(six.text_type, "default")
#     ownerReferences = ListField(OwnerReference)
#     resourceVersion = ReadOnlyField(six.text_type)
#     selfLink = ReadOnlyField(six.text_type)
#     uid = ReadOnlyField(six.text_type)
# 
# Path: k8s/watcher.py
# class Watcher(object):
#     """Higher-level interface to watch for changes in objects
# 
#     The low-level :py:meth:`~.watch_list` method will stop when the API-server drops the connection.
#     When reconnecting, the API-server will send a list of :py:const:`~k8s.base.WatchEvent.ADDED`
#     events for all objects, even if they have been seen before.
# 
#     The Watcher will hide this complexity for you, and make sure to reconnect when the
#     connection drops, and skip events that have already been seen.
# 
#     :param Model model: The model class to watch
#     :param int capacity: How many seen objects to keep track of
#     """
#     def __init__(self, model, capacity=DEFAULT_CAPACITY):
#         self._seen = cachetools.LRUCache(capacity)
#         self._model = model
#         self._run_forever = True
# 
#     def watch(self, namespace=None):
#         """Watch for events
# 
#         :param str namespace: the namespace to watch for events in. The default (None) results in
#             watching for events in all namespaces.
#         :return: a generator that yields :py:class:`~.WatchEvent` objects not seen before
#         """
#         while self._run_forever:
#             for event in self._model.watch_list(namespace=namespace):
#                 o = event.object
#                 key = (o.metadata.name, o.metadata.namespace)
#                 if self._seen.get(key) == o.metadata.resourceVersion and event.type != WatchEvent.DELETED:
#                     continue
#                 self._seen[key] = o.metadata.resourceVersion
#                 yield event


# Path: tests/k8s/test_watcher.py
import mock
import pytest
import six
from k8s.base import Model, Field, WatchEvent
from k8s.models.common import ObjectMeta
from k8s.watcher import Watcher

        assert list(gen) == []

        api_watch_list.assert_called_with(namespace=namespace)


def _event(id, event_type, rv, namespace="default"):
    metadict = {"name": "name{}".format(id), "namespace": namespace, "resourceVersion": rv}
    metadata = ObjectMeta.from_dict(metadict)
    wle = WatchListExample(metadata=metadata, value=(id * 100) + rv)
    return mock.NonCallableMagicMock(type=event_type, object=wle)


def _assert_event(event, id, event_type, rv, namespace="default"):
    assert event.type == event_type
    o = event.object
    assert o.kind == "Example"
    assert o.metadata.name == "name{}".format(id)
    assert o.metadata.namespace == namespace
    assert o.value == (id * 100) + rv


class WatchListExample(Model):
    class Meta:
        url_template = '/example'
        watch_list_url = '/watch/example'
        watch_list_url_template = '/watch/{namespace}/example'

    apiVersion = Field(six.text_type, "example.com/v1")
    kind = Field(six.text_type, "Example")
    metadata = Field(ObjectMeta)

    value = Field(int)