ó
çiõ\c           @` s   d  Z  d d l m Z d d l m Z d d l m Z d d l Z d d l Z d d l Z d d l Z d d l	 m
 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 e f d „  ƒ  YZ e ƒ  Z d e f d „  ƒ  YZ d S(   s,    monkeypatching and mocking functionality.  i    (   t   absolute_import(   t   division(   t   print_functionN(   t   contextmanager(   t   fixture(   t   Paths   ^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, 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(    (    s2   lib/python2.7/site-packages/_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(    (    s2   lib/python2.7/site-packages/_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(    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyR   K   s    #c         C` s   t  |  t j ƒ s d |  k r5 t d |  f ƒ ‚ n  |  j d d ƒ \ } } t | ƒ } | ru t | | d | ƒn  | | f S(   NR
   s+   must be absolute import path string, not %ri   R   (   t
   isinstancet   sixt   string_typest	   TypeErrort   rsplitR   R   (   t   import_patht   raisingt   modulet   attrt   target(    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyt   derive_importpathU   s    t   Notsetc           B` s   e  Z d  „  Z RS(   c         C` s   d S(   Ns   <notset>(    (   t   self(    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyt   __repr__`   s    (   R   t
   __module__R,   (    (    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyR*   _   s   R   c           B` s•   e  Z d  Z d „  Z e d „  ƒ Z e e d „ Z e e d „ Z	 d „  Z
 e d „ Z 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+   (    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyt   __init__k   s    			c         c` s$   t  ƒ  } z	 | VWd | j ƒ  Xd S(   s  
        Context manager that returns a new :class:`MonkeyPatch` object which
        undoes any patching done inside the ``with`` block upon exit:

        .. code-block:: python

            import functools
            def test_partial(monkeypatch):
                with monkeypatch.context() as m:
                    m.setattr(functools, "partial", 3)

        Useful in situations where it is desired to undo some patches before the test ends,
        such as mocking ``stdlib`` functions that might break pytest itself if mocked (for examples
        of this see `#3290 <https://github.com/pytest-dev/pytest/issues/3290>`_.
        N(   R   R   (   R+   t   m(    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyt   contextq   s    		c         C` sî   t  } d d l } | t k r] t | t j ƒ 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(   si   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: "/")``
        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   R   t   isclasst   __dict__t   getR.   t   appendt   setattr(   R+   R(   R   t   valueR%   t   __tracebackhide__R7   t   oldval(    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyR=   ˆ   s    c         C` sá   t  } d d l } | t k rW t | t j ƒ s? t d ƒ ‚ n  t | | ƒ \ } } n  t | | ƒ s~ | rÝ t	 | ƒ ‚ qÝ n_ t
 | | t ƒ } | j | ƒ r· | j j | t ƒ } n  |  j j | | | 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.
        i    NsU   use delattr(target, name) or delattr(target) with target being a dotted import string(   R6   R7   R8   R   R    R!   R"   R)   t   hasattrR   R   R9   R:   R;   R.   R<   t   delattr(   R+   R(   R   R%   R?   R7   R@   (    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyRB   ­   s    c         C` s3   |  j  j | | | j | t ƒ f ƒ | | | <d S(   s)    Set dictionary entry ``name`` to value. N(   R/   R<   R;   R8   (   R+   t   dicR   R>   (    (    s2   lib/python2.7/site-packages/_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/   R<   R;   R8   (   R+   RC   R   R%   (    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyt   delitemÔ   s
    %c         C` s?   t  j r; t | t ƒ r; t j t j d j | ƒ ƒ ƒ n  d S(   sT   On Python 2, warn if the given environment variable name is not a native str (#4056)s,   Environment variable name {!r} should be strN(	   R    t   PY2R   R   t   warningst   warnt   pytestt   PytestWarningt   format(   R+   R   (    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyt   _warn_if_env_name_is_not_strá   s    c      
   C` s¯   t  | t ƒ s[ t j t j d j d | d | d t | ƒ j ƒ ƒ d d ƒt | ƒ } n  | rˆ | t	 j
 k rˆ | | t	 j
 | } n  |  j | ƒ |  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.sv   Value of environment variable {name} type should be str, but got {value!r} (type: {type}); converted to str implicitlyR   R>   R   t
   stackleveli   N(   R   R   RH   RI   RJ   RK   RL   R   R   t   ost   environRM   RD   (   R+   R   R>   t   prepend(    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyt   setenvê   s    	!c         C` s*   |  j  | ƒ |  j t j | d | ƒd S(   sÑ    Delete ``name`` from the environment. Raise KeyError if it does
        not exist.

        If ``raising`` is set to False, no exception will be raised if the
        environment variable is missing.
        R%   N(   RM   RF   RO   RP   (   R+   R   R%   (    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyt   delenvþ   s    c         C` s…   d d l  m } |  j d k r/ t j |  _ n  t j j d t | ƒ ƒ | t | ƒ ƒ t j d k r d d l	 m
 } | ƒ  n  d S(   s<    Prepend ``path`` to ``sys.path`` list of import locations. i    (   t   fixup_namespace_packagesi   (   t   invalidate_cachesN(   i   i   (   t   pkg_resourcesRT   R2   R0   t   syst   patht   insertR   t   version_infot	   importlibRU   (   R+   RX   RT   RU   (    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyt   syspath_prepend  s    	c         C` ss   |  j  d k r! t j ƒ  |  _  n  t | d ƒ r= | j ƒ  n2 t | t ƒ rb t j t | ƒ ƒ 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(	   R1   R0   RO   t   getcwdRA   R]   R   R   R   (   R+   RX   (    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyR]     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.   R8   R=   RB   R/   RE   R2   R0   RW   RX   R1   RO   R]   (   R+   R   R   R>   t
   dictionary(    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyR   -  s&    

N(   R   R-   t   __doc__R3   R   R5   R8   R6   R=   RB   RD   RF   RM   R0   RR   RS   R\   R]   R   (    (    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyR   g   s   	%"			
		(   Ra   t
   __future__R    R   R   RO   t   reRW   RH   t
   contextlibR   R    RJ   t   _pytest.fixturesR   t   _pytest.pathlibR   t   compilet   RE_IMPORT_ERROR_NAMER	   R   R   R)   t   objectR*   R8   R   (    (    (    s2   lib/python2.7/site-packages/_pytest/monkeypatch.pyt   <module>   s(   		
	
	