U
    ZenO                     @   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ze  eZW n: ek
r   z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ismethod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   h/mounts/lovelace/software/anaconda3/envs/qiime2-amplicon-2024.2/lib/python3.8/site-packages/nose/util.pyls_tree   s    
  r   c                 #   s  dkrt  g }t }|  g g  }}	|D ]>}
t|
rFq4t jt j|
rh|	|
 q4|		|
 q4t
tdd |	D dd |D } fdd}|d d D ]"\}
}||
| D ]
}|V  qq|r|d \}
}||
|D ]}|V   qd 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   =   s     c                 3   s^   |s||  V  nJt j| }t j|sZ||  V  t| }|D ]}|| V  qJd S N)ospathr
   islinkr   )r   is_dir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   )   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    r6   c                 C   s  | }|dkrt  }t|ts(t|trP|D ]}t| |}|dk	r,|  S q,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.
    N__init__.py)r   r#   
isinstancer*   tupleabsfiler   r3   r4   r5   r
   existsr(   isfile)r   whereorigZ
maybe_pathZ	maybe_absinitr   r   r   r:   _   s2    

r:   c                 C   s   |D ]}| |r dS qdS )NTFr   )	predicateiterableitemr   r   r   anyp   s    rC   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.
    .pyr   )r   r   r;   dirnameendswithident_rer'   splitext)r   r   r   r   	file_like   s    
rI   c                 C   sJ   z| j W S  tk
rD   z| jjW  Y S  tk
r>   Y Y 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    rO   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)objobj_typer   r   r   isclass   s    rU   c                 C   sr   t j| rnt j| }t|rndD ] }t jt j| |r& dS q&tj	
drnt jt j| drnd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
    )r7   z__init__.pycz__init__.pyoTjavaz__init__$py.classF)r   r   r(   basenamerG   r'   r<   r
   sysplatform
startswith)r   endr?   r   r   r   	ispackage   s    
r\   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
    )rP   propertyrS   r   r   r   
isproperty   s    r_   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__.pyrD   )r   r#   r   r
   sepsplitr;   )packageZ
relativeTor   filenamer   r   r   getfilename   s    re   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 \}}|rttj	||r|
| nqtj|\}}qr|  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'
    rD   N__init__r   r`   )srcr   r   r(   rF   r\   rH   rW   rb   r
   r)   reverse)rd   Zsrc_filebaseextZ	mod_partsr   partr   r   r   
getpackage   s    rl   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)labelZ	label_lenchunkoutpadr   r   r   ln  s    ru   c                 C   s   |  d}|dd }|dkrt|rhz"td|  td|}W qhW q tk
rd   |d= |s` Y qX q|dd }|}td|| || |D ]}t||}q|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...>
    r`   Nz__import__ %sr"      zresolve: %s, %s, %s, %s)rb   logdebug
__import__r
   ImportErrorgetattr)r   modulepartsZ
parts_copyrS   rk   r   r   r   resolve_name)  s$    	

r~   c                 C   s<  t jj}| }d}d| kr8t| r.|| ddfS d| dfS t j| \}}|sz$| 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   rv   r"   zaTest name '%s' could not be parsed. Please format test names as path:callable or module:callable.)	r   r   r4   rI   rb   
ValueErrorrp   r
   ra   )testZnormZfile_or_modfnheadtailr}   Z	file_partr   r   r   split_test_nameF  s>    


r   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rZzt| jW S  tk
rX   t| j Y S X t| j}z
| 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   rv   z%s.%srm   _FunctionTestCase__testFunc	_testFunc	__class__)__builtin__builtinszI don't know what %s is (%s))hasattrr   rP   types
ModuleTyper{   rg   FunctionTyperR   rX   modulesr   r   r5   
MethodTypetest_address__self__r   r   r8   unittestZTestCaser   rJ   r   Z_TestCase__testMethodNameZ_testMethodNamer   	TypeError)r   tfiler|   callmZcls_adrmethod_namer   r   r   r     sV    






r   c              	   C   s   |D ]}t | |d}|dk	rt| tjkrt|tjrJt|\}}}}n`t|drdt	|sd|j
}z t|\}}}}|d W n$ tk
r   td|| f Y nX t|rtd| ||  ||   S td| | |   S q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)r{   rP   r   r   r8   r   inspect
getargspecr   r   r   popr   rp   rw   rx   )rS   r.   r   rN   argsvarargs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.
    NrV   z	$py.classr`   ipy)z.pycz.pyorD   )rX   rY   rZ   rF   r
   r   r   rH   )rd   ri   rj   r   r   r   rg     s    rg   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 )Nrv   r   )searchr^   regexr   r   k  s    
zregex_last_key.<locals>.kr   )r   r   r   r   r   regex_last_key  s    r   c                 C   sb   | dkrdS z|  g  | W S  tk
r0   Y nX ztd| W S  tk
r\   t|  Y 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*)extendrJ   r&   rb   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 r   )_keyssuperr   rf   )selfargkwr   r   r   rf     s    zodict.__init__c                    s    t t| | | j| d S r   )r   r   __delitem__r   remove)r   keyr   r   r   r   !  s    zodict.__delitem__c                    s,   t t| || || jkr(| j| d S r   )r   r   __setitem__r   r)   )r   r   rB   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 r   )r   r   clearr   r   r   r   r   r   -  s    zodict.clearc                    s"   t t|  }| jd d  |_|S r   )r   r   copyr   )r   dr   r   r   r   1  s    z
odict.copyc                 C   s   t t| jt |  S r   )r*   zipr   valuesr   r   r   r   r   6  s    zodict.itemsc                 C   s   | j d d  S r   )r   r   r   r   r   keys9  s    z
odict.keysNc                    s,   t t| ||}|| jkr(| j| |S r   )r   r   
setdefaultr   r)   )r   r   failobjrB   r   r   r   r   <  s    
zodict.setdefaultc                    s<   t t| | t| D ]}|| jkr| j| qd S r   )r   r   updater*   r   r   r)   )r   dictr   r   r   r   r   B  s    
zodict.updatec                 C   s   t t| j| jS r   )r*   mapgetr   r   r   r   r   r   H  s    zodict.values)N)r   r   __qualname____doc__rf   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    | |D ]
}|V  q
d S r   r   )r   r   r   rM   r   r   newfuncg  s    z transplant_func.<locals>.newfuncc                     s
    | |S r   r   )r   r   rM   r   r   r   k  s    )Z
nose.toolsr   r   r   )rN   r|   r   r   r   rM   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)r   r   r   r   r   r   r   C  s   r   )r   r   )clsr|   r   r   r   r   transplant_classs  s    r   utf-8c                    sX   z
t | W S  tk
rR   t| tr@d fdd| D  Y S t |   Y 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UnicodeEncodeErrorr8   	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   r;   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+   loggingr   r   r&   rX   r   r   Znose.pyversionr   r   r   r   	getLoggerrw   compilerG   rQ   r   set	NameErrorZsetsr   rz   r   r   r6   r:   rC   rI   rO   rU   Zis_generatorr\   r_   re   rl   ru   r~   r   Z__test__r   r   rg   r   r   r   r   r   r   r   r   r   doctesttestmodr   r   r   r   <module>   sv   

  

*
!	
1
<1!4'


