Thread: [SQL-CVS] r1178 - SQLObject/trunk/sqlobject
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: <sub...@co...> - 2005-10-31 17:46:13
|
Author: ianb Date: 2005-10-31 17:45:56 +0000 (Mon, 31 Oct 2005) New Revision: 1178 Modified: SQLObject/trunk/sqlobject/events.py Log: Some changed names for the event signals, and a few signature changes. Also some routines using PyDispatcher for handling subclassing (and listening to classes and their subclasses); actual use of these events will come about in a later commit Modified: SQLObject/trunk/sqlobject/events.py =================================================================== --- SQLObject/trunk/sqlobject/events.py 2005-10-31 17:15:43 UTC (rev 1177) +++ SQLObject/trunk/sqlobject/events.py 2005-10-31 17:45:56 UTC (rev 1178) @@ -1,4 +1,18 @@ -class Event(object): +from dispatch import dispatcher +from weakref import ref + + +subclassClones = {} + +def listen(receiver, soClass, signal, alsoSubclasses=True): + dispatcher.connect(receiver, signal=signal, sender=soClass) + weakSOClass = ref(soClass) + weakReceiver = ref(receiver) + subclassClones.setdefault(weakSOClass, []).append((weakReceiver, signal)) + +send = dispatcher.send + +class Signal(object): """ Base event for all SQLObject events. @@ -6,9 +20,9 @@ instance. """ -class ClassCreateEvent(Event): +class ClassCreateSignal(Signal): """ - Event raised before class creation. The sender is the superclass + Signal raised before class creation. The sender is the superclass (in case of multiple superclasses, the first superclass). The arguments are ``(new_class_name, bases, new_attrs, post_funcs)``. ``new_attrs`` is a dictionary and may be modified (but @@ -21,30 +35,41 @@ ``(new_class)``. """ +def _makeSubclassConnections(new_class_name, bases, new_attrs, post_funcs): + post_funcs.append(_makeSubclassConnectionsPost) + +def _makeSubclassConnectionsPost(new_class): + for cls in new_class.__bases__: + for weakReceiver, signal in subclassClones.get(cls, []): + receiver = weakReceiver() + if not receiver: + continue + dispatcher.connect(receiver, signal=signal, sender=new_class) + +dispatcher.connect(_makeSubclassConnections, signal=ClassCreateSignal) + # @@: Should there be a class reload event? This would allow modules # to be reloaded, possibly. Or it could even be folded into -# ClassCreateEvent, since anything that listens to that needs to pay +# ClassCreateSignal, since anything that listens to that needs to pay # attention to reloads (or else it is probably buggy). -class InstanceCreateEvent(Event): +class RowCreateSignal(Signal): """ Called before an instance is created, with the class as the - sender. Called with the arguments ``(varargs, kwargs, - post_funcs)``. Both ``kwargs`` and ``varargs`` may be usefully - modified (``varargs`` is converted from a tuple to a list before - calling). ``post_funcs`` is a list of callbacks, intended to have + sender. Called with the arguments ``(kwargs, post_funcs)``. + There may be a ``connection`` argument. ``kwargs``may be usefully + modified. ``post_funcs`` is a list of callbacks, intended to have functions appended to it, and are called with the arguments ``(new_instance)``. Note: this is not called when an instance is created from an - existing database row. (@@: Show the name be RowCreateEvent, or - RowInsertEvent?) + existing database row. """ # @@: An event for getting a row? But for each row, when doing a # select? For .sync, .syncUpdate, .expire? -class InstanceDestroyEvent(Event): +class RowDestroySignal(Signal): """ Called before an instance is deleted. Sender is the instance's class. Arguments are ``(instance)``. You cannot cancel the delete, @@ -52,14 +77,13 @@ delete, but also cause an uncaught exception if not expected). Note: this is not called when an instance is destroyed through - garbage collection (@@: Should this be called RowDestroyEvent or - RowDeleteEvent?) + garbage collection. @@: Should this allow ``instance`` to be a primary key, so that a row can be deleted without first fetching it? """ -class InstanceUpdateEvent(Event): +class RowUpdateSignal(Signal): """ Called when an instance is updated through a call to ``.set()``. The arguments are ``(instance, kwargs)``. ``kwargs`` can be @@ -68,45 +92,57 @@ @@: Should this also catch single-column updates? Should this only be run before updates go to the server? Should this be - called RowUpdateEvent? + called RowUpdateSignal? """ -class AddColumnEvent(Event): +class AddColumnSignal(Signal): """ Called when a column is added to a class, with arguments ``(cls, - column_name, column_definition)``. This is called *after* the - column has been added, and is called for each column after class - creation. + connection, column_name, column_definition, changeSchema, + post_funcs)``. This is called *after* the column has been added, + and is called for each column after class creation. + + post_funcs are called with ``(cls, so_column_obj)`` """ -class DeleteColumnEvent(Event): +class DeleteColumnSignal(Signal): """ Called when a column is removed from a class, with the arguments - ``(cls, column_name, column_definition)``. Like - ``AddColumnEvent`` this is called after the action has been + ``(cls, connection, column_name, so_column_obj, post_funcs)``. + Like ``AddColumnSignal`` this is called after the action has been performed, and is called for subclassing (when a column is implicitly removed by setting it to ``None``). + + post_funcs are called with ``(cls, so_column_obj)`` """ -# @@: Events for indexes and joins? These are mostly event consumers, +# @@: Signals for indexes and joins? These are mostly event consumers, # though. -class CreateTableEvent(Event): +class CreateTableSignal(Signal): """ Called when a table is created. If ``ifNotExists==True`` and the table exists, this event is not called. - Called with ``(cls, connection, post_funcs)``. ``post_funcs`` + Called with ``(cls, connection, extra_sql, post_funcs)``. + ``extra_sql`` is a list (which can be appended to) of extra SQL + statements to be run after the table is created. ``post_funcs`` functions are called with ``(cls, connection)`` after the table - has been created. + has been created. Those functions are *not* called simply when + constructing the SQL. """ -class DropTableEvent(Event): +class DropTableSignal(Signal): """ Called when a table is dropped. If ``ifExists==True`` and the table doesn't exist, this event is not called. - Called with ``(cls, connection, post_funcs)``. ``post_funcs`` - functions are called with ``(cls, connection)`` after the table - has been dropped. + Called with ``(cls, connection, extra_sql, post_funcs)``. + ``post_funcs`` functions are called with ``(cls, connection)`` + after the table has been dropped. """ + +__all__ = ['listen', 'send'] +for name, value in globals().items(): + if isinstance(value, type) and issubclass(value, Signal): + __all__.append('value') |