³ò
3ÒÇIc           @   sÝ   d  Z  d Z d d d g Z d d k Z d d k Z y e Wn# e j
 o d d k l Z n Xd „  Z	 d d	 „ Z d
 „  Z d „  Z d „  Z d „  Z d „  Z e d „  ƒ Z e d j o d d k Z e i ƒ  n d S(   s  
Decorator module by Michele Simionato <michelesimionato@libero.it>
Copyright Michele Simionato, distributed under the terms of the BSD License (see below).
http://www.phyast.pitt.edu/~micheles/python/documentation.html

Included in NLTK for its support of a nice memoization decorator.
s   restructuredtext ent	   decoratort   new_wrappert   getinfoiÿÿÿÿN(   t   Setc         C   sø   t  i |  ƒ p t  i |  ƒ p t ‚ t  i |  ƒ \ } } } } t | ƒ } | o | i | ƒ n | o | i | ƒ n t  i | | | | d d „  ƒd d !} t d |  i	 d | d | d |  i
 d	 |  i d
 |  i d |  i d |  i d |  i ƒ 	S(   so  
    Returns an info dictionary containing:
    - name (the name of the function : str)
    - argnames (the names of the arguments : list)
    - defaults (the values of the default arguments : tuple)
    - signature (the signature : str)
    - doc (the docstring : str)
    - module (the module name : str)
    - dict (the function __dict__ : str)
    
    >>> def f(self, x=1, y=2, *args, **kw): pass

    >>> info = getinfo(f)

    >>> info["name"]
    'f'
    >>> info["argnames"]
    ['self', 'x', 'y', 'args', 'kw']
    
    >>> info["defaults"]
    (1, 2)

    >>> info["signature"]
    'self, x, y, *args, **kw'
    t   formatvaluec         S   s   d  S(   t    (    (   t   value(    (    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyt   <lambda>:   s    i   iÿÿÿÿt   namet   argnamest	   signaturet   defaultst   doct   modulet   dictt   globalst   closure(   t   inspectt   ismethodt
   isfunctiont   AssertionErrort
   getargspect   listt   appendt   formatargspecR   t   __name__t   func_defaultst   __doc__t
   __module__t   __dict__t   func_globalst   func_closure(   t   funct   regargst   varargst	   varkwargsR   R	   R
   (    (    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyR      s    'c         C   sv   | p
 t  | ƒ } y | d |  _ Wn n X| d |  _ | d |  _ |  i i | d ƒ | d |  _ | |  _ |  S(   NR   R   R   R   R   (   R   R   R   R   R   t   updateR   t   undecorated(   t   wrappert   modelt   infodict(    (    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyt   update_wrapperA   s    	c         C   ss   t  | t ƒ o
 | } n t | ƒ } d | d j p
 t d ‚ d | } t | t d |  ƒ ƒ } t | | | ƒ S(   sB  
    An improvement over functools.update_wrapper. The wrapper is a generic
    callable object. It works by generating a copy of the wrapper with the 
    right signature and by updating the copy, not the original.
    Moreovoer, 'model' can be a dictionary with keys 'name', 'doc', 'module',
    'dict', 'defaults'.
    t	   _wrapper_R	   s(   "_wrapper_" is a reserved argument name!s.   lambda %(signature)s: _wrapper_(%(signature)s)(   t
   isinstanceR   R   R   t   evalR)   (   R&   R'   R(   t   srct   funcopy(    (    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyR   N   s    

c            s   t  ‡  ‡ f d †  ˆ ƒ S(   Nc             s   ˆ  i  ˆ |  | Ž S(    (   t   call(   t   at   k(   t   selfR    (    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyR   b   s    (   R   (   R2   R    (    (   R2   R    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyt   __call__a   s    c         C   sY   t  t |  ƒ ƒ } d | j o t d ƒ ‚ n d | j o t d ƒ ‚ n t |  _ |  S(   sí   
    Take a class with a ``.caller`` method and return a callable decorator
    object. It works by adding a suitable __call__ method to the class;
    it raises a TypeError if the class already has a nontrivial __call__
    method.
    R3   s=   You cannot decorate a class with a nontrivial __call__ methodR/   s2   You cannot decorate a class without a .call method(   t   sett   dirt	   TypeErrorR3   (   t   clst   attrs(    (    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyt   decorator_factoryd   s    	c            s:   t  i ˆ  ƒ o t ˆ  ƒ Sn ‡  f d †  } t | ˆ  ƒ S(   sù  
    General purpose decorator factory: takes a caller function as
    input and returns a decorator with the same attributes.
    A caller function is any function like this::

     def caller(func, *args, **kw):
         # do something
         return func(*args, **kw)
    
    Here is an example of usage:

    >>> @decorator
    ... def chatty(f, *args, **kw):
    ...     print "Calling %r" % f.__name__
    ...     return f(*args, **kw)

    >>> chatty.__name__
    'chatty'
    
    >>> @chatty
    ... def f(): pass
    ...
    >>> f()
    Calling 'f'

    decorator can also take in input a class with a .caller method; in this
    case it converts the class into a factory of callable decorator objects.
    See the documentation for an example.
    c            ss   t  |  ƒ } | d } d | j p
 d | j p
 t d ‚ d | } t | t d |  d ˆ  ƒ ƒ } t | |  | ƒ S(   NR	   t   _call_t   _func_s2   You cannot use _call_ or _func_ as argument names!s3   lambda %(signature)s: _call_(_func_, %(signature)s)(   R   R   R,   R   R)   (   R    R(   R	   R-   t   dec_func(   t   caller(    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyt
   _decorator•   s    

(   R   t   isclassR9   R)   (   R=   R>   (    (   R=   s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyR    u   s    	c         C   sH   y t  |  | ƒ SWn0 t j
 o$ | ƒ  } t |  | | ƒ | Sn Xd S(   s'   Similar to .setdefault in dictionaries.N(   t   getattrt   AttributeErrort   setattr(   t   objR   t   default_thunkt   default(    (    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyt   getattr_    s    	c         G   sI   t  |  d t ƒ } | | j o | | Sn |  | Œ  } | | | <| Sd  S(   Nt   memoize_dic(   RF   R   (   R    t   argst   dict   result(    (    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pyt   memoize©   s    
t   __main__(   R   t   __docformat__t   __all__R   t   sysR4   t	   NameErrort   setsR   R   t   NoneR)   R   R3   R9   R    RF   RK   R   t   doctestt   testmod(    (    (    s%   /p/zhu/06/nlp/nltk/nltk/decorators.pys   <module>   s"   	)				+		