99import asyncio
1010from pydispatch .aioutils import AioWeakMethodContainer , AioEventWaiters
1111
12+ __all__ = (
13+ 'DoesNotExistError' , 'ExistsError' , 'EventExistsError' ,
14+ 'PropertyExistsError' , 'Event' , 'Dispatcher' ,
15+ )
16+
17+
18+ class DoesNotExistError (KeyError ):
19+ """Raised when binding to an :class:`Event` or :class:`~.properties.Property`
20+ that does not exist
21+
22+ .. versionadded:: 0.2.2
23+ """
24+ def __init__ (self , name ):
25+ self .name = name
26+
27+ def __str__ (self ):
28+ return f'Event "{ self .name } " not registered'
29+
30+
31+ class ExistsError (RuntimeError ):
32+ """Raised when registering an event name that already exists
33+ as either a normal :class:`Event` or :class:`~.properies.Property`
34+
35+ .. versionadded:: 0.2.2
36+ """
37+ def __init__ (self , name ):
38+ self .name = name
39+
40+ def __str__ (self ):
41+ return f'"{ self .name } " already exists'
42+
43+ class EventExistsError (ExistsError ):
44+ """Raised when registering an event name that already exists
45+ as an :class:`Event`
46+
47+ .. versionadded:: 0.2.2
48+ """
49+
50+
51+ class PropertyExistsError (ExistsError ):
52+ """Raised when registering an event name that already exists
53+ as a :class:`~.properties.Property`
54+
55+ .. versionadded:: 0.2.2
56+ """
1257
1358
1459class Event (object ):
@@ -108,10 +153,20 @@ def register_event(self, *names):
108153
109154 Args:
110155 *names (str): Name or names of the events to register
156+
157+ Raises:
158+ EventExistsError: If an event with the given name already exists
159+ PropertyExistsError: If a property with the given name already exists
160+
161+ .. versionchanged:: 0.2.2
162+ :class:`ExistsError` exceptions are raised when attempting to
163+ register an event or property that already exists
111164 """
112165 for name in names :
113166 if name in self .__events :
114- continue
167+ raise EventExistsError (name )
168+ elif name in self .__property_events :
169+ raise PropertyExistsError (name )
115170 self .__events [name ] = Event (name )
116171 def bind (self , ** kwargs ):
117172 """Subscribes to events or to :class:`~pydispatch.properties.Property` updates
@@ -164,6 +219,14 @@ class Foo(Dispatcher):
164219
165220 This can also be done using :meth:`bind_async`.
166221
222+ Raises:
223+ DoesNotExistError: If attempting to bind to an event or
224+ property that has not been registered
225+
226+ .. versionchanged:: 0.2.2
227+ :class:`DoesNotExistError` is now raised when binding to
228+ non-existent events or properties
229+
167230 .. versionadded:: 0.1.0
168231
169232 """
@@ -174,7 +237,10 @@ class Foo(Dispatcher):
174237 if name in props :
175238 e = props [name ]
176239 else :
177- e = events [name ]
240+ try :
241+ e = events [name ]
242+ except KeyError :
243+ raise DoesNotExistError (name )
178244 e .add_listener (cb , __aio_loop__ = aio_loop )
179245 def unbind (self , * args ):
180246 """Unsubscribes from events or :class:`~pydispatch.properties.Property` updates
@@ -224,10 +290,21 @@ def emit(self, name, *args, **kwargs):
224290 name (str): The name of the :class:`Event` to dispatch
225291 *args (Optional): Positional arguments to be sent to listeners
226292 **kwargs (Optional): Keyword arguments to be sent to listeners
293+
294+ Raises:
295+ DoesNotExistError: If attempting to emit an event or
296+ property that has not been registered
297+
298+ .. versionchanged:: 0.2.2
299+ :class:`DoesNotExistError` is now raised if the event or property
300+ does not exist
227301 """
228302 e = self .__property_events .get (name )
229303 if e is None :
230- e = self .__events [name ]
304+ try :
305+ e = self .__events [name ]
306+ except KeyError :
307+ raise DoesNotExistError (name )
231308 return e (* args , ** kwargs )
232309 def get_dispatcher_event (self , name ):
233310 """Retrieves an Event object by name
@@ -239,11 +316,21 @@ def get_dispatcher_event(self, name):
239316 Returns:
240317 The :class:`Event` instance for the event or property definition
241318
319+ Raises:
320+ DoesNotExistError: If no event or property with the given name exists
321+
322+ .. versionchanged:: 0.2.2
323+ :class:`DoesNotExistError` is now raised if the event or property
324+ does not exist
325+
242326 .. versionadded:: 0.1.0
243327 """
244328 e = self .__property_events .get (name )
245329 if e is None :
246- e = self .__events [name ]
330+ try :
331+ e = self .__events [name ]
332+ except KeyError :
333+ raise DoesNotExistError (name )
247334 return e
248335 def emission_lock (self , name ):
249336 """Holds emission of events and dispatches the last event on release
@@ -279,9 +366,14 @@ def emission_lock(self, name):
279366 The context manager is re-entrant, meaning that multiple calls to
280367 this method within nested context scopes are possible.
281368
369+ Raises:
370+ DoesNotExistError: If no event or property with the given name exists
371+
372+ .. versionchanged:: 0.2.2
373+ :class:`DoesNotExistError` is now raised if the event or property
374+ does not exist
375+
282376 .. _PEP 492: https://www.python.org/dev/peps/pep-0492/#asynchronous-context-managers-and-async-with
283377 """
284- e = self .__property_events .get (name )
285- if e is None :
286- e = self .__events [name ]
378+ e = self .get_dispatcher_event (name )
287379 return e .emission_lock
0 commit comments