B
    Ր<[nO                 @   s  d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZmZmZmZ edZedZeefZdZye  eZW n: ek
r   yddlmZ W n ek
r   Y nX Y nX ded	d
ddfddZdd Zdd ZdBddZdd Zdd Zdd Z dd Z!eZ"dd Z#dd  Z$dCd!d"Z%d#d$ Z&d%d& Z'dDd'd(Z(d)d* Z)d+e)_*d,d- Z+d+e+_*d.d/ Z,d0d1 Z-d2d3 Z.d4d5 Z/G d6d7 d7e0Z1d8d9 Z2d:d; Z3dEd=d>Z4d?d@ Z5e6dAkrddl7Z7e78  dS )Fz7Utility functions and classes used by nose internally.
    N)	ClassTypeTypeTypeisgeneratorismethodZnosez^[A-Za-z_][A-Za-z0-9_.]*$zE(?:\.svn)|(?:[^.]+\.py[co])|(?:.*~)|(?:.*\$py\.class)|(?:__pycache__))Set z|-- z|   z`-- z    c          	   C   s   d t| |||||S )N
)join_ls_tree_lines)dir_pathskip_patternindentbranch_indentlast_indentlast_branch_indent r   (lib/python3.7/site-packages/nose/util.pyls_tree   s    
r   c             #   s   dkrt  g }t }|  g g  }}	xF|D ]>}
t|
rHq6t jt j|
rj|	|
 q6|		|
 q6W t
tdd |	D dd |D } fdd}x6|d d D ]&\}
}x||
| D ]
}|V  qW qW |r|d \}
}x||
|D ]}|V  qW d S )Nr   c             S   s   g | ]}|d fqS )Fr   ).0namer   r   r   
<listcomp><   s    z"_ls_tree_lines.<locals>.<listcomp>c             S   s   g | ]}|d fqS )Tr   )r   r   r   r   r   r   =   s    c             3   sb   |s||  V  nNt j| }t j|s^||  V  t| }x|D ]}|| V  qLW d S )N)ospathr	   islinkr
   )r   is_dirZindZ
branch_indr   Zsubtreex)r   r   r   r   r   r   r   r   ls_entry>   s    

z _ls_tree_lines.<locals>.ls_entry)r   getcwdlistdirsortrematchr   isdirr	   appendlist	itertoolschain)r   r   r   r   r   r   linesnamesdirsnondirsr   entriesr   r   liner   )r   r   r   r   r   r   r   r
   )   s,    


r
   c             C   sJ   t j| s.t jt jt jt  | } | dksBt j| sFdS | S )zUReturn absolute, normalized path to directory, if it exists; None
    otherwise.
    N)r   r   isabsnormpathabspathr	   r   r#   )r   r   r   r   absdirS   s    
r1   c             C   s  | }|dkrt  }t|ts(t|trPx"|D ]}t| |}|dk	r.|S q.W dS t j| szt jt j	t j
|| } | dkst j| s|t  krt jt j	t j
t  |} | dkst j| sdS t j| rt j
| d}t j|r|S nt j| r| S dS )zReturn absolute, normalized path to file (optionally in directory
    where), or None if the file can't be found either in where or the current
    working directory.
    Nz__init__.py)r   r   
isinstancer%   tupleabsfiler   r.   r/   r0   r	   existsr#   isfile)r   whereZorigZ
maybe_pathZ	maybe_absinitr   r   r   r4   _   s0    


r4   c             C   s   x|D ]}| |rdS qW dS )NTFr   )Z	predicateiterableitemr   r   r   anyp   s    
r;   c             C   s:   t j| p8t j| p8| dp8tt j| d  S )zA name is file-like if it is a path that exists, or it has a
    directory part, or it ends in .py, or it isn't a legal python
    identifier.
    z.pyr   )r   r   r5   dirnameendswithident_rer"   splitext)r   r   r   r   	file_like   s    
r@   c             C   s>   y| j S  tk
r8   y| jjS  tk
r2   dS X Y nX dS )zrGet the line number of a function. First looks for
    compat_co_firstlineno, then func_code.co_first_lineno.
    r   N)Zcompat_co_firstlinenoAttributeError__code__co_firstlineno)funcr   r   r   func_lineno   s    rE   c             C   s   t | }|tkpt|t S )z|Is obj a class? Inspect's isclass is too liberal and returns True
    for objects that can't be subclasses of anything.
    )typeclass_types
issubclass)objZobj_typer   r   r   isclass   s    rJ   c             C   st   t j| rpt j| }t|rpx&dD ]}t jt j| |r(dS q(W tj	
drpt jt j| drpdS dS )z
    Is this path a package directory?

    >>> ispackage('nose')
    True
    >>> ispackage('unit_tests')
    False
    >>> ispackage('nose/plugins')
    True
    >>> ispackage('nose/loader.py')
    False
    )z__init__.pyz__init__.pycz__init__.pyoTjavaz__init__$py.classF)r   r   r#   basenamer>   r"   r6   r	   sysplatform
startswith)r   endr8   r   r   r   	ispackage   s    

rQ   c             C   s   t | tkS )a  
    Is this a property?

    >>> class Foo:
    ...     def got(self):
    ...         return 2
    ...     def get(self):
    ...         return 1
    ...     get = property(get)

    >>> isproperty(Foo.got)
    False
    >>> isproperty(Foo.get)
    True
    )rF   property)rI   r   r   r   
isproperty   s    rS   c             C   s\   |dkrt  }t j|t j| d}t j|d r@|S |d }t j|rX|S dS )zFind the python source file for a package, relative to a
    particular directory (defaults to current working directory if not
    given).
    N.z/__init__.pyz.py)r   r   r   r	   sepsplitr5   )packageZ
relativeTor   filenamer   r   r   getfilename   s    rY   c             C   s   t | }tj|s|ds*t|s*dS tjtj|\}}|dkrPg }n|g}tjtj|d \}}x8|rttj	||r|
| nP tj|\}}qtW |  d	|S )a  
    Find the full dotted package name for a given python source file
    name. Returns None if the file is not a python source file.

    >>> getpackage('foo.py')
    'foo'
    >>> getpackage('biff/baf.py')
    'baf'
    >>> getpackage('nose/util.py')
    'nose.util'

    Works for directories too.

    >>> getpackage('nose')
    'nose'
    >>> getpackage('nose/plugins')
    'nose.plugins'

    And __init__ files stuck onto directories

    >>> getpackage('nose/plugins/__init__.py')
    'nose.plugins'

    Absolute paths also work.

    >>> path = os.path.abspath(os.path.join('nose', 'plugins'))
    >>> getpackage(path)
    'nose.plugins'
    z.pyN__init__r   rT   )srcr   r   r#   r=   rQ   r?   rL   rV   r	   r$   reverse)rX   Zsrc_filebaseextZ	mod_partsr   partr   r   r   
getpackage   s    r`   c             C   sR   t | d }d| d }dd| | d| f }dt | }|dkrN|d|  }|S )zDraw a 70-char-wide divider, with label in the middle.

    >>> ln('hello there')
    '---------------------------- hello there -----------------------------'
       F   z%s %s %s-r   )len)ZlabelZ	label_lenchunkoutZpadr   r   r   ln  s    rg   c             C   s   |  d}|dd }|dkrvxJ|rhy td|  td|}P W q  tk
