Repository: canonical/operator
Pull request #91 (2019-12-13 18:51:09)

Rename Event to EventSource
Per discussions, we're keeping the wrapping of event types explicit but renaming `Event` to avoid confusion between it and `EventBase`.


Patch:
diff --git a/ops/charm.py b/ops/charm.py
index 2ec6a23..3ccca13 100755
--- a/ops/charm.py
+++ b/ops/charm.py
@@ -1,4 +1,4 @@
-from ops.framework import Object, Event, EventBase, EventsBase
+from ops.framework import Object, EventSource, EventBase, EventsBase
 
 
 class HookEvent(EventBase):
@@ -113,16 +113,16 @@ class StorageDetachingEvent(StorageEvent):
 
 class CharmEvents(EventsBase):
 
-    install = Event(InstallEvent)
-    start = Event(StartEvent)
-    stop = Event(StopEvent)
-    update_status = Event(UpdateStatusEvent)
-    config_changed = Event(ConfigChangedEvent)
-    upgrade_charm = Event(UpgradeCharmEvent)
-    pre_series_upgrade = Event(PreSeriesUpgradeEvent)
-    post_series_upgrade = Event(PostSeriesUpgradeEvent)
-    leader_elected = Event(LeaderElectedEvent)
-    leader_settings_changed = Event(LeaderSettingsChangedEvent)
+    install = EventSource(InstallEvent)
+    start = EventSource(StartEvent)
+    stop = EventSource(StopEvent)
+    update_status = EventSource(UpdateStatusEvent)
+    config_changed = EventSource(ConfigChangedEvent)
+    upgrade_charm = EventSource(UpgradeCharmEvent)
+    pre_series_upgrade = EventSource(PreSeriesUpgradeEvent)
+    post_series_upgrade = EventSource(PostSeriesUpgradeEvent)
+    leader_elected = EventSource(LeaderElectedEvent)
+    leader_settings_changed = EventSource(LeaderSettingsChangedEvent)
 
 
 class CharmBase(Object):
diff --git a/ops/framework.py b/ops/framework.py
index eef6961..09e69e2 100755
--- a/ops/framework.py
+++ b/ops/framework.py
@@ -112,17 +112,16 @@ class EventBase:
         self.deferred = False
 
 
-class Event:
-    """Event creates class descriptors to operate with events.
+class EventSource:
+    """EventSource wraps an event type with a descriptor to facilitate observing and emitting.
 
     It is generally used as:
 
         class SomethingHappened(EventBase):
             pass
 
-        class SomeObject:
-            something_happened = Event(SomethingHappened)
-
+        class SomeObject(Object):
+            something_happened = EventSource(SomethingHappened)
 
     With that, instances of that type will offer the someobj.something_happened
     attribute which is a BoundEvent and may be used to emit and observe the event.
@@ -138,7 +137,7 @@ class Event:
     def __set_name__(self, emitter_type, event_kind):
         if self.event_kind is not None:
             raise RuntimeError(
-                f'Event({self.event_type.__name__}) reused as '
+                f'EventSource({self.event_type.__name__}) reused as '
                 f'{self.emitter_type.__name__}.{self.event_kind} and '
                 f'{emitter_type.__name__}.{event_kind}')
         self.event_kind = event_kind
@@ -204,7 +203,7 @@ class Object:
         # really relevant if someone is either emitting the event or observing
         # it.
         for attr_name, attr_value in inspect.getmembers(type(self)):
-            if isinstance(attr_value, Event):
+            if isinstance(attr_value, EventSource):
                 event_type = attr_value.event_type
                 event_kind = attr_name
                 emitter = self
@@ -247,7 +246,7 @@ class EventsBase(Object):
         except AttributeError:
             pass
 
-        event_descriptor = Event(event_type)
+        event_descriptor = EventSource(event_type)
         event_descriptor.__set_name__(cls, event_kind)
         setattr(cls, event_kind, event_descriptor)
 
@@ -258,7 +257,7 @@ class EventsBase(Object):
         # We have to iterate over the class rather than instance to allow for properties which
         # might call this method (e.g., event views), leading to infinite recursion.
         for attr_name, attr_value in inspect.getmembers(type(self)):
-            if isinstance(attr_value, Event):
+            if isinstance(attr_value, EventSource):
                 # We actually care about the bound_event, however, since it
                 # provides the most info for users of this method.
                 event_kind = attr_name
@@ -289,8 +288,8 @@ class CommitEvent(EventBase):
 
 
 class FrameworkEvents(EventsBase):
-    pre_commit = Event(PreCommitEvent)
-    commit = Event(CommitEvent)
+    pre_commit = EventSource(PreCommitEvent)
+    commit = EventSource(CommitEvent)
 
 
 class NoSnapshotError(Exception):
@@ -594,7 +593,7 @@ class StoredStateChanged(EventBase):
 
 
 class StoredStateEvents(EventsBase):
-    changed = Event(StoredStateChanged)
+    changed = EventSource(StoredStateChanged)
 
 
 class StoredStateData(Object):


Test patch:
diff --git a/test/test_charm.py b/test/test_charm.py
index f558259..ec6506c 100755
--- a/test/test_charm.py
+++ b/test/test_charm.py
@@ -9,7 +9,7 @@ from pathlib import Path
 
 from ops.charm import CharmBase, CharmMeta
 from ops.charm import CharmEvents
-from ops.framework import Framework, Event, EventBase
+from ops.framework import Framework, EventSource, EventBase
 from ops.model import Model, ModelBackend
 
 
