ϪfdddZddlZddlZddlZddlZddlmZddlmZmZ ddl m Z ddl m Z ddlmZddlmZmZmZmZmZmZmZmZmZmZmZmZdd lmZdd l m!Z!dd l"m#Z#dd l$m%Z%dd l&m'Z'GddZ(Gdde'Z)Gdde'Z*Gdde%e'Z+Gdde'Z,dZ-dZ.Gdde'Z/ee ddddGd d!Z0Gd"d#Z1ee dd$ddd%d/d&Z2Gd'd(e'Z3Gd)d*e'Z4Gd+d,e'Z5Gd-d.e'Z6y#e $rdZ YwxYw)0zI Tests for Twisted's deprecation framework, L{twisted.python.deprecate}. N)normcase)catch_warnings simplefilter)invalidate_caches)Version) deprecate) DEPRECATION_WARNING_FORMAT_appendToDocstring_fullyQualifiedName_getDeprecationDocstring_getDeprecationWarningString_mutuallyExclusiveArguments_passedArgSpec_passedSignature deprecateddeprecatedKeywordParameterdeprecatedPropertygetDeprecationWarningString)FilePath)platform)deprecatedattributes)TwistedModulesMixin)SynchronousTestCaseceZdZdZdZdZy)_MockDeprecatedAttributezq Mock of L{twisted.python.deprecate._DeprecatedAttribute}. @ivar value: The value of the attribute. c||_yNvalueselfrs D/usr/lib/python3/dist-packages/twisted/python/test/test_deprecate.py__init__z!_MockDeprecatedAttribute.__init__8s  c|jS)z$ Get a known value. rr!s r"getz_MockDeprecatedAttribute.get;szzr$N)__name__ __module__ __qualname____doc__r#r'r$r"rr1s r$rc4eZdZdZdZdZdZdZdZdZ y) ModuleProxyTestsz Tests for L{twisted.python.deprecate._ModuleProxy}, which proxies access to module-level attributes, intercepting access to deprecated attributes and passing through access to normal attributes. c tjd}|jD]\}}t|||t j |S)z Create a temporary module proxy object. @param **kw: Attributes to initialise on the temporary module object @rtype: L{twistd.python.deprecate._ModuleProxy} foo)types ModuleTypeitemssetattrr _ModuleProxy)r!attrsmodkeyrs r" _makeProxyzModuleProxyTests._makeProxyIsJu%++- %JC Ce $ %%%c**r$c|jd}|j|jd|jtt |dy)z Getting a normal attribute on a L{twisted.python.deprecate._ModuleProxy} retrieves the underlying attribute's value, and raises C{AttributeError} if a non-existent attribute is accessed. hello)SOME_ATTRIBUTEDOES_NOT_EXISTN)r9assertIsr< assertRaisesAttributeErrorgetattrr!proxys r"test_getattrPassthroughz(ModuleProxyTests.test_getattrPassthroughVs= w7 e**G4 .'5:JKr$c|j}tj|d}td|d<|j |j dy)z Getting an attribute marked as being deprecated on L{twisted.python.deprecate._ModuleProxy} results in calling the deprecated wrapper's C{get} method. _deprecatedAttributes*r0N)r9object__getattribute__r assertEqualr0)r!rCrFs r"test_getattrInterceptz&ModuleProxyTests.test_getattrIntercept`sH ! & 7 7?V W'?'Ce$ B'r$c|j}|jtt|d|jtt|dy)z Private attributes of L{twisted.python.deprecate._ModuleProxy} are inaccessible when regular attribute access is used. _modulerFN)r9r?r@rArBs r"test_privateAttributesz'ModuleProxyTests.test_privateAttributesks9 ! .'5)D .'5:QRr$c|j}d|_|jtj |dd|j |jdy)z Setting attributes on L{twisted.python.deprecate._ModuleProxy} proxies them through to the wrapped module. rMN)r9rMassertNotEqualrHrIrJrBs r" test_setattrzModuleProxyTests.test_setattrtsH !  F33E9EqI *r$c|j}tj|d}|jt |dt |j d|dy)z L{twisted.python.deprecated._ModuleProxy.__repr__} produces a string containing the proxy type and a representation of the wrapped module object. rMN)r9rHrIrJreprtyper()r!rC realModules r" test_reprzModuleProxyTests.test_repr~sQ !,,UI>  e$u+*>*>)?x ~UV&WXr$N) r(r)r*r+r9rDrKrNrRrYr,r$r"r.r.Bs( +L (S+Yr$r.c.eZdZdZdZdZdZdZdZy)DeprecatedAttributeTestsz Tests for L{twisted.python.deprecate._DeprecatedAttribute} and L{twisted.python.deprecate.deprecatedModuleAttribute}, which issue warnings for deprecated module-level attributes. cttj|_tj|_tdz|_y)Nz.foo)rversionmessager(_testModuleNamer&s r"setUpzDeprecatedAttributeTests.setUps)+33 +33 '&0r$cttjdz|ztjtdztj zS)zJ Create the warning string used by deprecated attributes. .z: )r rr(r]r r^)r!attrs r"_getWarningStringz*DeprecatedAttributeTests._getWarningStringsA, ) )C /$ 6 ( ( & -0D0L0L L  r$cd}tt|dtjt||j|j |j j|fd}||j|jg}|j|ddt|j |dd|j||j t|dy) z L{twisted.python.deprecate._DeprecatedAttribute} correctly sets its __name__ to match that of the deprecated attribute and emits a warning when the original attribute value is accessed. ANOTHER_DEPRECATED_ATTRIBUTErGc&jyr)r')rcsr" addStackLevelzNDeprecatedAttributeTests.test_deprecatedAttributeHelper..addStackLevels HHJr$rcategoryr^rPN)r4rr_DeprecatedAttributer]r^rJr( flushWarningstest_deprecatedAttributeHelperr>DeprecationWarningrdlen)r!namerh warningsShownrcs @r"rlz7DeprecatedAttributeTests.test_deprecatedAttributeHelpers .$dB/-- $ dll  -  **D,O,O+PQ  mA&z24FG q))4d6L6LT6RS ]+Q/r$ctj|j|jg}|j t |dd}t t||j|jg}|j t |d|j|ddt|j |dd|j|y)a L{twisted.python.deprecate.deprecatedModuleAttribute} wraps a module-level attribute in an object that emits a deprecation warning when it is accessed the first time only, while leaving other unrelated attributes alone. rDEPRECATED_ATTRIBUTErPrir^N) rANOTHER_ATTRIBUTErktest_deprecatedAttributerJrnrAr>rmrd)r!rpros r"rtz1DeprecatedAttributeTests.test_deprecatedAttributes ..**D,I,I+JK  ]+Q/% $d+**D,I,I+JK  ]+Q/ mA&z24FG q))4d6L6LT6RSr$cttjdxtj|j<}|j tjj |jt|ddt|ddtjtddddd |jdtj|j}|j||tjtddddd |jd|j|tj|jy ) z Deprecating an attribute in a module replaces and wraps that module instance, in C{sys.modules}, with a L{twisted.python.deprecate._ModuleProxy} instance but only if it hasn't already been wrapped. r0firstrPsecondTwistedrr^N) r1r2sysmodulesr_ addCleanuppopr4rdeprecatedModuleAttributerrQr>)r!r7rCs r"test_wrappedModulez+DeprecatedAttributeTests.test_wrappedModules382B2B52II D(()C  )=)=>Wa Xq!++ Iq!Q 'D4H4H'  D001 E3'++ Iq!Q 'D4H4H(  eS[[)=)=>?r$N) r(r)r*r+r`rdrlrtrr,r$r"r[r[s" 1  04T.@r$r[c2eZdZdZdZdZdZdZdZdZ y) ImportedModuleAttributeTestsza Tests for L{deprecatedModuleAttribute} which involve loading a module via 'import'. zfrom twisted.python.deprecate import deprecatedModuleAttribute from incremental import Version deprecatedModuleAttribute( Version('Package', 1, 2, 3), 'message', __name__, 'module') cffdt|jjd}|j||}|j |j j dgtj z|jtjj|S)a_ Create some files in a hierarchy, based on a dictionary describing those files. The resulting hierarchy will be placed onto sys.path for the duration of the test. @param tree: A dictionary representing a directory structure. Keys are strings, representing filenames, dictionary values represent directories, string values represent file contents. @return: another dictionary similar to the input, with file content strings replaced with L{FilePath} objects pointing at where those contents are now stored. ci}|jD]t\}}|j|}t|tr|||<|j |>t|t r|j ||||<ktd|S)Nz(only strings and dicts allowed as values)r3child isinstancebytes setContentdictcreateDirectory ValueError)pathobjdirdictpathdictr8rr makeSomeFiless r"rzAImportedModuleAttributeTests.pathEntryTree..makeSomeFilessH%mmo Q U c*eU+$)HSM$$U+t,))+$1%$?HSM$%OPP QOr$utf-8) rmktempencodemakedirsreplaceSysPathpathdecoder{replaceSysModulesr|copy)r!treebaseresultrs @r" pathEntryTreez*ImportedModuleAttributeTests.pathEntryTrees  ,,W56 tT* TYY--g67#((BC s{{//12 r$cp|jd|jjdddi}|ddS)z Add a sample module and package to the path, returning a L{FilePath} pointing at the module which will be loadable as C{package.module}. spackagerr$)s __init__.py module.pyr)r _packageInitr)r!pathss r"simpleModuleEntryz.ImportedModuleAttributeTests.simpleModuleEntrysJ ""$($5$5$<$z.WarnAboutFunctionTests.setUp..s(!2!2!4ckk6H6H6Q Rr$N)rrrrrrparentrr{insertr}remover|rr isWindowsrk)r! packagePathr|s @r"r`zWarnAboutFunctionTests.setUp`s  .445MN   =)44S9 ;'22  " ;'22  0ll))+00  ;' 5++""$ RS         r$c.d}tj|d|j}t}|j j dr|dd}|j t|ddt||j|dddy) z L{deprecate.warnAboutFunction} emits a warning the file and line number of which point to the beginning of the implementation of the function passed to it. cyrr,r,r$r"aFuncz2WarnAboutFunctionTests.test_warning..aFunc r$zA Warning Messagez.pycNrfilenamer^) rwarnAboutFunctionrkrlowerendswithassertSamePathrrJ)r!rrprs r" test_warningz#WarnAboutFunctionTests.test_warnings  ##E+>?**,  >>  $ $V ,}H H]1%5j%ABHXDVW q))46IJr$cddlm}|j|j}|j t |ddj d|jjdjd|j|ddd|j|dd d |jt|d y ) z L{deprecate.warnAboutFunction} emits a C{DeprecationWarning} with the number of a line within the implementation of the function passed to it. rrrrtwisted_private_helperrlineno r^A Warning StringrPN) rrcallTestFunctionrkrrrrsiblingrrJrnr!rrps r"test_warningLineNumberz-WarnAboutFunctionTests.test_warningLineNumbers 2!**,   ]1%j188A B LL !: ; A A, O q)(3Q7 q))46HI ]+Q/r$cddlm}|j|j}|j t |ddj d|jjdjd|j|ddd|j|dd d |jt|d y ) z L{deprecate.warnAboutFunction} emits a C{DeprecationWarning} with the number of a line within the implementation handling the case in which dis.findlinestarts returns the lines in random order. r)pep626rrrs pep626.pyrr^rrPN) rrrrkrrrrrrrJrn)r!rrps r"'test_warningLineNumberDisFindlinestartsz>WarnAboutFunctionTests.test_warningLineNumberDisFindlinestartss 2!**,   ]1%j188A B LL !: ; A A, O q)(3R8 q))46HI ]+Q/r$c|jt|jt|jk(|d|y)a Assert that the two paths are the same, considering case normalization appropriate for the current platform. @type first: L{FilePath} @type second: L{FilePath} @raise C{self.failureType}: If the paths are not the same. z != N) assertTruerr)r!rvrws r"rz%WarnAboutFunctionTests.assertSamePaths8  UZZ HV[[$9 9itF: & r$c^ddlm}tjd=tj|j=|j j |j jdtr tddl m}|jtjjd|jtjj|j|j|j|jg}t|ddj!d}|j jdj#d}|j%|||j'|dd d |j'|dd d |j't)|d y)a  Even if the implementation of a deprecated function is moved around on the filesystem, the line number in the warning emitted by L{deprecate.warnAboutFunction} points to a line in the implementation of the deprecated function. rrrstwisted_renamed_helpertwisted_renamed_helperrrrrrr^rrPN)rrr{r|r(rmoveTorrrr}r~rrk testFunctionrrrrrJrn)r!rrp warnedPath expectedPaths r"test_renamedFilez'WarnAboutFunctionTests.test_renamedFilesN 2 KK0 1 KK ( DLL001JKL    2  )AB  9!**F,?,?+@A mA.z:AA'JK ||++,EFLL   J 5 q)(3Q7 q))46HI ]+Q/r$ctjdd=tjddddlm}|j |j }|jt|dy)z L{deprecate.warnAboutFunction} emits a warning that will be filtered if L{warnings.filterwarning} is called with the module name of the deprecated function. Nignoreractionrrr) warningsfiltersfilterwarningsrrrrkrJrnrs r"test_filteredWarningz+WarnAboutFunctionTests.test_filteredWarning sU   Q x8PQ1!**,  ]+Q/r$ctjdd=tjddddlm}|j |j |j }|jt|d|dd}|dd }|dd }|dd }tj||||}|j|jd d |y)z L{deprecate.warnAboutFunction} emits a warning that will be filtered once if L{warnings.filterwarning} is called with the module name of the deprecated function and an action of once. NrrrrrrPr^rirrz=module.py:9: DeprecationWarning: A Warning String return a zUnexpected warning string: ) rrrrrrrkrJrn formatwarningrr)r!rrpr^rirrmsgs r"test_filteredOnceWarningz/WarnAboutFunctionTests.test_filteredOnceWarnings   Q x8PQ1!!**,  ]+Q/"9- #J/ #J/q!(+$$Wh&I  LLT *# 1  r$N) r(r)r*r+r`rrrrrrrr,r$r"rrZs2 ;!zK$0&0(  $0L0( r$rcy)zK Do nothing. This is used to test the deprecation decorators. Nr,r,r$r" dummyCallabler@r$cy)z[ Do nothing. This is used to test the replacement parameter to L{deprecated}. Nr,r,r$r"dummyReplacementMethodrHrr$cBeZdZdZdZdZdZdZdZdZ dZ d Z y ) DeprecationWarningsTestscztdddd}|jt|j|tdy)z L{getDeprecationWarningString} returns a string that tells us that a callable was deprecated at a certain released version of Twisted. ryrzrzZ.DeprecationWarningsTests.test_getDeprecationWarningString was deprecated in Twisted 8.0.0N)rrJr test_getDeprecationWarningStringr(r!r]s r"rz9DeprecationWarningsTests.test_getDeprecationWarningStringQs: )Q1-  '(M(Mw W19 < r$ctdddd}tdz}|jt|j||t dy)z L{getDeprecationWarningString} returns a string that tells us that a callable was deprecated at a certain released version of Twisted, with a message containing additional information about the deprecation. ryrzrz: This is a messagezm.DeprecationWarningsTests.test_getDeprecationWarningString was deprecated in Twisted 8.0.0: This is a messageN)rr rJrrr()r!r]formats r"*test_getDeprecationWarningStringWithFormatzCDeprecationWarningsTests.test_getDeprecationWarningStringWithFormat]sO )Q1-+.CC  '55w AI K  r$ctdddd}t|tfd}td5}t d||j |dj t|j t|djtt||j |djjdtjdd d d y #1swYy xYw) zK Decorating a callable with L{deprecated} emits a warning. ryrzrcyrr,)dummysr"rhzJDeprecationWarningsTests.test_deprecateEmitsWarning..addStackLevelts Gr$TrecordalwayscoN)rrrrrrJrirmstrr^rrrstripr)r!r]rhcaughtrs @r"test_deprecateEmitsWarningz3DeprecationWarningsTests.test_deprecateEmitsWarningms)Q1-# 7#M2 4 ( UF  " O   VAY//1C D   F1I%%&+M7C    VAY//66tS T U U Us B-C,,C5ctdddd}t|t}|jtj|j|jt tt |y)zK The decorated function has the same name as the original. ryrzrN)rrrrJr(fullyQualifiedNamer!r]rs r"test_deprecatedPreservesNamez5DeprecationWarningsTests.test_deprecatedPreservesNames[)Q1-# 7#M2 //@ +M:.localDummyCallablerr$ryrzrrN)rrr r rJr+)r!r r]rs r"test_deprecatedUpdatesDocstringz8DeprecationWarningsTests.test_deprecatedUpdatesDocstringsZ  )Q1-# 7#$67-/GQS/TU +33U]]Cr$ctdddd}t|t}|j||jy)zt Deprecating a function adds version information to the decorated version of that function. ryrzrN)rrrrJdeprecatedVersionrs r"test_versionMetadataz-DeprecationWarningsTests.test_versionMetadatas; )Q1-# 7#M2 %"9"9:r$ctdddd}t|j|d}|j|t |jdy)a L{getDeprecationWarningString} takes an additional replacement parameter that can be used to add information to the deprecation. If the replacement parameter is a string, it will be interpolated directly into the result. ryrzrsomething.foobar replacementzE was deprecated in Twisted 8.0.0; please use something.foobar insteadN)rrrrJrr!r] warningStrings r"+test_getDeprecationWarningStringReplacementzDDeprecationWarningsTests.test_getDeprecationWarningStringReplacementsT)Q1-3  1 1 *  +D,Q,QR U r$ctdddd}t|j|t}|j |t |jdt dy)a L{getDeprecationWarningString} takes an additional replacement parameter that can be used to add information to the deprecation. If the replacement parameter is a callable, its fully qualified name will be interpolated into the result. ryrzrrz- was deprecated in Twisted 8.0.0; please use z.dummyReplacementMethod insteadN)rrrrrJrr(rs r"7test_getDeprecationWarningStringReplacementWithCallablezPDeprecationWarningsTests.test_getDeprecationWarningStringReplacementWithCallablesX)Q1-3  1 1 .  "$"G"GH( T r$N) r(r)r*rrrrr r rrrr,r$r"rrPs2   U*W D(; & r$rryrPrxceZdZdZy)DeprecatedClasszJ Class which is entirely deprecated without having a replacement. N)r(r)r*r+r,r$r"rrsr$rcfeZdZdZdZeedddddZejdZy) ClassWithDeprecatedPropertyz2 Class with a single deprecated property. NryrPrxrc|jS)zC Getter docstring. @return: The property. _someProtectedValuer&s r" somePropertyz(ClassWithDeprecatedProperty.somePropertys'''r$c||_y)z# Setter docstring. Nr r s r"r"z(ClassWithDeprecatedProperty.somePropertys $) r$) r(r)r*r+r!rrr"setterr,r$r"rrsK 1a34(5())r$rr0cy)z7 Function with a deprecated keyword parameter. Nr,)abcr0bars r"functionWithDeprecatedParameterr+rr$c:eZdZdZdZdZdZdZdZdZ dZ y ) DeprecatedDecoratorTestsz* Tests for deprecated decorators. c|j||jjDcgc]#}|js|j%c}ycc}w)a8 Check that C{target} object has the C{expected} docstring lines. @param target: Object which is checked. @type target: C{anything} @param expected: List of lines, ignoring empty lines or leading or trailing spaces. @type expected: L{list} or L{str} N)rJr+ splitlinesstrip)r!targetexpectedrs r"assertDocstringz(DeprecatedDecoratorTests.assertDocstrings@  &..*C*C*ESQqwwyS Ss A A ct}|j|jtjgdtddddtj_d}|j |j g}|jdt||jt|dd|j||dd y ) a% When L{deprecatedProperty} is used on a C{property}, accesses raise a L{DeprecationWarning} and getter docstring is updated to inform the version in which it was deprecated. C{deprecatedVersion} attribute is also set to inform the deprecation version. )zGetter docstring.z@return: The property.Deprecated in Twisted 1.2.3.ryrPrxrktwisted.python.test.test_deprecate.ClassWithDeprecatedProperty.someProperty was deprecated in Twisted 1.2.3rrir^N) rr"r3rrrktest_propertyGetterrJrnrm)r!objr^rs r"r7z,DeprecatedDecoratorTests.test_propertyGetters*+   ' 4 4  FM q!QF #00B  ; %%t'?'?&@A CM* +Xa[-DE (1+i"89r$cLt}t}||_|j||jd}|j |j g}|jdt||jt|dd|j||ddy)z} When L{deprecatedProperty} is used on a C{property}, setter accesses raise a L{DeprecationWarning}. r6rPrrir^N) rHrr"r>r!rktest_propertySetterrJrnrm)r!newValuer8r^rs r"r:z,DeprecatedDecoratorTests.test_propertySetter4s 8)+# h 7 78 ; %%t'?'?&@A CM* +Xa[-DE (1+i"89r$cPt|jtddgtddddt_d}|j |j g}|j dt||j t|dd |j ||dd y ) a When L{deprecated} is used on a class, instantiations raise a L{DeprecationWarning} and class's docstring is updated to inform the version in which it was deprecated. C{deprecatedVersion} attribute is also set to inform the deprecation version. z@Class which is entirely deprecated without having a replacement.r5ryrPrxrzRtwisted.python.test.test_deprecate.DeprecatedClass was deprecated in Twisted 1.2.3rrir^N) rr3rrrk test_classrJrnrm)r!r^rs r"r=z#DeprecatedDecoratorTests.test_classHs   V.  -4Iq!Q,G) . %%t&78 CM* +Xa[-DE (1+i"89r$ctdddd}t|dt}|j|jdy)a L{deprecated} takes an additional replacement parameter that can be used to indicate the new, non-deprecated method developers should use. If the replacement parameter is a string, it will be interpolated directly into the warning message. ryrzrrz Do nothing. This is used to test the deprecation decorators. Deprecated in Twisted 8.0.0; please use something.foobar instead. N)rrrrJr+rs r"test_deprecatedReplacementz3DeprecatedDecoratorTests.test_deprecatedReplacementcsB)Q1-7 7$67 F  MM  r$ctdddd}t|t}|t}|j |j dt dy)a) L{deprecated} takes an additional replacement parameter that can be used to indicate the new, non-deprecated method developers should use. If the replacement parameter is a callable, its fully qualified name will be interpolated into the warning message. ryrzrrzt Do nothing. This is used to test the deprecation decorators. Deprecated in Twisted 8.0.0; please use z%.dummyReplacementMethod instead. N)rrrrrJr+r()r!r] decoratorrs r"&test_deprecatedReplacementWithCallablez?DeprecatedDecoratorTests.test_deprecatedReplacementWithCallablewsJ)Q1-w4JK -(  MM   ! r$c d}td5}tdtdd|j|gtddd|j|gtddd |jt |d |j|d j t |jt|d j||jtddd |j|gtdddd|jt |d |j|d j t |jt|d j|dddy#1swYyxYw)NzzThe 'foo' parameter to twisted.python.test.test_deprecate.functionWithDeprecatedParameter was deprecated in Twisted 19.2.0Trr ()r0rPr2)r*) rrr+rJrnrirmrr^r)r!r^wss r"test_deprecatedKeywordParameterz8DeprecatedDecoratorTests.test_deprecatedKeywordParameters> / 4 ( :B  " +B 3   R $ +BB 7   R $ +B ;   SWa (   RU^^-? @   SA/ 9 HHJ +B ;   R $ +BB ;   SWa (   RU^^-? @   SA/ 9+ : : :s E!E99FN) r(r)r*r+r3r7r:r=r?rBrJr,r$r"r-r-s+  :@:(:6 ( (:r$r-c"eZdZdZdZdZdZy)AppendToDocstringTestszk Test the _appendToDocstring function. _appendToDocstring is used to add text to a docstring. cZd}t|d|jd|jy)zP Appending to an empty docstring simply replaces the docstring. cyrr,r,r$r" noDocstringzGAppendToDocstringTests.test_appendToEmptyDocstring..noDocstringrr$Appended text.Nr rJr+)r!rOs r"test_appendToEmptyDocstringz2AppendToDocstringTests.test_appendToEmptyDocstrings+   ;(89 );+>+>?r$cd}t|d|jgd|jj|j |jj dy)a Appending to a single line docstring places the message on a new line, with a blank line separating it from the rest of the docstring. The docstring ends with a newline, conforming to Twisted and PEP 8 standards. Unfortunately, the indentation is incorrect, since the existing docstring doesn't have enough info to help us indent properly. cy);This doesn't comply with standards, but is here for a test.Nr,r,r$r"singleLineDocstringzTAppendToDocstringTests.test_appendToSingleLineDocstring..singleLineDocstringrr$rP)rUrrP N)r rJr+r/rr)r!rVs r" test_appendToSingleLineDocstringz7AppendToDocstringTests.test_appendToSingleLineDocstrings] N .0@A   ' ' 2 2 4   +33<.multiLineDocstringrr$cy)zU This is a multi-line docstring. Appended text. Nr,r,r$r"expectedDocstringzQAppendToDocstringTests.test_appendToMultilineDocstring..expectedDocstringrr$rPNrQ)r!r[r]s r"test_appendToMultilineDocstringz6AppendToDocstringTests.test_appendToMultilineDocstrings8    -/?@ *224F4N4NOr$N)r(r)r*r+rRrXr^r,r$r"rLrLs @D2Pr$rLcReZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zy )MutualArgumentExclusionTestsz2 Tests for L{mutuallyExclusiveArguments}. cttddr ttj|||St tj |||S)a Test an invocation of L{passed} with the given function, arguments, and keyword arguments. @param func: A function whose argspec will be inspected. @type func: A callable. @param args: The arguments which could be passed to C{func}. @param kw: The keyword arguments which could be passed to C{func}. @return: L{_passedSignature} or L{_passedArgSpec}'s return value @rtype: L{dict} signatureN)rAinspectrrbr getargspecr!funcargskws r" checkPassedz(MutualArgumentExclusionTests.checkPassedsF 7K .#G$5$5d$;T2F F"'"4"4T":D"E Er$cfd}|j|j|ddtddy)z` L{passed} identifies the arguments passed by a simple positional test. cyrr,r'r(s r"rfzGMutualArgumentExclusionTests.test_passed_simplePositional..funcrr$rPrxrlNrJrirr!rfs r"test_passed_simplePositionalz9MutualArgumentExclusionTests.test_passed_simplePositional s.   ))$15ta1~Fr$cRd}|jt|j|dddy)z[ L{passed} raises a L{TypeError} if too many arguments are passed. cyrr,rls r"rfzBMutualArgumentExclusionTests.test_passed_tooManyArgs..funcrr$rPrxrNr? TypeErrorrirns r"test_passed_tooManyArgsz4MutualArgumentExclusionTests.test_passed_tooManyArgss'   )T%5%5tQ1Er$cRd}|jt|j|ddy)zs L{passed} raises a L{TypeError} if a argument is passed both positionally and by keyword. cyrr,r's r"rfzHMutualArgumentExclusionTests.test_passed_doublePassKeyword..func&rr$rPrxrwNrrrns r"test_passed_doublePassKeywordz:MutualArgumentExclusionTests.test_passed_doublePassKeyword (   )T%5%5tQ!Dr$cRd}|jt|j|ddy)z L{passed} raises a L{TypeError} if a keyword argument not present in the function's declaration is passed. cyrr,rws r"rfzIMutualArgumentExclusionTests.test_passed_unspecifiedKeyword..func1rr$rPrx)zNrrrns r"test_passed_unspecifiedKeywordz;MutualArgumentExclusionTests.test_passed_unspecifiedKeyword+ryr$chd}|j|j|dddtddy)z| L{passed} places additional positional arguments into a tuple under the name of the star argument. cyrr,rls r"rfz;MutualArgumentExclusionTests.test_passed_star..func<rr$rPrxr)rxrrlNrmrns r"test_passed_starz-MutualArgumentExclusionTests.test_passed_star6s1   ))$1a8$f:MNr$c d}|j|j|ddddtdtdddy) zn Additional keyword arguments are passed as a dict to the star star keyword argument. cyrr,rls r"rfz?MutualArgumentExclusionTests.test_passed_starStar..funcGrr$rPrxr)ryr|rlNrmrns r"test_passed_starStarz1MutualArgumentExclusionTests.test_passed_starStarAsC      T1Q!  4dQ$aSTBU6V r$cndd}|j|j|dddtdddy) zp The results of L{passed} only include arguments explicitly passed, not default values. rPrxcyrr,r'r(r)des r"rfzFMutualArgumentExclusionTests.test_passed_noDefaultValues..funcTrr$)r)r'r(rNrPrxrrmrns r"test_passed_noDefaultValuesz8MutualArgumentExclusionTests.test_passed_noDefaultValuesNs6   ))$1):D1Q.func`sq519q= r$rPrxrDrr( Nrr)rrJrns r""test_mutualExclusionPrimeDirectivez?MutualArgumentExclusionTests.test_mutualExclusionPrimeDirectiveYse %j\ 2 ! 3 ! aR( aA+ aa"-r$c`tddggdd}|jt|ddy) z L{mutuallyExclusiveArguments} raises a L{TypeError}n if its decoratee is passed a pair of mutually exclusive arguments. r'r(rrc ||zSrr,rls r"rfzPMutualArgumentExclusionTests.test_mutualExclusionExcludesByKeyword..funcns q5Lr$rlNr)rr?rsrns r"%test_mutualExclusionExcludesByKeywordzBMutualArgumentExclusionTests.test_mutualExclusionExcludesByKeywordhs: %sCj\ 2  3  )TQ!4r$cGdd}Gdd}d}|ddtj|j}|j}|dd|d <||}|j t t |d iy ) z Create a fake signature with an invalid parameter type to test error handling. The valid parameter types are specified in L{inspect.Parameter}. ceZdZdZy)MMutualArgumentExclusionTests.test_invalidParameterType..FakeSignaturec||_yr) parameters)r!rs r"r#zVMutualArgumentExclusionTests.test_invalidParameterType..FakeSignature.__init__|s ",r$Nr(r)r*r#r,r$r" FakeSignaturer{s -r$rceZdZdZy)MMutualArgumentExclusionTests.test_invalidParameterType..FakeParameterc ||_||_yr)rokind)r!rors r"r#zVMutualArgumentExclusionTests.test_invalidParameterType..FakeParameter.__init__s    r$Nrr,r$r" FakeParameterrs !r$rcyrr,rls r"rfzDMutualArgumentExclusionTests.test_invalidParameterType..funcrr$rPrxfaker)rPrxN)rcrbrrr?rsr)r!rrrfrdummyParametersfakeSigs r"test_invalidParameterTypez6MutualArgumentExclusionTests.test_invalidParameterTypetsz - - ! !   Q &&t,77 $//+,VV<0 )%5wKr$N)r(r)r*r+rirortrxr}rrrrrrr,r$r"r`r`sFF, G F E E O   Q . 5Lr$r`ceZdZdZdZdZy)KeywordOnlyTestsz, Keyword only arguments (PEP 3102). cBttj|||S)a Test an invocation of L{passed} with the given function, arguments, and keyword arguments. @param func: A function whose argspec to pass to L{_passed}. @type func: A callable. @param args: The arguments which could be passed to L{func}. @param kw: The keyword arguments which could be passed to L{func}. @return: L{_passed}'s return value @rtype: L{dict} )rrcrbres r"rizKeywordOnlyTests.checkPasseds  1 1$ 7rBBr$c ddd}ddd}|j|j|dddtdd |j|j|dddd tdd |j|j|ddd ddd td d ddd |jt|j|ddd ddy)z` Keyword only arguments follow varargs. They are specified in PEP 3102. Trcy)zM b is a keyword-only argument, with a default value. Nr,)r(r's r"func1z6KeywordOnlyTests.test_passedKeywordOnly..func1rr$cy)zd b, c, d, e are keyword-only arguments. b has a default value. Nr,)r(r)rrr's r"func2z6KeywordOnlyTests.test_passedKeywordOnly..func2rr$rPrxrrrlF)r(r)rrrr)r(r)rN)rJrirr?rs)r!rrs r"test_passedKeywordOnlyz'KeywordOnlyTests.test_passedKeywordOnlys     ))%Aq94)t;TU    UAq!u  5ti57Q     UAqEQ!q  A 6Ua1 2  )T%5%5uaeqTUVr$N)r(r)r*r+rirr,r$r"rrsC"Wr$rr)7r+rcr{r1ros.pathrrr importlibr ImportError incrementalrtwisted.pythonrtwisted.python.deprecater r r rr r rrrrrrrtwisted.python.filepathrtwisted.python.runtimertwisted.python.testr#twisted.python.test.modules_helpersrtwisted.trial.unittestrrr.r[rrrrrrrr+r-rLr`rr,r$r"rss  1+ $    -+4C6"DY*DYN_@2_@Dl%#68Kl%^c 0c LG 2G T GIq!Q '() ))0GIr1a8%@A h:2h:VAP0APH]L#6]L@/W*/W{#sD$$D/.D/