ϪfmdZddlmZgdZddlZddlZddlmZddlm Z ddl m Z ddl m Z mZmZmZmZmZdd lmamZdd lmZmZdd l mZed Zed ZdZdZde_de_de_ dZ!d+dZ"d,dZ#d,dZ$dZ% d+ d-dZ&d+dZ'dZ(dZ)GddZ*GddZ+Gdd Z,d!Z-d"Z.d#Z/d$Z0d%Z1d&Z2ed'ed(e f)Z3 d+ d.d*Z4y)/ah Deprecation framework for Twisted. To mark a method, function, or class as being deprecated do this:: from incremental import Version from twisted.python.deprecate import deprecated @deprecated(Version("Twisted", 22, 10, 0)) def badAPI(self, first, second): ''' Docstring for badAPI. ''' ... @deprecated(Version("Twisted", 22, 10, 0)) class BadClass: ''' Docstring for BadClass. ''' The newly-decorated badAPI will issue a warning when called, and BadClass will issue a warning when instantiated. Both will also have a deprecation notice appended to their docstring. To deprecate properties you can use:: from incremental import Version from twisted.python.deprecate import deprecatedProperty class OtherwiseUndeprecatedClass: @deprecatedProperty(Version("Twisted", 22, 10, 0)) def badProperty(self): ''' Docstring for badProperty. ''' @badProperty.setter def badProperty(self, value): ''' Setter sill also raise the deprecation warning. ''' To mark module-level attributes as being deprecated you can use:: badAttribute = "someValue" ... deprecatedModuleAttribute( Version("Twisted", 22, 10, 0), "Use goodAttribute instead.", "your.full.module.name", "badAttribute") The deprecated attributes will issue a warning whenever they are accessed. If the attributes being deprecated are in the same module as the L{deprecatedModuleAttribute} call is being made from, the C{__name__} global can be used as the C{moduleName} parameter. To mark an optional, keyword parameter of a function or method as deprecated without deprecating the function itself, you can use:: @deprecatedKeywordParameter(Version("Twisted", 22, 10, 0), "baz") def someFunction(foo, bar=0, baz=None): ... See also L{incremental.Version}. @type DEPRECATION_WARNING_FORMAT: C{str} @var DEPRECATION_WARNING_FORMAT: The default deprecation warning string format to use when one is not provided by the user. ) annotations) deprecateddeprecatedPropertygetDeprecationWarningStringgetWarningMethodsetWarningMethoddeprecatedModuleAttributedeprecatedKeywordParameterN)findlinestartswraps) ModuleType)AnyCallableDictOptionalTypeVarcast)warn warn_explicit)VersiongetVersionString) ParamSpec_P_Rz&%(fqpn)s was deprecated in %(version)sc0 |j}tj|stj |r|j }|d|Stj|r|j d|jS|S#t$r|j}YwxYw)z Return the fully qualified name of a module, class, method or function. Classes and functions need to be module level ones to be correctly qualified. @rtype: C{str}. .) __qualname__AttributeError__name__inspectisclass isfunction __module__ismethod)objname moduleNames :/usr/lib/python3/dist-packages/twisted/python/deprecate.py_fullyQualifiedNamer*sssw11#6^^ Qtf%%   # ..!3#3#3"455 K ||s A==BBztwisted.python.reflectfullyQualifiedNamec:t|r t|}d|dS)a  Surround a replacement for a deprecated API with some polite text exhorting the user to consider it as an alternative. @type replacement: C{str} or callable @return: a string like "please use twisted.python.modules.getModule instead". z please use z instead)callabler* replacements r)_getReplacementStringr0s% )+6  X ..cLdt|}|r|dt|}|dzS)a Generate an addition to a deprecated object's docstring that explains its deprecation. @param version: the version it was deprecated. @type version: L{incremental.Version} @param replacement: The replacement, if specified. @type replacement: C{str} or callable @return: a string like "Deprecated in Twisted 27.2.0; please use twisted.timestream.tachyon.flux instead." zDeprecated in ; r)rr0)versionr/docs r)_getDeprecationDocstringr6s; +G45 6CR-k:;< 9r1cr|t}||t|dz}|rdj|t|}|S)ag Return a string indicating that the Python name was deprecated in the given version. @param fqpn: Fully qualified Python name of the thing being deprecated @type fqpn: C{str} @param version: Version that C{fqpn} was deprecated in. @type version: L{incremental.Version} @param format: A user-provided format to interpolate warning values into, or L{DEPRECATION_WARNING_FORMAT } if L{None} is given. @type format: C{str} @param replacement: what should be used in place of C{fqpn}. Either pass in a string, which will be inserted into the warning message, or a callable, which will be expanded to its full import path. @type replacement: C{str} or callable @return: A textual description of the deprecation @rtype: C{str} )fqpnr4z{}; {})DEPRECATION_WARNING_FORMATrformatr0)r8r4r:r/ warningStrings r)_getDeprecationWarningStringr<sG2~+d7G7PQQM  0=  r1c0tt||||S)ak Return a string indicating that the callable was deprecated in the given version. @type callableThing: C{callable} @param callableThing: Callable object to be deprecated @type version: L{incremental.Version} @param version: Version that C{callableThing} was deprecated in. @type format: C{str} @param format: A user-provided format to interpolate warning values into, or L{DEPRECATION_WARNING_FORMAT } if L{None} is given @param replacement: what should be used in place of the callable. Either pass in a string, which will be inserted into the warning message, or a callable, which will be expanded to its full import path. @type replacement: C{str} or callable @return: A string describing the deprecation. @rtype: C{str} )r<r*) callableThingr4r:r/s r)rrs2 (M*GV[ r1cV|jr|jj}ng}t|dk(r|j|nJt|dk(r|j d|dgn'|j }|j d||z|gdj ||_y)av Append the given text to the docstring of C{thingWithDoc}. If C{thingWithDoc} has no docstring, then the text just replaces the docstring. If it has a single-line docstring then it appends a blank line and the message text. If it has a multi-line docstring, then in appends a blank line a the message text, and also does the indentation correctly. r N)__doc__ splitlineslenappendextendpopjoin) thingWithDoc textToAppenddocstringLinesspacess r)_appendToDocstringrNs%--88: >al+ ^  !r<45##%r6L#8&AB99^4Lr1cdfd }|S)a Return a decorator that marks callables as deprecated. To deprecate a property, see L{deprecatedProperty}. @type version: L{incremental.Version} @param version: The version in which the callable will be marked as having been deprecated. The decorated function will be annotated with this version, having it set as its C{deprecatedVersion} attribute. @param replacement: what should be used in place of the callable. Either pass in a string, which will be inserted into the warning message, or a callable, which will be expanded to its full import path. @type replacement: C{str} or callable ctdtdfd }t|t|_|S)zA Decorator that marks C{function} as deprecated. Nc8ttd|i|SN stacklevelrDeprecationWarningargskwargsfunctionr;s r)deprecatedFunctionzDdeprecated..deprecationDecorator..deprecatedFunction%  2q AT,V, ,r1)rYz_P.argsrZz _P.kwargsreturnr)rr rNr6deprecatedVersion)r[r\r;r/r4s` @r)deprecationDecoratorz(deprecated..deprecationDecoratorsX4 gt[  x -  -   8+ N 07,!!r1)r[Callable[_P, _R]r^ra)r4r/r`s`` r)rr s&"& r1c8Gddtfd}|S)a Return a decorator that marks a property as deprecated. To deprecate a regular callable or class, see L{deprecated}. @type version: L{incremental.Version} @param version: The version in which the callable will be marked as having been deprecated. The decorated function will be annotated with this version, having it set as its C{deprecatedVersion} attribute. @param replacement: what should be used in place of the callable. Either pass in a string, which will be inserted into the warning message, or a callable, which will be expanded to its full import path. @type replacement: C{str} or callable @return: A new property with deprecated setter and getter. @rtype: C{property} @since: 16.1.0 ceZdZdZdZdZy)/deprecatedProperty.._DeprecatedPropertyzQ Extension of the build-in property to allow deprecated setters. c2tfd}|S)NcLtjtd|i|SrR)rr;rW)rYrZr[selfs r)r\z^deprecatedProperty.._DeprecatedProperty._deprecatedWrapper..deprecatedFunctionPs,&&&   000r1r )rhr[r\s`` r)_deprecatedWrapperzBdeprecatedProperty.._DeprecatedProperty._deprecatedWrapperOs! 8_ 1 1& %r1cLtj||j|SN)propertysetterri)rhr[s r)rmz6deprecatedProperty.._DeprecatedProperty.setter[s??4)@)@)JK Kr1N)r r$rrCrirmrbr1r)_DeprecatedPropertyreJs  & Lr1rnctdtfd}t|t|_|}|_|S)Nc8ttd|i|SrRrVrXs r)r\zLdeprecatedProperty..deprecationDecorator..deprecatedFunctioncr]r1)rr rNr6r_r;)r[r\resultr;rnr/r4s` @r)r`z0deprecatedProperty..deprecationDecorator^sh3 gt[  x -  -   8+ N 07,$%78, r1)rl)r4r/r`rns`` @r)rr3s.LhL(& r1ctS)zR Return the warning method currently used to record deprecation warnings. rrbr1r)rrts  Kr1c|ay)z Set the warning method to use to record deprecation warnings. The callable should take message, category and stacklevel. The return value is ignored. Nrs) newMethods r)rr{s  Dr1c"eZdZdZdZdZdZy)_InternalStatez An L{_InternalState} is a helper object for a L{_ModuleProxy}, so that it can easily access its own attributes, bypassing its logic for delegating to another object that it's proxying for. @ivar proxy: a L{_ModuleProxy} c2tj|d|yNproxy)object __setattr__)rhrzs r)__init__z_InternalState.__init__s4%0r1cVtjtj|d|Sry)r{__getattribute__)rhr's r)rz_InternalState.__getattribute__s"&&v'>'>tW'MtTTr1cXtjtj|d||Sry)r{r|r)rhr'values r)r|z_InternalState.__setattr__s%!!&"9"9$"H$PUVVr1N)r r$rrCr}rr|rbr1r)rwrws1UWr1rwc*eZdZdZdZddZdZdZy) _ModuleProxya Python module wrapper to hook module-level attribute access. Access to deprecated attributes first checks L{_ModuleProxy._deprecatedAttributes}, if the attribute does not appear there then access falls through to L{_ModuleProxy._module}, the wrapped module object. @ivar _module: Module on which to hook attribute access. @type _module: C{module} @ivar _deprecatedAttributes: Mapping of attribute names to objects that retrieve the module attribute's original value. @type _deprecatedAttributes: C{dict} mapping C{str} to L{_DeprecatedAttribute} @ivar _lastWasPath: Heuristic guess as to whether warnings about this package should be ignored for the next call. If the last attribute access of this module was a C{getattr} of C{__path__}, we will assume that it was the import system doing it and we won't emit a warning for the next access, even if it is to a deprecated attribute. The CPython import system always tries to access C{__path__}, then the attribute itself, then the attribute itself again, in both successful and failed cases. @type _lastWasPath: C{bool} cDt|}||_i|_d|_y)NF)rw_module_deprecatedAttributes _lastWasPath)rhmodulestates r)r}z_ModuleProxy.__init__s#t$ &(#"r1cdt|}dt|jd|jdS)z Get a string containing the type of the module proxy and a representation of the wrapped module object. )rwtyper r)rhrs r)__repr__z_ModuleProxy.__repr__s3 t$4:&&'x /@BBr1cVt|}d|_t|j||y)z@ Set an attribute on the wrapped module object. FN)rwrsetattrr)rhr'rrs r)r|z_ModuleProxy.__setattr__s&t$" tU+r1ct|}|jrd}n|jj|}||j}nt |j |}|dk(r d|_|Sd|_|S)aG Get an attribute from the module object, possibly emitting a warning. If the specified name has been deprecated, then a warning is issued. (Unless certain obscure conditions are met; see L{_ModuleProxy._lastWasPath} for more information about what might quash such a warning.) N__path__TF)rwrrgetgetattrr)rhr'rdeprecatedAttributers r)rz_ModuleProxy.__getattribute__st$   "& "'"="="A"A$"G   *(++-EEMM40E : !%E  "'E  r1N)r^str)r r$rrCr}rr|rrbr1r)rrs6# C,r1rceZdZdZdZdZy)_DeprecatedAttributeaE Wrapper for deprecated attributes. This is intended to be used by L{_ModuleProxy}. Calling L{_DeprecatedAttribute.get} will issue a warning and retrieve the underlying attribute's value. @type module: C{module} @ivar module: The original module instance containing this attribute @type fqpn: C{str} @ivar fqpn: Fully qualified Python name for the deprecated attribute @type version: L{incremental.Version} @ivar version: Version that the attribute was deprecated in @type message: C{str} @ivar message: Deprecation message cj||_||_|jdz|z|_||_||_y)z7 Initialise a deprecated name wrapper. rN)rr r8r4message)rhrr'r4rs r)r}z_DeprecatedAttribute.__init__s5  OOc)D0   r1ct|j|j}t|j|j t dz|jz}t|td|S)zU Get the underlying attribute value and issue a deprecation warning. z: rT) rrr r<r8r4r9rrrW)rhrqrs r)rz_DeprecatedAttribute.getsTdmm4. IIt||%?$%F%U  W(Q7 r1N)r r$rrCr}rrbr1r)rrs( r1rctj|d}t||||}tj|d}|||<y)a Mark a module-level attribute as being deprecated. @type proxy: L{_ModuleProxy} @param proxy: The module proxy instance proxying the deprecated attributes @type name: C{str} @param name: Attribute name @type version: L{incremental.Version} @param version: Version that the attribute was deprecated in @type message: C{str} @param message: Deprecation message rrN)r{rr)rzr'r4rrattrrs r)_deprecateAttributersG %%eY7G w @D#33E;RS"&$r1ctj|}t|ts,t t t|}|tj|<t ||||y)aE Declare a module-level attribute as being deprecated. @type version: L{incremental.Version} @param version: Version that the attribute was deprecated in @type message: C{str} @param message: Deprecation message @type moduleName: C{str} @param moduleName: Fully-qualified Python name of the module containing the deprecated attribute; if called from the same module as the attributes are being deprecated in, using the C{__name__} global can be helpful @type name: C{str} @param name: Attribute name to deprecate N)sysmodules isinstancerrrr)r4rr(r'rs r)r r 0sI&[[ $F fl +j,v"67"( Jgw7r1c tj|j}t|tt j |tdt|jD|j|jjdidy)a Issue a warning string, identifying C{offender} as the responsible code. This function is used to deprecate some behavior of a function. It differs from L{warnings.warn} in that it is not limited to deprecating the behavior of a function currently on the call stack. @param offender: The function that is being deprecated. @param warningString: The string that should be emitted by this warning. @type warningString: C{str} @since: 11.0 c3*K|] \}}|| ywrkrb).0_ lineNumbers r) z$warnAboutFunction..ds" :%  s__warningregistry__N)categoryfilenamelinenorregistrymodule_globals) rrr$rrWr! getabsfilemaxr __code__r __globals__ setdefault)offenderr;offenderModules r)warnAboutFunctionrKsy([[!4!45N###N3 !/0A0A!B  &&%%001FK r1ci}t|jt|z }|jix}||j<|dkr<|j t d|t|jd||j<t |j|D] \}}|||< |j D]D\}}||jvr||vr t d|||<)|j||<;t d|S)a Take an I{inspect.ArgSpec}, a tuple of positional arguments, and a dict of keyword arguments, and return a mapping of arguments that were actually passed to their passed values. @param argspec: The argument specification for the function to inspect. @type argspec: I{inspect.ArgSpec} @param positional: The positional arguments that were passed. @type positional: L{tuple} @param keyword: The keyword arguments that were passed. @type keyword: L{dict} @return: A dictionary mapping argument names (those declared in C{argspec}) to values that were passed explicitly by the user. @rtype: L{dict} mapping L{str} to L{object} NrToo many arguments.Already passed. no such param)rErYkeywordsvarargs TypeErrorzipitems)argspec positionalkeywordrqunpassedrZr'rs r)_passedArgSpecros &!#F7<< 3z?2H#,..(()!| ?? "12 2&0W\\1B1D&EF7?? #7<<4 et }}- e 7<< v~ 122 F4L    ) F4LO, ,- Mr1c i}d}d}t|jjD]b\}\}}|jtj j k(r||d||<t||dz}K|jtj jk(rix}||<z|jtj jtj jfvr|t|ks||||<|dz }|jtj jk(rL||vs|jtj jk(rtd||j||<Jtd|d|jt||kDr td|jD]H\}} ||jjvr||vr td| ||<7|| ||<?td |S) a Take an L{inspect.Signature}, a tuple of positional arguments, and a dict of keyword arguments, and return a mapping of arguments that were actually passed to their passed values. @param signature: The signature of the function to inspect. @type signature: L{inspect.Signature} @param positional: The positional arguments that were passed. @type positional: L{tuple} @param keyword: The keyword arguments that were passed. @type keyword: L{dict} @return: A dictionary mapping argument names (those declared in C{signature}) to values that were passed explicitly by the user. @rtype: L{dict} mapping L{str} to L{object} Nrr@zmissing keyword arg 'z' parameter is invalid kind: rrr) enumerate parametersrkindr! ParameterVAR_POSITIONALrE VAR_KEYWORDPOSITIONAL_OR_KEYWORDPOSITIONAL_ONLY KEYWORD_ONLYdefaultemptyrkeys) signaturerrrqrZ numPositionalnr'paramrs r)_passedSignaturers&F FM%i&:&:&@&@&BCQ=D% ::**99 9%ab>F4Lt -1M ZZ7,,88 8$& &FVD\ ZZ    3 3    - -  3z?")!}t " ZZ7,,99 97"==G$5$5$;$;;#&:4&$ABB#(==F4Lav%B5::,OP P-Q0 :&-..}}- e 9'',,. .v~ 122 F4L   F4LO, ,- Mr1cfd}|S)a Decorator which causes its decoratee to raise a L{TypeError} if two of the given arguments are passed at the same time. @param argumentPairs: pairs of argument identifiers, each pair indicating an argument that may not be passed in conjunction with another. @type argumentPairs: sequence of 2-sequences of L{str} @return: A decorator, used like so:: @_mutuallyExclusiveArguments([["tweedledum", "tweedledee"]]) def function(tweedledum=1, tweedledee=2): "Don't pass tweedledum and tweedledee at the same time." @rtype: 1-argument callable taking a callable and returning a callable. cptjttfd}|S)Nc ||}D],\}}||vs ||vstd|d|dtd|i|S)NThe z and z arguments to z are mutually exclusive.)rr*) rYrZ argumentsthisthat_passed argumentPairsspecwrappees r)wrappedz=_mutuallyExclusiveArguments..wrapper..wrappedsedF3I+  d9$):#':7'CE  D+F+ +r1)r!rrr )rrrrrs` @@r)wrapperz,_mutuallyExclusiveArguments..wrappers5  )" w ,  ,r1rb)rrs` r)_mutuallyExclusiveArgumentsrs$" Nr1_Tc.)boundcdfd }|S)aw Return a decorator that marks a keyword parameter of a callable as deprecated. A warning will be emitted if a caller supplies a value for the parameter, whether the caller uses a keyword or positional syntax. @type version: L{incremental.Version} @param version: The version in which the parameter will be marked as having been deprecated. @type name: L{str} @param name: The name of the deprecated parameter. @type replacement: L{str} @param replacement: Optional text indicating what should be used in place of the deprecated parameter. @since: Twisted 21.2.0 ctddt djt }r|dzt z}|dz }t j j}|vrM|jt jjk(r#t|jfd}nfd}ttt|}t!|||S) Nrz parameter to r.z'The {!r} parameter was deprecated in {}r3rc\t|kDs|vrttd|i|SrR)rErrW)rYrZr'parameterIndexr;rs r)checkDeprecatedParameterzMdeprecatedKeywordParameter..wrapper..checkDeprecatedParameter+s2t9~-(:qI///r1c@|vrttd|i|SrRrV)rYrZr'r;rs r)rzMdeprecatedKeywordParameter..wrapper..checkDeprecatedParameter2s'6>(:qI///r1)r<r*r:rr0r!rrrrrlistindexrrr rN) rr5paramsr decoratedrr;r'r/r4s ` @@r)rz+deprecatedKeywordParameter..wrappers44(.)>  W %  *4[AAC s ""7+66 FNt !!W%6%6%L%LL!&\//5N 0 0 0 neGn-EFG 9c*r1)rrr^rrb)r4r'r/rs``` r)r r s.$L Nr1rk)NN)r4rr/z"str | Callable[..., object] | Noner^z.Callable[[Callable[_P, _R]], Callable[_P, _R]])r4rr'rr/z Optional[str]r^zCallable[[_Tc], _Tc])5rC __future__r__all__r!rdisr functoolsr typesrtypingrrrrrrwarningsrr incrementalrrrrrr9r*r$r rr0r6r<rrNrrrrrwrrrr rrrrrr rbr1r)rsI KX#  ??(1t_ T]E,":3#7  /( F<52IM& & #E& 3& R> BWW&MM`,,^'086!H'T9x#Le8CH-.?C= ==.;==r1