@@ -29,7 +29,7 @@ class TestCharm(unittest.TestCase):
             pass
 
         class TestCharmEvents(CharmEvents):
-            custom = Event(CustomEvent)
+            custom = EventSource(CustomEvent)
 
         # Relations events are defined dynamically and modify the class attributes.
         # We use a subclass temporarily to prevent these side effects from leaking.
diff --git a/test/test_framework.py b/test/test_framework.py
index 6d8f582..34095f3 100755
--- a/test/test_framework.py
+++ b/test/test_framework.py
@@ -8,7 +8,7 @@ import gc
 from pathlib import Path
 
 from ops.framework import (
-    Framework, Handle, Event, EventsBase, EventBase, Object, PreCommitEvent, CommitEvent,
+    Framework, Handle, EventSource, EventsBase, EventBase, Object, PreCommitEvent, CommitEvent,
     NoSnapshotError, StoredState, StoredList, BoundStoredState, StoredStateData
 )
 
@@ -110,9 +110,9 @@ class TestFramework(unittest.TestCase):
             pass
 
         class MyNotifier(Object):
-            foo = Event(MyEvent)
-            bar = Event(MyEvent)
-            baz = Event(MyEvent)
+            foo = EventSource(MyEvent)
+            bar = EventSource(MyEvent)
+            baz = EventSource(MyEvent)
 
         class MyObserver(Object):
             def __init__(self, parent, key):
@@ -150,10 +150,10 @@ class TestFramework(unittest.TestCase):
             pass
 
         class MyNotifier(Object):
-            foo = Event(MyEvent)
-            bar = Event(MyEvent)
-            baz = Event(MyEvent)
-            qux = Event(MyEvent)
+            foo = EventSource(MyEvent)
+            bar = EventSource(MyEvent)
+            baz = EventSource(MyEvent)
+            qux = EventSource(MyEvent)
 
         class MyObserver(Object):
             def on_foo(self):
@@ -231,11 +231,11 @@ class TestFramework(unittest.TestCase):
             pass
 
         class MyNotifier1(Object):
-            a = Event(MyEvent)
-            b = Event(MyEvent)
+            a = EventSource(MyEvent)
+            b = EventSource(MyEvent)
 
         class MyNotifier2(Object):
-            c = Event(MyEvent)
+            c = EventSource(MyEvent)
 
         class MyObserver(Object):
             def __init__(self, parent, key):
@@ -305,7 +305,7 @@ class TestFramework(unittest.TestCase):
                 self.my_n = snapshot["My N!"] + 1
 
         class MyNotifier(Object):
-            foo = Event(MyEvent)
+            foo = EventSource(MyEvent)
 
         class MyObserver(Object):
             def __init__(self, parent, key):
@@ -346,7 +346,7 @@ class TestFramework(unittest.TestCase):
             pass
 
         class MyEvents(EventsBase):
-            foo = Event(MyEvent)
+            foo = EventSource(MyEvent)
 
         class MyNotifier(Object):
             on = MyEvents()
@@ -375,7 +375,7 @@ class TestFramework(unittest.TestCase):
             pass
 
         class MyEvents(EventsBase):
-            foo = Event(MyEvent)
+            foo = EventSource(MyEvent)
 
         class MyNotifier(Object):
             on = MyEvents()
@@ -402,7 +402,7 @@ class TestFramework(unittest.TestCase):
         class MyEvent(EventBase):
             pass
 
-        event = Event(MyEvent)
+        event = EventSource(MyEvent)
 
         class MyEvents(EventsBase):
             foo = event
@@ -412,7 +412,7 @@ class TestFramework(unittest.TestCase):
                 foo = event
         self.assertEqual(
             str(cm.exception.__cause__),
-            "Event(MyEvent) reused as MyEvents.foo and OtherEvents.foo")
+            "EventSource(MyEvent) reused as MyEvents.foo and OtherEvents.foo")
 
         with self.assertRaises(RuntimeError) as cm:
             class MyNotifier(Object):
@@ -420,7 +420,7 @@ class TestFramework(unittest.TestCase):
                 bar = event
         self.assertEqual(
             str(cm.exception.__cause__),
-            "Event(MyEvent) reused as MyEvents.foo and MyNotifier.bar")
+            "EventSource(MyEvent) reused as MyEvents.foo and MyNotifier.bar")
 
     def test_reemit_ignores_unknown_event_type(self):
         # The event type may have been gone for good, and nobody cares,
@@ -432,7 +432,7 @@ class TestFramework(unittest.TestCase):
             pass
 
         class MyNotifier(Object):
-            foo = Event(MyEvent)
+            foo = EventSource(MyEvent)
 
         class MyObserver(Object):
             def __init__(self, parent, key):
@@ -474,11 +474,11 @@ class TestFramework(unittest.TestCase):
             pass
 
         class MyEvents(EventsBase):
-            foo = Event(MyFoo)
+            foo = EventSource(MyFoo)
 
         class MyNotifier(Object):
             on = MyEvents()
-            bar = Event(MyBar)
+            bar = EventSource(MyBar)
 
         class MyObserver(Object):
             def __init__(self, parent, key):
@@ -588,7 +588,7 @@ class TestFramework(unittest.TestCase):
                 self.value = value
 
         class MyNotifier(Object):
-            foo = Event(MyEvent)
+            foo = EventSource(MyEvent)
 
         class MyObserver(Object):
             has_deferred = False