rd   |d= |s` Y q X q W |dd }|}td|| || x|D ]}t||}qW |S )a8  Resolve a dotted name to a module and its parts. This is stolen
    wholesale from unittest.TestLoader.loadTestByName.

    >>> resolve_name('nose.util') #doctest: +ELLIPSIS
    <module 'nose.util' from...>
    >>> resolve_name('nose.util.resolve_name') #doctest: +ELLIPSIS
    <function resolve_name at...>
    rT   Nz__import__ %sr      zresolve: %s, %s, %s, %s)rV   logdebug
__import__r	   ImportErrorgetattr)r   modulepartsZ
parts_copyrI   r_   r   r   r   resolve_name)  s$    	

rp   c             C   s<  t jj}| }d}d| kr8t| r.|| ddfS d| dfS t j| \}}|sy$| d\}}t|rn| d }}W nZ tk
r   | d}t|d dkrd|dd |d  }}ntd| f Y nX n6|s| }n,d|kr|d\}}n|}t j||g}|r.t|r"||d|fS d||fS n
dd|fS dS )a3  Split a test name into a 3-tuple containing file, module, and callable
    names, any of which (but not all) may be blank.

    Test names are in the form:

    file_or_module:callable

    Either side of the : may be dotted. To change the splitting behavior, you
    can alter nose.util.split_test_re.
    N:r   rh   r   zaTest name '%s' could not be parsed. Please format test names as path:callable or module:callable.)	r   r   r/   r@   rV   
ValueErrorrd   r	   rU   )testZnormZfile_or_modfnheadtailro   Z	file_partr   r   r   split_test_nameF  s<    


rw   Fc             C   s  t | dr|  S t| }d } }}|tjkrVt| dd}t| dd}t|||fS |tjksrt|tsr|tkrt| dd}|dk	rt	j
| }t|dd}|dk	rtj|}t| dd}t|||fS |tjkrt| jj}t|d |d d|d	 | jf fS t| tjrt | d
s,t | drTy
t| jS  tk
rR   t| jS X t| j}y
| j}W n tk
r   | j}Y nX t|d |d d|d	 |f fS t | dr| jjdkrt| jS td| |f dS )zfFind the test address for a test, which may be a module, filename,
    class, method or function.
    addressN__file____name__
__module__r   rh   z%s.%sra   _FunctionTestCase__testFunc	_testFunc	__class__)Z__builtin__builtinszI don't know what %s is (%s))hasattrrx   rF   types
ModuleTyperm   r[   FunctionTyperH   rM   modulesr   r   r0   
MethodTypetest_address__self__r~   rz   r2   unittestZTestCaser|   rA   r}   Z_TestCase__testMethodNameZ_testMethodNamer{   	TypeError)rs   tfilern   ZcallmZcls_adrZmethod_namer   r   r   r     sN    






r   c          	   C   s   x|D ]}t | |d}|dk	rt| tjkrt|tjrLt|\}}}}n`t|drft	|sf|j
}y t|\}}}}|d W n$ tk
r   td|| f Y nX t|rtd| ||  || S td| | | S qW dS )zGiven a list of possible method names, try to run them with the
    provided object. Keep going until something works. Used to run
    setup/teardown methods for module, package, and function tests.
    N__call__r   zaAttribute %s of %r is not a python function. Only functions or callables may be used as fixtures.zcall fixture %s.%s(%s)zcall fixture %s.%s)rm   rF   r   r   r2   r   inspectZ
