ó
a#nSc           @   sŠ   d  Z  d d l Z d d l Z e e j d ƒ ƒ Z e j e j e g Z d „  Z	 d e
 f d „  ƒ  YZ d e
 f d „  ƒ  YZ d	 „  Z d S(
   s‚    Provides a Logger class which can be wrapped around another
             python class to log method calls and attribute changes.
iÿÿÿÿNs   f*c         C   sS   xL | D]D } t  | ƒ t k r; | j |  ƒ d k	 rK d Sq |  | k r d Sq Wd S(   sw   checks to see if any of the regular expressions in a list match a string

   **Arguments**

     - what: the thing to match against

     - checkList: the list of regexps to try the match with

   **Returns**

     1 or 0 depending upon whether or not _what_ was found in checkList

   **Notes**

     - the search is done using _match_, so we match *any* part of _what_

  i   i    N(   t   typet   reTypet   matcht   None(   t   whatt	   checkListt   entry(    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyt	   isPresent   s    t   Callablec           B   s    e  Z d  Z d „  Z d „  Z RS(   sz    this is just a simple class with a __call__ method we'll use to pass
      any method invocations back to the caller.

  c         C   s   | |  _  | |  _ | |  _ d S(   s/   Constructor
    
      **Arguments:**

        - log: a python list (or anything else supporting the append method)
             which is used to log the actual invocation of a method

        - obj: the object which is calling the method

        - method: the *name* of the method to be invoked

    N(   t   _objt   _logt   _method(   t   selft   logt   objt   method(    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyt   __init__>   s    		c         O   s8   |  j  j |  j | | f ƒ t |  j |  j ƒ | | Ž  S(   s<    logs the method name and arguments and makes the call

    (   R
   t   appendR   t   getattrR	   (   R   t   argst   kwargs(    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyt   __call__N   s    (   t   __name__t
   __module__t   __doc__R   R   (    (    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyR   9   s   	t   Loggerc           B   s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   s   This is the actual wrapper class.

    The wrapper is fairly thin; it only has one methods of its own:

      - _LoggerGetLog()

    and then several instance variables:

      - _loggerFlushCommand

      - _loggerClass

      - _loggerObj

      - _loggerCommandLog

      - _loggerIgnore

    These names were chosen to minimize the likelihood of a collision
     with the attributes of a wrapped class.  Obviously... ;-)

    The general idea of using this is that you wrap a class in the logger,
      and then use the class as you normally would.  Whenever you want to 
      get the contents of the log (for example after running your program for
      a while), you can call _loggerCommandLog.  The resulting list can be
      played back in another (or the same) object using the replay() function
      defined below.

    The logger can, optionally, be set to flush its log whenever a method with
      a particular name is invoked.  For example, you may want to be wrapping
      some kind of drawing canvas and want to reset the log whenever the canvas
      is cleared because there's no point in storing commands which will have
      no effect on the final drawing.

    **Note**

      because of the way I've worked this, the log will actually be flushed
      whenever the client program accesses the flush method, it need not be invoked.
      i.e. if the loggerFlushCommand is 'foo', then doing either wrappedObj.foo() or
      wrappedObj.foo will reset the log.  This is undesirable and will most likely
      be fixed in a future version

  c         O   s×   | j  d ƒ r* | d |  j d <| d =n d	 |  j d <| j  d ƒ r– | d } x, | D]$ } t | ƒ t k rW t d ‚ qW qW W| |  j d <| d =n g  |  j d <| |  j d <| | | Ž  |  j d <g  |  j d <d	 S(
   sµ    Constructor

      **Arguments**
      
        The one required argument here is _klass_, which is the class
        to be wrapped.

      **Optional Keyword Arguments**

        - loggerFlushCommand: the name of the attribute which will flush the log

        - loggerIgnore: a list of regexps defining methods which should not be
          logged

      **All other arguments are passed to the constructor for _klass_ **
      
    t   loggerFlushCommandt   _loggerFlushCommandt   loggerIgnores=   All entries in loggerIgnore must be either strings or regexpst   _loggerIgnoret   _loggerClasst
   _loggerObjt   _loggerCommandLogN(   t   has_keyt   __dict__R   R    t   stringTypest
   ValueError(   R   t   klassR   R   t   tempLR   (    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyR   �   s    


c         C   s   |  j  S(   s?    Returns the contents of the command log as a python list

    (   R    (   R   (    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyt   _LoggerGetLog¥   s    c         C   sç   t  |  j | ƒ r¾ t |  j | ƒ } t | ƒ t j k r· |  j } | | k rj g  |  _ t g  |  j | ƒ S|  j	 g  k rž t
 | |  j	 ƒ rž t g  |  j | ƒ St |  j |  j | ƒ Sqã | Sn% t d t |  j j ƒ t | ƒ f ‚ d S(   sA    here's where the logging of method invocations takes place

    s   %s instance has no attribute %sN(   t   hasattrR   R   R    t   typest
   MethodTypeR   R    R   R   R   t   AttributeErrort   reprR   R   (   R   t   whicht   tmpAttrR   (    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyt   __getattr__«   s    		!c         C   sY   |  j  } | j | ƒ r% | | | <n0 |  j j t | | f ƒ t |  j | | ƒ | Sd S(   sA    setattr calls (i.e. wrappedObject.foo = 1) are also logged

    N(   R"   R!   R    R   t   setattrR   (   R   R-   t   valt   d(    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyt   __setattr__¿   s    	(   R   R   R   R   R'   R/   R3   (    (    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyR   U   s
   +	$		c         C   s¾   t  |  t ƒ r |  j ƒ  }  n  g  } x“ |  D]‹ \ } } } t | ƒ rŽ | t k rr | | | | ƒ | j | ƒ q¶ | j | | | | ƒ ƒ q+ t | | ƒ } | j t | | | ƒ ƒ q+ W| S(   s·   loops through the items in a Logger log list and invokes
     them in obj

    **Arguments**

      - logItems: a list of 3 tuples containing:

         1) method name

         2) tuple of positional arguments

         3) dictionary of keyword arguments

      - obj: the object in which the log should be replayed  

    **Returns**

      a list with the the return values of all the method
      invocations/attribute assignments

  (   t
   isinstanceR   R'   t   callableR0   R   R   t   apply(   t   logItemsR   t   resListR   t   a1t   a2t   a(    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyt   replayË   s    (   R   R)   t   reR    t   compileR   t
   StringTypet   UnicodeTypeR#   R   t   objectR   R   R<   (    (    (    sU   /public2/ftp/pub/ccp4/6.5/ccp4-6.5/lib/python2.7/site-packages/rdkit/Logger/Logger.pyt   <module>   s   	v