U enO @sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z m Z m Z mZedZedZe e fZdZzeeZWn:ek rzddlmZWnek rYnXYnXded d d d fd dZddZddZdBddZddZddZddZ ddZ!e Z"ddZ#dd 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,d0d1Z-d2d3Z.d4d5Z/Gd6d7d7e0Z1d8d9Z2d:d;Z3dEd=d>Z4d?d@Z5e6dAkrddl7Z7e78dS)Fz7Utility functions and classes used by nose internally. N) ClassTypeTypeType isgeneratorismethodnosez^[A-Za-z_][A-Za-z0-9_.]*$zE(?:\.svn)|(?:[^.]+\.py[co])|(?:.*~)|(?:.*\$py\.class)|(?:__pycache__))Setz|-- z| z`-- z c Csdt||||||S)N )join_ls_tree_lines)dir_path skip_patternindent branch_indent last_indentlast_branch_indentr7/opt/hc_python/lib/python3.8/site-packages/nose/util.pyls_trees  rc#sdkrtg}t}|gg}} |D]>} t| rFq4tjtj| rh| | q4| | q4t t dd| Ddd|D} fdd} | ddD]"\} } | | | D] }|Vqq| r | d\} } | | | D] }|VqdS)NrcSsg|] }|dfqS)Fr.0namerrr <sz"_ls_tree_lines..cSsg|] }|dfqS)Trrrrrr=sc3s^|s||VnJtj|}tj|sZ||Vt|}|D]}||VqJdSN)ospathr islinkr )ris_dirindZ branch_indrZsubtreexrr rrrr rrls_entry>s   z _ls_tree_lines..ls_entry) rgetcwdlistdirsortrematchrisdirr appendlist itertoolschain)r r rrrrlinesnamesdirsnondirsrentriesr!rlinerr rr )s.         r cCsJtj|s.tjtjtjt|}|dksBtj|sFdS|S)zUReturn absolute, normalized path to directory, if it exists; None otherwise. N)rrisabsnormpathabspathr r#r()rrrrabsdirSs r6cCs|}|dkrt}t|ts(t|trP|D]}t||}|dk r,|Sq,dStj|sztjtj tj ||}|dkstj |s|tkrtjtj tj t|}|dkstj |sdStj |rtj |d}tj |r|Sntj |r|SdS)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)rr# isinstancer*tupleabsfilerr3r4r5r existsr(isfile)rwhereorigZ maybe_pathZ maybe_absinitrrrr:_s2    r:cCs|D]}||rdSqdS)NTFr) predicateiterableitemrrranypsrCcCs:tj|p8tj|p8|dp8ttj|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)rrr;dirnameendswithident_rer'splitext)rrrr file_likes  rIc CsJz|jWStk rDz|jjWYStk r>YYdSXYnXdS)zrGet the line number of a function. First looks for compat_co_firstlineno, then func_code.co_first_lineno. r"N)Zcompat_co_firstlinenoAttributeError__code__co_firstlinenofuncrrr func_linenosrOcCst|}|tkpt|tS)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)objobj_typerrrisclasssrUcCsrtj|rntj|}t|rndD] }tjtj||r&dSq&tj drntjtj|drndSdS)z Is this path a package directory? >>> ispackage('nose') True >>> ispackage('unit_tests') False >>> ispackage('nose/plugins') True >>> ispackage('nose/loader.py') False )r7z __init__.pycz __init__.pyoTjavaz__init__$py.classF) rrr(basenamerGr'r<r sysplatform startswith)rendr?rrr ispackages    r\cCs t|tkS)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 )rPpropertyrSrrr ispropertysr_cCs\|dkrt}tj|tj|d}tj|dr@|S|d}tj|rX|SdS)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)rr#rr sepsplitr;)packageZ relativeTorfilenamerrr getfilenames recCst|}tj|s|ds*t|s*dStjtj|\}}|dkrPg}n|g}tjtj|d\}}|rttj ||r| |nqtj|\}}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' rDN__init__rr`) srcrrr(rFr\rHrWrbr r)reverse)rdZsrc_filebaseextZ mod_partsrpartrrr getpackages rlcCsRt|d}d|d}dd||d|f}dt|}|dkrN|d|}|S)zDraw a 70-char-wide divider, with label in the middle. >>> ln('hello there') '---------------------------- hello there -----------------------------' Fz%s %s %s-r)len)labelZ label_lenchunkoutpadrrrlns    rucCs|d}|dd}|dkrt|rhz"td|td|}WqhWqtk rd|d=|s`YqXq|dd}|}td|||||D]}t||}q|S)a8Resolve a dotted name to a module and its parts. This is stolen wholesale from unittest.TestLoader.loadTestByName. >>> resolve_name('nose.util') #doctest: +ELLIPSIS >>> resolve_name('nose.util.resolve_name') #doctest: +ELLIPSIS r`Nz __import__ %sr"zresolve: %s, %s, %s, %s)rblogdebug __import__r ImportErrorgetattr)rmodulepartsZ parts_copyrSrkrrr resolve_name)s$      r~cCs<tjj}|}d}d|kr8t|r.||ddfSd|dfStj|\}}|sz$|d\}}t|rn|d}}WnZtk r|d}t|ddkrd|dd|d}}ntd|fYnXn6|s|}n,d|kr|d\}}n|}tj||g}|r.t|r"||d|fSd||fSn dd|fSdS)a3Split 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:rrvr"zaTest name '%s' could not be parsed. Please format test names as path:callable or module:callable.) rrr4rIrb ValueErrorrpr ra)testZnormZ file_or_modfnheadtailr}Z file_partrrrsplit_test_nameFs>     rFcCst|dr|St|}d}}}|tjkrVt|dd}t|dd}t|||fS|tjksrt|tsr|tkrt|dd}|dk rt j |}t|dd}|dk rt j |}t|dd}t|||fS|tjkrt|jj}t|d|dd|d |jffSt|tjrt|d s,t|d rZz t|jWStk rXt|jYSXt|j}z |j}Wntk r|j}YnXt|d|dd|d |ffSt|d r|jjd krt|jStd||fdS)zfFind the test address for a test, which may be a module, filename, class, method or function. addressN__file____name__ __module__rrvz%s.%srm_FunctionTestCase__testFunc _testFunc __class__) __builtin__builtinszI don't know what %s is (%s))hasattrrrPtypes ModuleTyper{rg FunctionTyperRrXmodulesrrr5 MethodType test_address__self__rrr8unittestZTestCaserrJrZ_TestCase__testMethodNameZ_testMethodNamer TypeError)rtfiler|callmZcls_adr method_namerrrrsV                    rc Cs|D]}t||d}|dk rt|tjkrt|tjrJt|\}}}}n`t|drdt |sd|j }z t|\}}}}| dWn$t k rt d||fYnXt |rtd|||||Std|||SqdS)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__rzaAttribute %s of %r is not a python function. Only functions or callables may be used as fixtures.zcall fixture %s.%s(%s)zcall fixture %s.%s)r{rPrrr8rinspect getargspecrrrpoprrprwrx)rSr.rrNargsvarargsvarkwdefaultsrrrtry_runs,      rcCsb|dkr |Stjdr8|dr8d|dddfStj|\}}|dkr^d|dfS|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. NrVz $py.classr`ipy)z.pycz.pyorD)rXrYrZrFr rrrH)rdrirjrrrrgsrgcsfdd}|S)aSort 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'] cs|rd|fSd|fS)Nrvr)searchr^regexrrks zregex_last_key..kr)rrrrrregex_last_keys rcCsb|dkr dSz|g|WStk r0YnXztd|WStk r\t|YSXdS)awConvert 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*)extendrJr&rbrr*)valrrrtolists  rcseZdZdZfddZfddZfddZdd Zfd d Zfd d Z ddZ ddZ dfdd Z fddZ ddZZS)odictzvSimple ordered dict implementation, based on: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747 csg|_tt|j||dSr)_keyssuperrrf)selfargkwrrrrfszodict.__init__cs tt|||j|dSr)rr __delitem__rremove)rkeyrrrr!szodict.__delitem__cs,tt|||||jkr(|j|dSr)rr __setitem__rr))rrrBrrrr%s zodict.__setitem__cCs ddddt|DS)Nz{%s}z, cSsg|]\}}d||fqS)z%r: %rr)rrvrrrr+sz!odict.__str__..)r r*itemsrrrr__str__*sz odict.__str__cstt|g|_dSr)rrclearrrrrrr-sz odict.clearcs"tt|}|jdd|_|Sr)rrcopyr)rdrrrr1sz odict.copycCstt|jt|Sr)r*ziprvaluesrrrrr6sz odict.itemscCs|jddSr)rrrrrkeys9sz odict.keysNcs,tt|||}||jkr(|j||Sr)rr setdefaultrr))rrfailobjrBrrrr<s  zodict.setdefaultcs<tt||t|D]}||jkr|j|qdSr)rrupdater*rrr))rdictrrrrrBs z odict.updatecCstt|j|jSr)r*mapgetrrrrrrHsz odict.values)N)rr __qualname____doc__rfrrrrrrrrrr __classcell__rrrrrs      rcsDddlm}tr"fdd}n fdd}||}||_|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] }|Vq dSrr)rrrrMrrnewfuncgsz transplant_func..newfunccs ||Srr)rrrMrrrks)Z nose.toolsrrr)rNr|rrrrMrtransplant_funcLs   rcCs"Gddd|}||_|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 eZdZdS)ztransplant_class..CN)rrrrrrrCsr)rr)clsr|rrrrtransplant_classssrutf-8csXz t|WStk rRt|tr@dfdd|DYSt|YSXdS)N csg|]}t|qSr)safe_str)rrencodingrrrszsafe_str..)strUnicodeEncodeErrorr8 Exceptionr encode)rrrrrrs   rcCs6tj|sdSt|}t|jtjtjBtjB@S)NF) rrr;statboolst_modeS_IXUSRS_IXGRPS_IXOTH)rstrrr is_executables  r__main__)N)N)N)r)9rrr+loggingrrr&rXrrZnose.pyversionrrrr getLoggerrwcompilerGrQr set NameErrorZsetsrrzrr r6r:rCrIrOrUZ is_generatorr\r_rerlrur~rZ__test__rrrgrrrrrrrrrdoctesttestmodrrrrsv    * !    1 <1!4'