getargspecr   r   r   popr   rd   ri   rj   )rI   r)   r   rD   argsZvarargsZvarkwdefaultsr   r   r   try_run  s&    
r   c             C   sb   | dkr| S t jdr8| dr8d| dd dfS tj| \}}|dkr^d|dfS | S )zFind the python source file for a .pyc, .pyo or $py.class file on
    jython. Returns the filename provided if it is not a python source
    file.
    NrK   z	$py.classrT   ipy)z.pycz.pyoz.py)rM   rN   rO   r=   r	   r   r   r?   )rX   r]   r^   r   r   r   r[     s    r[   c                s    fdd}|S )a  Sort key function factory that puts items that match a
    regular expression last.

    >>> from nose.config import Config
    >>> from nose.pyversion import sort_list
    >>> c = Config()
    >>> regex = c.testMatch
    >>> entries = ['.', '..', 'a_test', 'src', 'lib', 'test', 'foo.py']
    >>> sort_list(entries, regex_last_key(regex))
    >>> entries
    ['.', '..', 'foo.py', 'lib', 'src', 'a_test', 'test']
    c                s     | rd| fS d| fS )Nrh   r   )search)rI   )regexr   r   k  s    
zregex_last_key.<locals>.kr   )r   r   r   )r   r   regex_last_key  s    r   c             C   sZ   | dkrdS y|  g  | S  tk
r.   Y nX ytd| S  tk
rT   t| S X dS )aw  Convert a value that may be a list or a (possibly comma-separated)
    string into a list. The exception: None is returned as None, not [None].

    >>> tolist(["one", "two"])
    ['one', 'two']
    >>> tolist("hello")
    ['hello']
    >>> tolist("separate,values, with, commas,  spaces , are    ,ok")
    ['separate', 'values', 'with', 'commas', 'spaces', 'are', 'ok']
    Nz\s*,\s*)extendrA   r!   rV   r   r%   )valr   r   r   tolist  s    
r   c                   s   e Zd ZdZ fddZ fddZ fddZdd	 Z fd
dZ fddZ	dd Z
dd Zd fdd	Z fddZdd Z  ZS )odictzvSimple ordered dict implementation, based on:

    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747
    c                s   g | _ tt| j|| d S )N)_keyssuperr   rZ   )selfargkw)r~   r   r   rZ     s    zodict.__init__c                s    t t| | | j| d S )N)r   r   __delitem__r   remove)r   key)r~   r   r   r   !  s    zodict.__delitem__c                s,   t t| || || jkr(| j| d S )N)r   r   __setitem__r   r$   )r   r   r:   )r~   r   r   r   %  s    
