ó
ú2ec           @   s¼   d  Z  d d l Z d d l Z d d l m Z d e j f d „  ƒ  YZ d a d a	 d „  Z
 d „  Z d „  Z e a a d	 e j f d
 „  ƒ  YZ d a d a d „  Z d „  Z d „  Z d S(   s¿  
threadedprint.py
================

:author: Ian Bicking
:date: 12 Jul 2004

Multi-threaded printing; allows the output produced via print to be
separated according to the thread.

To use this, you must install the catcher, like::

    threadedprint.install()

The installation optionally takes one of three parameters:

default
    The default destination for print statements (e.g., ``sys.stdout``).
factory
    A function that will produce the stream for a thread, given the
    thread's name.
paramwriter
    Instead of writing to a file-like stream, this function will be
    called like ``paramwriter(thread_name, text)`` for every write.

The thread name is the value returned by
``threading.current_thread().name``, a string (typically something
like Thread-N).

You can also submit file-like objects for specific threads, which will
override any of these parameters.  To do this, call ``register(stream,
[threadName])``.  ``threadName`` is optional, and if not provided the
stream will be registered for the current thread.

If no specific stream is registered for a thread, and no default has
been provided, then an error will occur when anything is written to
``sys.stdout`` (or printed).

Note: the stream's ``write`` method will be called in the thread the
text came from, so you should consider thread safety, especially if
multiple threads share the same writer.

Note: if you want access to the original standard out, use
``sys.__stdout__``.

You may also uninstall this, via::

    threadedprint.uninstall()

TODO
----

* Something with ``sys.stderr``.
* Some default handlers.  Maybe something that hooks into `logging`.
* Possibly cache the results of ``factory`` calls.  This would be a
  semantic change.

iÿÿÿÿN(   t	   filemixint   PrintCatcherc           B   s†   e  Z d
 d
 d
 e d  „ Z e j d „ Z d „  Z d „  Z	 d „  Z
 d „  Z d „  Z d „  Z d
 e j d „ Z d
 e j d	 „ Z RS(   c         C   sÏ   t  t d „  | | | g ƒ ƒ d k s3 t d ƒ ‚ | r\ | sP t d | ƒ ‚ t j } n  | rq |  j |  _ n6 | r† |  j |  _ n! | r› |  j |  _ n |  j	 |  _ | |  _
 | |  _ | |  _ i  |  _ d  S(   Nc         S   s
   |  d  k	 S(   N(   t   None(   t   x(    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyt   <lambda>G   t    i   s<   You can only provide one of default, factory, or paramwriters:   You cannot pass in both default (%r) and leave_stdout=True(   t   lent   filtert   AssertionErrort   syst   stdoutt   _writedefaultt   _defaultfunct   _writefactoryt   _writeparamt   _writeerrort   _defaultt   _factoryt   _paramwritert	   _catchers(   t   selft   defaultt   factoryt   paramwritert   leave_stdout(    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyt   __init__E   s&    	

			c         C   sR   t  ƒ  j } |  j } | j | ƒ s7 |  j | | ƒ n | | } | j | ƒ d  S(   N(   t   current_threadt   nameR   t   has_keyR   t   write(   R   t   vt   currentThreadR   t   catcherst   catcher(    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR   \   s    	
c         G   sL   t  j ƒ  j } |  j } | | k r7 |  j j | Œ  n | | j | Œ  d  S(   N(   t	   threadingR   R   R   R   t   seek(   R   t   argsR   R    (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR#   e   s
    	c         G   sL   t  j ƒ  j } |  j } | | k r7 |  j j | Œ  n | | j | Œ  d  S(   N(   R"   R   R   R   R   t   read(   R   R$   R   R    (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR%   n   s
    	c         C   s   |  j  j | ƒ d  S(   N(   R   R   (   R   R   R   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR   w   s    c         C   s   |  j  | ƒ j | ƒ d  S(   N(   R   R   (   R   R   R   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR   z   s    c         C   s   |  j  | | ƒ d  S(   N(   R   (   R   R   R   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR   }   s    c         C   s   t  s t d | ƒ ‚ d  S(   Ns8   There is no PrintCatcher output stream for the thread %r(   t   FalseR   (   R   R   R   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR   €   s    	c         C   s,   | d  k r | ƒ  j } n  | |  j | <d  S(   N(   R   R   R   (   R   R!   R   R   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyt   register…   s    c         C   sK   | d  k r | ƒ  j } n  |  j j | ƒ s= t d | ƒ ‚ |  j | =d  S(   Ns2   There is no PrintCatcher catcher for the thread %r(   R   R   R   R   R   (   R   R   R   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyt
   deregister‹   s
    N(   t   __name__t
   __module__R   R&   R   R"   R   R   R#   R%   R   R   R   R   R'   R(   (    (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR   C   s   										c          K   sK   t  s t j t  k	 rG t j a t |    a  t _ t  j a t  j a n  d  S(   N(   t   _printcatcherR	   R
   t
   _oldstdoutR   R'   R(   (   t   kw(    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyt   install–   s
    		c           C   s,   t  r( t t _ d  a  a t a t a n  d  S(   N(   R+   R,   R	   R
   R   t   not_installed_errorR'   R(   (    (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyt	   uninstallž   s
    	
c          O   s   t  s t d ƒ ‚ d  S(   NsG   threadedprint has not yet been installed (call threadedprint.install())(   R&   R   (   R$   R-   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR/   ¦   s    	t   StdinCatcherc           B   st   e  Z d d d d  „ Z d e j d „ Z d „  Z d „  Z d „  Z	 d „  Z
 d e j d „ Z d e j d „ Z RS(	   c         C   s¦   t  t d „  | | | g ƒ ƒ d k s3 t d ƒ ‚ | rH |  j |  _ n6 | r] |  j |  _ n! | rr |  j |  _ n |  j |  _ | |  _ | |  _	 | |  _
 i  |  _ d  S(   Nc         S   s
   |  d  k	 S(   N(   R   (   R   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR   °   R   i   s<   You can only provide one of default, factory, or paramwriter(   R   R   R   t   _readdefaultR   t   _readfactoryt
   _readparamt
   _readerrorR   R   R   R   (   R   R   R   R   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR   ¯   s    				c         C   sO   | ƒ  j  } |  j } | j | ƒ s4 |  j | | ƒ S| | } | j | ƒ Sd  S(   N(   R   R   R   R   R%   (   R   t   sizeR   R   R    R!   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR%   À   s    	
c         C   s   |  j  j | ƒ d  S(   N(   R   R%   (   R   R   R6   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR2   É   s    c         C   s   |  j  | ƒ j | ƒ d  S(   N(   R   R%   (   R   R   R6   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR3   Ì   s    c         C   s   |  j  | | ƒ d  S(   N(   t   _paramreader(   R   R   R6   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR4   Ï   s    c         C   s   t  s t d | ƒ ‚ d  S(   Ns8   There is no StdinCatcher output stream for the thread %r(   R&   R   (   R   R   R6   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR5   Ò   s    	c         C   s,   | d  k r | ƒ  j } n  | |  j | <d  S(   N(   R   R   R   (   R   R!   R   R   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR'   ×   s    c         C   sK   | d  k r | ƒ  j } n  |  j j | ƒ s= t d | ƒ ‚ |  j | =d  S(   Ns2   There is no StdinCatcher catcher for the thread %r(   R   R   R   R   R   (   R   R!   R   R   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR(   Ý   s
    N(   R)   R*   R   R   R"   R   R%   R2   R3   R4   R5   R'   R(   (    (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR1   ­   s   					c          K   s;   t  s7 t j a t |    a  t _ t  j a t  j a n  d  S(   N(	   t   _stdincatcherR	   t   stdint	   _oldstdinR1   R'   t   register_stdinR(   t   deregister_stdin(   R-   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyt   install_stdinè   s
    		c           C   s*   t  r& t t _ d  a  a t a a n  d  S(   N(   R8   R:   R	   R9   R   t   not_installed_error_stdinR;   R<   (    (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyt   uninstall_stdinð   s    	
c          O   s   t  s t d ƒ ‚ d  S(   NsW   threadedprint has not yet been installed for stdin (call threadedprint.install_stdin())(   R&   R   (   R$   R-   (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyR>   ÷   s    	(   t   __doc__R"   R	   t
   paste.utilR    t	   FileMixinR   R   R+   R,   R.   R0   R/   R'   R(   R1   R8   R:   R=   R?   R>   (    (    (    sB   /usr/local/lib/python2.7/dist-packages/paste/util/threadedprint.pyt   <module>=   s    P			
8		