dL iBdZddlZddlmcmZddlZddlZddl Z ddl Z ddl m Z ddl mZddlmZddlZddlmZddlmZdd lmZerdd lmZe j0d e j2Zd Zd ZdZGddej<ZdZ dZ!ejDddZ#GddZ$GddZ%ejLdZ'ejLdZ(dZ)y)zCoverage plugin for pytest.N)StringIO)Path) TYPE_CHECKING)CovDisabledWarning)CovReportWarning)PytestCovWarning) CovController2unclosed database in z'StoreReport.__call__..MsRQqI(((Rs)r7all_validate_markdown_dest_files)selfparserr:r option_stringr!files ` r$__call__zStoreReport.__call__Fsg" T,0 [) 9 9dl0=I  - R2QR R  . .y/C/CV L Sr&c\|d}|d}||k(rd|d}|dz }|j|yy)NrrzEmarkdown and markdown-append options cannot point to the same file: 'z'.zR Please redirect one of them using :DEST (e.g. --cov-report=markdown:dest_file.md))error)r>cov_report_optionsr? markdown_filemarkdown_append_file error_messages r$r=z)StoreReport._validate_markdown_dest_filesPsN*:6 12CD 0 0cdqcrrtuM q qM LL ' 1r&r6)__name__ __module__ __qualname__rBr=r&r$r3r3Es M(r&r3c 2|jdd}|jddgddddd |jd d gdd |jdtidtd|jddddd|jdddd|jdddd|jd dd!td"#|jd$ddd%|jd&dd'd(|jd)t d'd*+|jd,dd-t d.#y')/z Add options to control coverage.covz3coverage reporting with distributed testing support--covappendSOURCE?T cov_sourcezPath or package name to measure during execution (multi-allowed). Use --cov= to not do any source filtering and record everything.)actiondefaultmetavarnargsconstdesthelpz --cov-reset store_constz1Reset cov sources accumulated in options so far. )rTrXrYrZz --cov-reportTYPEacType of report to generate: term, term-missing, annotate, html, xml, json, markdown, markdown-append, lcov (multi-allowed). term, term-missing may be followed by ":skip-covered". annotate, html, xml, json, markdown, markdown-append and lcov may be followed by ":DEST" where DEST specifies the output location. Use --cov-report= to not generate any output.)rTrUrVtyperZz --cov-configstorez .coveragercPATHz.Config file for coverage. Default: .coveragerc)rTrUrVrZz--no-cov-on-fail store_trueFz8Do not report coverage if test run fails. Default: False)rTrUrZ--no-covzIDisable coverage report completely (useful for debuggers). Default: Falsez--cov-fail-underMINz,Fail if the total coverage is less than MIN.)rTrVr]rZz --cov-appendz$>?""++FF;4r&c,eZdZdZddej fdZddedfdZd Z d Z e jd d Z e jd d ZdZe jddZdZdZe jddZy)rrzUse coverage package to produce code coverage reports. Delegates all work to a particular implementation based on whether this test process is centralised, a distributed master or a distributed worker. Trwcd|_d|_t|_d|_d|_d|_d|_d|_||_ d|_ t|ddxst|ddxst|dddk7}t|ddrd|_y|jjsd g|j_nKt|jjd k(r)d |jjvri|j_t|jj|j_d d lm}|r|r|j#|j$y|r|j#|j&yy) zCreates a coverage pytest plugin. We read the rc file that coverage uses to get the data file name. This is needed since we give coverage through it's API the data file name. NF numprocessesdistloaddistnorxTrrrengine)pidcov_controllerrr7 cov_totalfailed_started _start_path _disabledrw_wrote_headinggetattrrrjrSrrstart DistMasterCentral)r>rwrsrrois_distrs r$__init__zCovPlugin.__init__sN""*   #'>59KWWjZ_=`Kdklsu{~BeCGKeK 7He ,!DN ||&&'-hDLL # (( )Q .29P9P3P&(DLL #"5dll6M6M"N   u JJv(( )  JJv~~ &r&Ncontroller_clsr c|Gfdd}|}|j||_jjd_t j _jjj}jj't|dr|jj_ jjt|ddj_ yy)Nc(eZdZWjZy)CovPlugin.start..ConfigN)rIrJrKrwoption)r>sr$Configrs r&rT fail_under precisionr)rwrrrrcwdrrNconfigcov_fail_underhasattrr cov_precisionr)r>rrnodeidr cov_configs` r$rzCovPlugin.starts > & &XF,T\\66J !!# 88:((,,33 << & & .7:|3T*4*?*?DLL ' << % % -)0[!)LDLL & .r&c4t|jddduS)N workerinput)rr)r>sessions r$ _is_workerzCovPlugin._is_workersw~~}d;4GGr&cD|jjrd|_yddlm}t j |_|j|rX|jjjd|j}|j|j|j|n'|js|j|j |jj"dk(r:|jj$j't)|j*dyy)zAAt session start determine our implementation and delegate to it.TNrrworkeridr0 _cov_contexts)rwrxrrrosgetpidrrrrgetrr DistWorkerrr cov_contextrsrtTestContextPluginr)r>rrrs r$pytest_sessionstartzCovPlugin.pytest_sessionstarts <<  !DN  99; ??7 #^^//33JOF JJv(('..& A JJv~~ & << # #v - NN ( ( 1 12CDDWDW2XZi j .r&) optionalhookcT|js|jj|yyzlDelegate to our implementation. Mark this hook as optional in case xdist is not installed. N)rrconfigure_node)r>nodes r$pytest_configure_nodezCovPlugin.pytest_configure_node)s$ ~~    . .t 4r&cV|js|jj||yyr)rr testnodedown)r>rrDs r$pytest_testnodedownzCovPlugin.pytest_testnodedown2s& ~~    , ,T5 9r&c|jjxs|jj}|xr%|jxr|jj Sr6)rwr7rrno_cov_on_fail)r>neededs r$_should_reportzCovPlugin._should_report;sA((GDLL,G,GKt{{Jt||/J/JKKr&)wrapperc#NK|jrdStjD]\}}}}}|tus|tk(sntj ddttjD]\}}}}}|t usntjdt ddlm }tjD]\}}}}}||usntjd|d}t|j|_ |j|jj|j|s|j!rddlm}ddlm}ddlm}  |jj-|j.|_|j0} d} | | u} | st?j@d| fd| | fdtCjDvst?jF|rt?jH|ndt?jH| t?jH| dz}t?jJddzd|iz}tMt?jN|dx} x} } |jPjR}|jPjT}||jPjVry| |j0||rudjY||j0|||}|j2j4j7d j9d|d d d |xjdz c_ |S#|$rs} d | d }|j2j4j7d j9d |d d d tj:t=|dd|_Yd} ~  d} ~ wwxYww)NrUr oncer)CoverageWarning)CoverageException)display_covered)should_fail_underzFailed to generate report:  terminalreporterz WARNING: Tredboldr stacklevel)is not)z5%(py2)s {%(py2)s = %(py0)s.cov_total } is not %(py5)sr>)py0py2py5z$Test coverage should never be `None`z >assert %(py7)spy7zMCoverage failure: total of {total} is less than fail-under={fail_under:.{p}f})totalrpz ERROR: )-rwarningsfiltersResourceWarningCOVERAGE_SQLITE_WARNING_REfilterwarningsr simplefiltercoverage.exceptionsrbool testsfailedrrfinishrr coverage.miscrcoverage.resultsrrsummaryr7rrrs getpluginwritewarnr @pytest_ar_call_reprcompare @py_builtinslocals_should_repr_global_name _saferepr_format_assertmsgAssertionError_format_explanationrwrr collectonlyformat)r>r_messagecategoryrresultrrrexc @py_assert1 @py_assert4 @py_assert3 @py_format6 @py_format8rrs r$pytest_runtestloopzCovPlugin.pytest_runtestloopAs  >>N+3*:*: v &Aw!Q?*w:T/T v  # #I/cet u$,$4$4 < Aq(Aq++ <  ! !&*: ;7$,$4$4 ; Aq(Aq?* ;  ! !&/ :7../    *    & & (w'D,?,?,A 8 8 : #!%!4!4!> U U>- U U U> U U U U U U4 U U U4 U U U> U U U U U U/U U U U U U U U!\\88N LL66M%)A)A Oipp)$..-H-#q ,,667IJPPS\]d\eegQhnry}P~##q(# )% #7uB?,,667IJPPS^_f^ggiQjpt{PA .w7AF!"  #sI2N% N%?N%?AN%BN%*L*=F-N%*N"/A(NN%N""N%cP|js|jddd|_yy)N=ztests coverageT)r write_sep)r>rs r$ write_headingzCovPlugin.write_heading~s)""  & &s,< ="&D #r&c |jrb|jjrK|j|d}|j d|dddt j t|dy|jy|jy|jj}|r"|j||j ||jj|jjdkDr|j||j|jjk}|rdddnd di}d j|jj|j|rd nd |rd nd}|j|fi|yyy)Nz&Coverage disabled via --no-cov switch!z WARNING: rTrrrrgreenzU{fail}Required test coverage of {required}% {reached}. Total coverage: {actual:.2f}% zFAIL rz not reachedreached)requiredactualfailr)rrwrorrrrrrrr7getvaluerr)r>rrreportrmarkups r$pytest_terminal_summaryz!CovPlugin.pytest_terminal_summarysa >>||..""#34B &&7)2'>Dt&T 09aH     &  >> ! ))+    / 0  " "6 * << & & 2t||7R7RUV7V   / 0^^dll&A&AAF4:T40$Fnuu44~~ &WB)/ Y vG #  " "7 5f 58W 2r&) hookwrapperc#K|jdsdt|ddvr9|jjd|jj ydyw)Nno_cover fixturenamesrL)get_closest_markerrrpauseresumer>items r$pytest_runtest_callzCovPlugin.pytest_runtest_callsO  " ": .*n^`@a2a    % % '     & & ( sAA!)TF)NN)rIrJrK__doc__r Namespacerr]rrrpytesthookimplrrrrrrr rLr&r$rrrrs&' 2 2&'TMD$9M$Hk,V__$'5(5V__$':(:L V__T":#:x' 6BV__&'r&rrc6eZdZUded<dZdZdZdZdZy) rr rc||_yr6)r)r>rs r$rzTestContextPlugin.__init__s ,r&c(|j|dy)Nsetupswitch_contextr s r$pytest_runtest_setupz&TestContextPlugin.pytest_runtest_setups D'*r&c(|j|dy)Nteardownrr s r$pytest_runtest_teardownz)TestContextPlugin.pytest_runtest_teardowns D*-r&c(|j|dy)Nrunrr s r$r z%TestContextPlugin.pytest_runtest_calls D%(r&c|jjr5|jjj|jd|yy)N|)rstartedrNrr)r>r whens r$rz TestContextPlugin.switch_contexts?    & &    # # 2 2dkk]!D63J K 'r&N) rIrJrK__annotations__rrrr rrLr&r$rrs"##-+.)Lr&rcy)z%A pytest fixture to disable coverage.NrLrLr&r$rrsr&c|jjjdrG|jjjd}|jr|jj Sy)zEA pytest fixture to provide access to the underlying coverage object.rmN)rrs haspluginrrrN)requestrys r$rNrNsT ~~##--f5--77?  ((,, , r&c(|jddy)Nmarkersz)no_cover: disable coverage for this test.)addinivalue_line)rs r$pytest_configurer*s I'RSr&)*rbuiltinsr_pytest.assertion.rewrite assertionrewriterrrreriorpathlibrtypingrrrrrr rr compileIrr%r.r1Actionr3rgrjrrzrrrfixturerrNr*rLr&r$r7s!  %'RZZ(\^`^b^bc2  ((//((Up]$ <  < __DLL(00Tr&