zodict.__setitem__c             C   s    dd dd t|  D  S )Nz{%s}z, c             S   s   g | ]\}}d ||f qS )z%r: %rr   )r   r   vr   r   r   r   +  s    z!odict.__str__.<locals>.<listcomp>)r	   r%   items)r   r   r   r   __str__*  s    zodict.__str__c                s   t t|   g | _d S )N)r   r   clearr   )r   )r~   r   r   r   -  s    zodict.clearc                s"   t t|  }| jd d  |_|S )N)r   r   copyr   )r   d)r~   r   r   r   1  s    z
odict.copyc             C   s   t t| jt |  S )N)r%   zipr   values)r   r   r   r   r   6  s    zodict.itemsc             C   s   | j d d  S )N)r   )r   r   r   r   keys9  s    z
odict.keysNc                s,   t t| ||}|| jkr(| j| |S )N)r   r   
setdefaultr   r$   )r   r   Zfailobjr:   )r~   r   r   r   <  s    
zodict.setdefaultc                s@   t t| | x*t| D ]}|| jkr| j| qW d S )N)r   r   updater%   r   r   r$   )r   dictr   )r~   r   r   r   B  s    
zodict.updatec             C   s   t t| j| jS )N)r%   mapgetr   )r   r   r   r   r   H  s    zodict.values)N)rz   r{   __qualname____doc__rZ   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   )r~   r   r     s   r   c                sD   ddl m} t r" fdd}n fdd}| |}||_|S )a  
    Make a function imported from module A appear as if it is located
    in module B.

    >>> from pprint import pprint
    >>> pprint.__module__
    'pprint'
    >>> pp = transplant_func(pprint, __name__)
    >>> pp.__module__
    'nose.util'

    The original function is not modified.

    >>> pprint.__module__
    'pprint'

    Calling the transplanted function calls the original.

    >>> pp([1, 2])
    [1, 2]
    >>> pprint([1,2])
    [1, 2]

    r   )make_decoratorc              ?   s   x | |D ]
}|V  qW d S )Nr   )r   r   r   )rD   r   r   newfuncg  s    z transplant_func.<locals>.newfuncc                 s
    | |S )Nr   )r   r   )rD   r   r   r   k  s    )Z
nose.toolsr   r   r{   )rD   rn   r   r   r   )rD   r   transplant_funcL  s    r   c             C   s"   G dd d| }||_ | j|_|S )aB  
    Make a class appear to reside in `module`, rather than the module in which
    it is actually defined.

    >>> from nose.failure import Failure
    >>> Failure.__module__
    'nose.failure'
    >>> Nf = transplant_class(Failure, __name__)
    >>> Nf.__module__
    'nose.util'
    >>> Nf.__name__
    'Failure'

    c               @   s   e Zd ZdS )ztransplant_class.<locals>.CN)rz   r{   r   r   r   r   r   C  s   r   )r{   rz   )clsrn   r   r   r   r   transplant_classs  s    r   utf-8c                sN   yt | S  tk
rH   t| tr:d fdd| D S t |  S X d S )N c                s   g | ]}t | qS r   )safe_str)r   r   )encodingr   r   r     s   zsafe_str.<locals>.<listcomp>)strUnicodeEncodeErrorr2   	Exceptionr	   encode)r   r   r   )r   r   r     s    

r   c             C   s6   t j| sdS t | }t|jtjtjB tjB @ S )NF)	r   r   r5   statboolst_modeS_IXUSRS_IXGRPS_IXOTH)r   str   r   r   is_executable  s    
r   __main__)N)N)N)r   )9r   r   r&   Zloggingr   r   r!   rM   r   r   Znose.pyversionr   r   r   r   Z	getLoggerri   compiler>   rG   r   set	NameErrorZsetsr   rl   r   r
   r1   r4   r;   r@   rE   rJ   Zis_generatorrQ   rS   rY   r`   rg   rp   rw   Z__test__r   r   r[   r   r   r   r   r   r   r   r   rz   ZdoctestZtestmodr   r   r   r   <module>   sp   

*
!	
1
<1!4'


