[pypy-svn] r40812 - in pypy/dist/pypy: doc lib lib/app_test

afayolle at codespeak.net afayolle at codespeak.net
Tue Mar 20 10:52:41 CET 2007


Author: afayolle
Date: Tue Mar 20 10:52:40 2007
New Revision: 40812

Added:
   pypy/dist/pypy/doc/aspect_oriented_programming.txt   (contents, props changed)
Modified:
   pypy/dist/pypy/lib/aop.py
   pypy/dist/pypy/lib/app_test/sample_aop_code.py
Log:
short documentation on the aop module

Added: pypy/dist/pypy/doc/aspect_oriented_programming.txt
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/doc/aspect_oriented_programming.txt	Tue Mar 20 10:52:40 2007
@@ -0,0 +1,194 @@
+=======================
+Documentation of aop.py
+=======================
+
+.. contents::
+.. sectnum::
+
+Prerequisites
+=============
+
+The ``aop`` module for PyPy only requires PyPy. No special translation
+options are required, and it should work with all the backends. For
+the development of application using AOP, though, it is strongly
+advised to use a PyPy interpreter translated with the
+``--no-objspace-usepycfiles`` option, which tells the interpreter not
+to use byte-compiled modules, otherwise, you will need to manually
+remove all the ``.pyc`` files each time the aspects are modified. 
+
+Concepts
+========
+
+Aspect
+------
+
+An aspect is a representation of a
+software design concern which affects a large part of a
+program. Cross-cutting aspects are those concerns which have to be
+dealt with in a number of unrelated parts of a program, for instance,
+logging, synchronisation, persistance, security, value sharing, etc. 
+
+Advice
+------
+
+An advice is a piece of code that will be woven in a code base at
+specific join points. An aspect is usually implemented as a set of
+advices. 
+
+Static advices deal with adding declarative statements in the code,
+for instance, adding new methods to a class. Dynamic advices are about
+modifying the behaviour of the code, by adding statements to a
+method, or replacing the code of a method. 
+
+Point cut
+---------
+
+A point cut is a set of join points. 
+
+Join point
+----------
+
+A join point is a place in a code base where some advices are to be
+woven. Common join points include class definition, method or
+function definition and methode calls. 
+
+Weaving
+-------
+
+Weaving is the process of inserting an advices at a set of point
+cuts. 
+
+Implementation
+==============
+
+Overview
+--------
+
+Importing the ``aop`` module has several side effects:
+
+* an instance of ``aop.Weaver`` is created and stored in
+  ``__builtin__.__aop__``, which makes it globally available in modules
+  which will be imported later
+* this instance registers one of its methods with
+  ``parser.install_compiler_hook`` (see above)
+
+From then on, any module imported will be examined by the ``Weaver``
+instance.
+
+The code can define new aspects by using the ``Aspect`` metaclass in
+the ``aop`` module. This metaclass can register methods decorated with
+one of the advices of the ``aop`` module with the ``Weaver`` when the
+``Aspect`` is instantiated. When a module is imported, the ``Weaver``
+looks for symbols (classes, functions and methods) which are targets
+of registered aspects and weaves the aspect in the function. The
+weaving is done by mutating the AST nodes of the module. The mutation
+generally involves calling a method on the ``__aop__`` instance with a
+unique identifier. The Weaver will use this identifier at run time to
+find which advice it should execute.
+
+Aspects
+~~~~~~~
+
+Aspects are declared in classes using the ``aop.Aspect``
+metaclass. Such classes can have normal methods, and additionally
+methods decorated with an advice decorator, and aspect instances will
+be registered with the Weaver by the metaclass. These decorators take
+a ``PointCut`` as an argument to describe the join points.
+
+Advices
+-------
+
+The available advices are:
+
+* ``before``: the advice code will be woven before a dynamic join point
+* ``after``: the advice code will be woven after a dynamic join point
+* ``around``: the advice code will be woven in replacement of the
+  dynamic join  point
+* ``introduce``: the advice code will be added to a static join
+  point. 
+
+Point cuts
+----------
+
+A static point cut is created by instantiating the ``aop.PointCut``
+class, passing one, two or three arguments. Each argument is a
+regular expression which can match a package/module, a class or a
+function/method. 
+
+Point cuts can be combined using the python binary operators & and
+|, which will produce a new PointCut representing respectively the
+intersection and the union of the join points of the original point
+cuts. 
+
+A dynamic point cut can be obtained from a static point cut by calling
+one of the following methods:
+
+=================== ======================================================
+method              dynamic pointcut matching
+------------------- ------------------------------------------------------  
+pc.call()           all the places where the method or
+                    function matched by the static pointcut is called
+------------------- ------------------------------------------------------
+pc.execution()      the execution of the function or method matched by
+                    the static point cut
+------------------- ------------------------------------------------------
+pc.initialization() the initialization of the class matched by the
+                    static point cut
+------------------- ------------------------------------------------------
+pc.destruction()    the destruction of the class matched by the
+                    static point cut
+=================== ======================================================
+
+Example
+=======
+
+The following code can be used to implement a logging aspect::
+
+in file ``logging_aspect.py``::
+
+ from aop import Aspect, before, PointCut
+
+ class LoggingAspect:
+     __metaclass__=Aspect
+
+     # We weave in all methods and functions, except if the name of
+     # the method starts with an underscore
+     @before(PointCut(module='.*', klass='.*', func='[^_].*').execution())
+     def logStartMethod(self, joinpoint):
+         print 'in', joinpoint.name()
+
+
+In the startup code of the application, before all other imports::
+
+ from logging_aspect import LoggingAspect
+ log = LoggingAspect()
+
+References
+==========
+
+AOP implementations exist for a wide variety of programming languages,
+and many languages have several implementations available. A list can
+be found on the `aosd.net`_ `tools for developers`_ wiki
+page. `aosd.net`_ is also the main resource for AOP programming. 
+
+Other AOP implementations for python include:
+
+* `lightweight aop for Python`_
+* `springpython.aop`_
+* `logilab.aspects`_
+
+The apy of PyPy's ``aop`` module is strongly inspired by AspectJ_ and `AspectC++`_.
+
+.. _aosd.net: http://aosd.net/
+
+.. _tools for developers: http://aosd.net/wiki/index.php?title=Tools_for_Developers
+
+.. _logilab.aspects: http://www.logilab.org/projects/aspects
+
+.. _lightweight aop for Python: http://www.cs.tut.fi/~ask/aspects/aspects.html
+
+.. _springpython.aop: http://springpython.python-hosting.com/wiki/AspectOrientedProgramming
+
+.. _AspectJ: http://www.eclipse.org/aspectj/
+
+.. _AspectC++: http://www.aspectc.org/

Modified: pypy/dist/pypy/lib/aop.py
==============================================================================
--- pypy/dist/pypy/lib/aop.py	(original)
+++ pypy/dist/pypy/lib/aop.py	Tue Mar 20 10:52:40 2007
@@ -91,6 +91,7 @@
     def weave_at_static(self, node, tjp):
         raise NotImplementedError("abstract method")
 
+
 class around(Advice):
     """specify code to be run instead of the pointcut"""
     @log_exc

Modified: pypy/dist/pypy/lib/app_test/sample_aop_code.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/sample_aop_code.py	(original)
+++ pypy/dist/pypy/lib/app_test/sample_aop_code.py	Tue Mar 20 10:52:40 2007
@@ -1,5 +1,9 @@
 code = """
-def foo(b,c):
+def foo(b, c):
+    '''
+    pre:
+        b < c
+    '''
     print 'foo'
     a = 2
     d = bar(a)



More information about the Pypy-commit mailing list