B t `nO @sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z m Z m Z mZedZedZe e fZdZyeeZWn:ek ryddlmZWnek 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 isgeneratorismethodZnosez^[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_indentr-/tmp/pip-unpacked-wheel-cjhnoqsi/nose/util.pyls_trees rc#s dkrtg}t}|gg}} xF|D]>} t| rHq6tjtj| rj| | q6| | q6Wt t dd| Ddd|D} fdd} x6| ddD]&\} } x| | | D] }|VqWqW| r| d\} } x| | | D] }|Vq WdS)NrcSsg|] }|dfqS)Fr).0namerrr <sz"_ls_tree_lines..cSsg|] }|dfqS)Tr)rrrrrr=sc3sb|s||VnNtj|}tj|s^||Vt|}x|D]}||VqLWdS)N)ospathr islinkr )ris_dirindZ branch_indrZsubtreex)rr r rrr rrls_entry>s    z _ls_tree_lines..ls_entry) rgetcwdlistdirsortrematchrisdirr appendlist itertoolschain)r r r rrrlinesnamesdirsnondirsrentriesrrliner)rr r rrr rr )s,       r cCsJtj|s.tjtjtjt|}|dksBtj|sFdS|S)zUReturn absolute, normalized path to directory, if it exists; None otherwise. N)rrisabsnormpathabspathr rr$)rrrrabsdirSs   r2cCs|}|dkrt}t|ts(t|trPx"|D]}t||}|dk r.|Sq.WdStj|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. Nz __init__.py)rr isinstancer&tupleabsfilerr/r0r1r existsr$isfile)rwhereorigZ maybe_pathZ maybe_absinitrrrr5_s0     r5cCsx|D]}||rdSqWdS)NTFr) predicateiterableitemrrranyps r>cCs: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. z.pyr)rrr6dirnameendswithident_rer#splitext)rrrr file_likes   rCc Cs>y|jStk r8y|jjStk r2dSXYnXdS)zrGet the line number of a function. First looks for compat_co_firstlineno, then func_code.co_first_lineno. rN)Zcompat_co_firstlinenoAttributeError__code__co_firstlineno)funcrrr func_linenosrHcCst|}|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)objZobj_typerrrisclasssrMcCsttj|rptj|}t|rpx&dD]}tjtj||r(dSq(Wtj drptjtj|drpdSdS)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__.pyoTjavaz__init__$py.classF) rrr$basenamerAr#r7r sysplatform startswith)rendr:rrr ispackages     rTcCs 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 )rIproperty)rLrrr ispropertysrVcCs\|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__.pyz.py)rrrr sepsplitr6)packageZ relativeTorfilenamerrr getfilenames r\cCst|}tj|s|ds*t|s*dStjtj|\}}|dkrPg}n|g}tjtj|d\}}x8|rttj ||r| |nPtj|\}}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__rrW) srcrrr$r@rTrBrOrYr r%reverse)r[Zsrc_filebaseextZ mod_partsrpartrrr getpackages rccCsRt|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    rlcCs|d}|dd}|dkrvxJ|rhy td|td|}PWq tk rd|d=|s`Yq Xq W|dd}|}td||||x|D]}t||}qW|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 rWNz __import__ %srzresolve: %s, %s, %s, %s)rYlogdebug __import__r ImportErrorgetattr)rmodulepartsZ parts_copyrLrbrrr resolve_name)s$      rucCs<tjj}|}d}d|kr8t|r.||ddfSd|dfStj|\}}|sy$|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:rrmrzaTest name '%s' could not be parsed. Please format test names as path:callable or module:callable.) rrr0rCrY ValueErrorrgr rX)testZnormZ file_or_modfnheadtailrtZ file_partrrrsplit_test_nameFs<     r|FcCst|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 rTy t|jStk rRt|jSXt|j}y |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__rrmz%s.%srd_FunctionTestCase__testFunc _testFunc __class__) __builtin__builtinszI don't know what %s is (%s))hasattrr}rItypes ModuleTyperrr^ FunctionTyperKrPmodulesrrr1 MethodType test_address__self__rrr3unittestZTestCaserrDrZ_TestCase__testMethodNameZ_testMethodNamer TypeError)rxtfilerscallmZcls_adr method_namerrrrsN                     rc Csx|D]}t||d}|dk rt|tjkrt|tjrLt|\}}}}n`t|drft |sf|j }y t|\}}}}| dWn$t k rt d||fYnXt |rtd|||||Std|||SqWdS)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)rrrIrrr3rinspect getargspecrrrpoprrgrnro)rLr*rrGargsvarargsvarkwdefaultsrrrtry_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. NrNz $py.classrWipy)z.pycz.pyoz.py)rPrQrRr@r rrrB)r[r`rarrrr^sr^csfdd}|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)Nrmr)search)rL)regexrrks zregex_last_key..kr)rrr)rrregex_last_keys rcCsZ|dkr dSy|g|Stk r.YnXy td|Stk rTt|SXdS)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*)extendrDr"rYrr&)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||dS)N)_keyssuperrr])selfargkw)rrrr]szodict.__init__cs tt|||j|dS)N)rr __delitem__rremove)rkey)rrrr!szodict.__delitem__cs,tt|||||jkr(|j|dS)N)rr __setitem__rr%)rrr=)rrrr%s zodict.__setitem__cCs ddddt|DS)Nz{%s}z, cSsg|]\}}d||fqS)z%r: %rr)rrvrrrr+sz!odict.__str__..)r r&items)rrrr__str__*sz odict.__str__cstt|g|_dS)N)rrclearr)r)rrrr-sz odict.clearcs"tt|}|jdd|_|S)N)rrcopyr)rd)rrrr1sz odict.copycCstt|jt|S)N)r&ziprvalues)rrrrr6sz odict.itemscCs|jddS)N)r)rrrrkeys9sz odict.keysNcs,tt|||}||jkr(|j||S)N)rr setdefaultrr%)rrfailobjr=)rrrr<s  zodict.setdefaultcs@tt||x*t|D]}||jkr|j|qWdS)N)rrupdater&rrr%)rdictr)rrrrBs z odict.updatecCstt|j|jS)N)r&mapgetr)rrrrrHsz odict.values)N)rr __qualname____doc__r]rrrrrrrrrr __classcell__rr)rrrs      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?sx||D] }|Vq WdS)Nr)rrr)rGrrnewfuncgsz transplant_func..newfunccs ||S)Nr)rr)rGrrrks)Z nose.toolsrrr)rGrsrrr)rGrtransplant_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)clsrsrrrrtransplant_classssrutf-8csNyt|Stk rHt|tr:dfdd|DSt|SXdS)N csg|]}t|qSr)safe_str)rr)encodingrrrszsafe_str..)strUnicodeEncodeErrorr3 Exceptionr encode)rrr)rrrs  rcCs6tj|sdSt|}t|jtjtjBtjB@S)NF) rrr6statboolst_modeS_IXUSRS_IXGRPS_IXOTH)rstrrr is_executables  r__main__)N)N)N)r)9rrr'loggingrrr"rPrrZnose.pyversionrrrr getLoggerrncompilerArJr set NameErrorZsetsrrqrr r2r5r>rCrHrMZ is_generatorrTrVr\rcrlrur|Z__test__rrr^rrrrrrrrrdoctesttestmodrrrrsp   * !    1 <1!4'