This module implements an aspect weaver.
It provides mainly two things:
Typical use:
Define aspect classes in some modules. For example:
Module myaspect1.py:
from libutilitaspy.aspects import Aspect
class MyAspect1(Aspect):
classes = 'SomeClass[0-9]+' # a regular expression defining the (names of the) classes to which this aspect will be applied
methods = 'some_method' # a regular expression defining the (names of the) methods to which this aspect will be applied
def before(self, klass, method, obj, *args, **kwargs):
print "(aspect1) before"
# do something...
def after(self, klass, method, obj, retval, exc_type, exc_val, traceback):
print "(aspect1) after"
# do something...
Module myaspect2.py:
from libutilitaspy.aspects import Aspect
class MyAspect2(Aspect):
classes = 'SomeClass[0-9]+' # a regular expression
methods = '.*_method' # a regular expression
def before(self, klass, method, obj, *args, **kwargs):
print "(aspect2) before"
# do something...
def after(self, klass, method, obj, retval, exc_type, exc_val, traceback):
print "(aspect2) after"
# do something...
Now, you create the aspect weaver which is a metaclass, as follows:
Module metaclassconfig.py:
from libutilitaspy.aspects.core import WeaverMetaClassFactory
from myaspect1 import MyAspect1
from myaspect2 import MyAspect2
MyMetaClass = WeaverMetaClassFactory(MyAspect1(), MyAspect2())
Note
The order of aspects matters; the aspects are applied from left-to-right, with left being the most deeply nested (the innermost)
Also note that the weaver expects instances of aspect classes.
Now, each class which may be affected by aspects, should declare its meta-class to be the aspect weaver. For example:
Module someclass1.py:
from metaclassconfig import MyMetaClass
class SomeClass1(object):
__metaclass__ = MyMetaClass
def some_method(self):
# ...
pass
def some_other_method(self):
# ...
pass
Here, MyAspect1 will be applied only to SomeClass1.some_method, while both MyAspect1 and MyAspect2 will be applied, in that order to both methods of SomeClass1
An aspect class defines a pointcut (the set of joinpoints where the aspect is to be applied, and advice methods before and after to be executed before (resp. after) the joinpoint.
The pointcut is specified by defining the following class attributes:
In a future version, the following will be supported as well:
Each of these class attributes is a regular expression (see http://docs.python.org/library/re.html). Together they determine the classes and methods where the aspect is to be applied.
Note
This is an abstract class, meant to be subclassed by concrete aspects.
Performs some actions before the execution of the method.
Parameters: |
|
---|---|
Returns: |
|
Performs some actions after the execution of the method.
Parameters: |
|
---|---|
Returns: |
|
This factory function produces a meta-class which weaves the given aspects in all classes which are instances of the meta-class.
Parameters: | aspects – a sequence of Aspect instances |
---|---|
Returns: | An aspect weaver meta-class (to be assigned to the __metaclass__ attribute of the client classes. |
Makes an Aspect class from a given generator. The idea is that whatever comes in the generator function before a yield becomes the before part of the aspect, and whatever comes after the yield becomes the after part of the aspect.
Parameters: | generator (GeneratorType) – some generator (typycally a generator function). |
---|---|
Returns: | An aspect with before and after methods |
Return type: | Aspect |