ó
…¾^Yc           @` sÒ   d  Z  d d l m Z m Z m Z d d l Z d d l Z d d l Z d d l m	 Z	 d d l
 m Z e j d ƒ Z e d „  ƒ Z d „  Z d	 „  Z d
 „  Z d d d „  ƒ  YZ e ƒ  Z d d d „  ƒ  YZ d S(   s,    monkeypatching and mocking functionality.  i    (   t   absolute_importt   divisiont   print_functionN(   t   _basestring(   t   fixtures   ^No module named (.*)$c          c` s   t  ƒ  }  |  V|  j ƒ  d S(   sú  The returned ``monkeypatch`` fixture provides these
    helper methods to modify objects, dictionaries or os.environ::

        monkeypatch.setattr(obj, name, value, raising=True)
        monkeypatch.delattr(obj, name, raising=True)
        monkeypatch.setitem(mapping, name, value)
        monkeypatch.delitem(obj, name, raising=True)
        monkeypatch.setenv(name, value, prepend=False)
        monkeypatch.delenv(name, value, raising=True)
        monkeypatch.syspath_prepend(path)
        monkeypatch.chdir(path)

    All modifications will be undone after the requesting
    test function or fixture has finished. The ``raising``
    parameter determines if a KeyError or AttributeError
    will be raised if the set/deletion operation has no target.
    N(   t   MonkeyPatcht   undo(   t   mpatch(    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   monkeypatch   s    	c         C` së   |  j  d ƒ } | j d ƒ } t | ƒ } xº | D]² } | d | 7} y t | | ƒ } Wq1 t k
 rk n Xq1 y t | ƒ WnQ t k
 rÐ } t | ƒ j  ƒ  d } | | k r· ‚  qÑ t d | | f ƒ ‚ n Xt | | | ƒ } q1 W| S(   Nt   .i    iÿÿÿÿs   import error in %s: %s(   t   splitt   popt
   __import__t   getattrt   AttributeErrort   ImportErrort   strt   annotated_getattr(   t   namet   partst   usedt   foundt   partt   ext   expected(    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   resolve&   s(    c         C` sM   y t  |  | ƒ }  Wn3 t k
 rH t d t |  ƒ j | | f ƒ ‚ n X|  S(   Ns#   %r object at %s has no attribute %r(   R   R   t   typet   __name__(   t   objR   t   ann(    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyR   E   s     c         C` s|   t  |  t ƒ s d |  k r2 t d |  f ƒ ‚ n  |  j d d ƒ \ } } t | ƒ } | rr t | | d | ƒn  | | f S(   NR	   s+   must be absolute import path string, not %ri   R   (   t
   isinstanceR   t	   TypeErrort   rsplitR   R   (   t   import_patht   raisingt   modulet   attrt   target(    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   derive_importpathQ   s    t   Notsetc           B` s   e  Z d  „  Z RS(   c         C` s   d S(   Ns   <notset>(    (   t   self(    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   __repr__]   s    (   R   t
   __module__R)   (    (    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyR'   \   s   R   c           B` s}   e  Z d  Z d „  Z e e d „ Z e e d „ Z d „  Z e d „ Z	 d d „ Z e d „ Z d „  Z d	 „  Z d
 „  Z RS(   sj    Object returned by the ``monkeypatch`` fixture keeping a record of setattr/item/env/syspath changes.
    c         C` s(   g  |  _  g  |  _ d  |  _ d  |  _ d  S(   N(   t   _setattrt   _setitemt   Nonet   _cwdt   _savesyspath(   R(   (    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   __init__h   s    			c         C` së   t  } d d l } | t k rZ t | t ƒ s< t d ƒ ‚ n  | } t | | ƒ \ } } n  t | | t ƒ } | r— | t k r— t d | | f ƒ ‚ n  | j	 | ƒ r¾ | j
 j | t ƒ } n  |  j j | | | f ƒ t | | | ƒ d S(   sk   Set attribute value on target, memorizing the old value.
        By default raise AttributeError if the attribute did not exist.

        For convenience you can specify a string as ``target`` which
        will be interpreted as a dotted import path, with the last part
        being the attribute name.  Example:
        ``monkeypatch.setattr("os.getcwd", lambda x: "/")``
        would set the ``getcwd`` function of the ``os`` module.

        The ``raising`` value determines if the setattr should fail
        if the attribute is not already present (defaults to True
        which means it will raise).
        i    Nsc   use setattr(target, name, value) or setattr(target, value) with target being a dotted import strings   %r has no attribute %r(   t   Truet   inspectt   notsetR   R   R   R&   R   R   t   isclasst   __dict__t   getR+   t   appendt   setattr(   R(   R%   R   t   valueR"   t   __tracebackhide__R2   t   oldval(    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyR8   n   s    c         C` s¥   t  } | t k rH t | t ƒ s0 t d ƒ ‚ n  t | | ƒ \ } } n  t | | ƒ so | r¡ t | ƒ ‚ q¡ n2 |  j j	 | | t
 | | t ƒ f ƒ t | | ƒ d S(   s   Delete attribute ``name`` from ``target``, by default raise
        AttributeError it the attribute did not previously exist.

        If no ``name`` is specified and ``target`` is a string
        it will be interpreted as a dotted import path with the
        last part being the attribute name.

        If ``raising`` is set to False, no exception will be raised if the
        attribute is missing.
        sU   use delattr(target, name) or delattr(target) with target being a dotted import stringN(   R1   R3   R   R   R   R&   t   hasattrR   R+   R7   R   t   delattr(   R(   R%   R   R"   R:   (    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyR=   ‘   s    %c         C` s3   |  j  j | | | j | t ƒ f ƒ | | | <d S(   s)    Set dictionary entry ``name`` to value. N(   R,   R7   R6   R3   (   R(   t   dicR   R9   (    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   setitem«   s    %c         C` sT   | | k r$ | rP t  | ƒ ‚ qP n, |  j j | | | j | t ƒ f ƒ | | =d S(   s¬    Delete ``name`` from dict. Raise KeyError if it doesn't exist.

        If ``raising`` is set to False, no exception will be raised if the
        key is missing.
        N(   t   KeyErrorR,   R7   R6   R3   (   R(   R>   R   R"   (    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   delitem°   s
    %c         C` sS   t  | ƒ } | r9 | t j k r9 | | t j | } n  |  j t j | | ƒ d S(   sÏ    Set environment variable ``name`` to ``value``.  If ``prepend``
        is a character, read the current environment variable value
        and prepend the ``value`` adjoined with the ``prepend`` character.N(   R   t   ost   environR?   (   R(   R   R9   t   prepend(    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   setenv½   s    c         C` s   |  j  t j | d | ƒd S(   sÎ    Delete ``name`` from the environment. Raise KeyError it does not
        exist.

        If ``raising`` is set to False, no exception will be raised if the
        environment variable is missing.
        R"   N(   RA   RB   RC   (   R(   R   R"   (    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   delenvÆ   s    c         C` s<   |  j  d k r t j |  _  n  t j j d t | ƒ ƒ d S(   s<    Prepend ``path`` to ``sys.path`` list of import locations. i    N(   R/   R-   t   syst   patht   insertR   (   R(   RH   (    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   syspath_prependÏ   s    c         C` sN   |  j  d k r! t j ƒ  |  _  n  t | d ƒ r= | j ƒ  n t j | ƒ d S(   s}    Change the current working directory to the specified path.
        Path can be a string or a py.path.local object.
        t   chdirN(   R.   R-   RB   t   getcwdR<   RK   (   R(   RH   (    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyRK   Õ   s
    c         C` s  xL t  |  j ƒ D]; \ } } } | t k	 r> t | | | ƒ q t | | ƒ q Wg  |  j (xX t  |  j ƒ D]G \ } } } | t k r¦ y | | =Wq° t k
 r¢ q° Xqi | | | <qi Wg  |  j (|  j d k	 ræ |  j t	 j
 (d |  _ n  |  j d k	 rt j |  j ƒ d |  _ n  d S(   sE   Undo previous changes.  This call consumes the
        undo stack. Calling it a second time has no effect unless
        you do more monkeypatching after the undo call.

        There is generally no need to call `undo()`, since it is
        called automatically during tear-down.

        Note that the same `monkeypatch` fixture is used across a
        single test function invocation. If `monkeypatch` is used both by
        the test function itself and one of the test fixtures,
        calling `undo()` will undo all of the changes made in
        both functions.
        N(   t   reversedR+   R3   R8   R=   R,   R@   R/   R-   RG   RH   R.   RB   RK   (   R(   R   R   R9   t
   dictionary(    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyR   à   s&    

N(   R   R*   t   __doc__R0   R3   R1   R8   R=   R?   RA   R-   RE   RF   RJ   RK   R   (    (    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyR   d   s   	#					(    (    (   RO   t
   __future__R    R   R   RB   RG   t   ret
   py.builtinR   t   _pytest.fixturesR   t   compilet   RE_IMPORT_ERROR_NAMER   R   R   R&   R'   R3   R   (    (    (    s3   /tmp/pip-build-hU8Cw8/pytest/_pytest/monkeypatch.pyt   <module>   s   				