o k`,@sddlZddlZddlZddlmZmZmZmZddl m Z m Z ddl m Z mZmZmZddlmZmZddlmZddlmZddlmZmZmZmZdd lmZmZm Z m!Z!gd Z"e#Z$d d Z%d dZ&ddZ'ddZ(GdddeZ)GdddeZ*Gddde#Z+Gddde#Z,d5ddZ-Gddde#Z.Gdd d e#Z/Gd!d"d"e/Z0Gd#d$d$e/Z1Gd%d&d&e/Z2Gd'd(d(e/Z3Gd)d*d*e/Z4Gd+d,d,e/Z5Gd-d.d.e/Z6Gd/d0d0e3Z7Gd1d2d2e Z8d3d4Z9dS)6N) ConfigParser NoOptionErrorNoSectionError ParsingError)AdminCommandErrorIAdminCommandProvider) ComponentExtensionPoint TracError implements) AtomicFileas_bool)wait_for_file_mtime_change)tag)cleandocprintout to_unicodeto_utf8)N__dgettexttag_) Configuration ConfigSectionOption BoolOption IntOption FloatOption ListOption ChoiceOption PathOptionExtensionOptionOrderedExtensionsOptionConfigurationErrorcC t|pdS)Nr)intvaluer(-/usr/lib/python3/dist-packages/trac/config.py_getint% r*cCr$)Ng)floatr&r(r(r) _getfloat)r+r-cCst|sgSt|tr+t|ttfrtdttj||}n||}dd|D}nt|}|s8dd|D}|S)N|cSg|]}|qSr()strip.0itemr(r(r) 5z_getlist..cSsg|]}|dvr|qS)Nr(r1r(r(r)r49) isinstancestrlisttupleresplitjoinmapescape)r'sep keep_emptysplitteditemsr(r(r)_getlist-s  rFcCs,t|j}|rt|j|fi|jpi}|SN)r__doc__r doc_domaindoc_args)option_or_sectiondocr(r(r)_getdoc=s  rMcs*eZdZdZedZdfdd ZZS)r#zEException raised when a value in the configuration file is not valid.zConfiguration ErrorNFcs$|durtd}t|||dS)Nz*Look in the Trac log for more information.)rsuper__init__)selfmessagetitleshow_traceback __class__r(r)rOIszConfigurationError.__init__)NNF)__name__ __module__ __qualname__rHrrRrO __classcell__r(r(rTr)r#Esr#c@sfeZdZdZdddZddZddefd d Zddefd d Zdd dZ dddZ ddZ ddZ dS)UnicodeConfigParserzzA Unicode-aware version of ConfigParser. Arguments are encoded to UTF-8 and return values are decoded from UTF-8. TcKs(||_|ddtj|fi|dS)N interpolation)_ignorecase_option setdefaultrrO)rPignorecase_optionkwargsr(r(r)rO[s zUnicodeConfigParser.__init__cCs|jr|}|SrG)r\lower)rPoptionr(r(r) optionxform`szUnicodeConfigParser.optionxformFNc Cs<z tj|||||dWSttfy|tur|YSwN)rawvars)rgetrr _use_default)rPsectionrardrefallbackr(r(r)rfeszUnicodeConfigParser.getcCs6z tj||||dWSty|tur|YSwrc)rrErrg)rPrhrdrerir(r(r)rEns zUnicodeConfigParser.itemscCs(t|dur|nd}t||||dSr6)rrset)rPrhrar' value_strr(r(r)rjvszUnicodeConfigParser.setutf-8cCst|||SrG)rread)rPfilenameencodingr(r(r)rmzszUnicodeConfigParser.readcCs|}t|j|_|SrG)rUcopy _sections)rPparserr(r(r)__copy__}zUnicodeConfigParser.__copy__cCs|}t|j|_|SrG)rUrpdeepcopyrq)rPmemorrr(r(r) __deepcopy__rtz UnicodeConfigParser.__deepcopy__TrG)rl) rVrWrXrHrOrbrgrfrErjrmrsrwr(r(r(r)rZOs     rZc@seZdZdZifddZddZddZdd Zd d Ze d d Z d7ddZ d7ddZ d7ddZ d7ddZd8ddZd7ddZddZd9d d!Zd9d"d#Zd9d$d%Zd:d'd(Zd;d)d*Zd+d,ZdrzThin layer over `ConfigParser` from the Python standard library. In addition to providing some convenience methods, the class remembers the last modification time of the configuration file, and reparses it when the file has changed. cCs6||_t|_d|_g|_d|_i|_|jdddS)NrTforce)rnrZrr_pristine_parserparents _lastmtimerqparse_if_needed)rPrnparamsr(r(r)rOszConfiguration.__init__cCd|jj|jfS)Nz<%s %r>)rUrVrnrPr(r(r)__repr__zConfiguration.__repr__cCs ||vS)zWReturn whether the configuration contains a section of the given name. )sectionsrPnamer(r(r) __contains__s zConfiguration.__contains__cCs$||jvr t|||j|<|j|S)z9Return the configuration section with the specified name.)rqSectionrr(r(r) __getitem__s  zConfiguration.__getitem__cCs|j|d|j|dSrG)rqpoprrremove_sectionrr(r(r) __delitem__szConfiguration.__delitem__cCstj|jS)zXReturn boolean indicating configuration file existence. :since: 1.0.11 )ospathisfilernrr(r(r)existsszConfiguration.existsr7cC||||SznReturn the value of the specified option. Valid default input is a string. Returns a string. rfrPrhkeydefaultr(r(r)rfzConfiguration.getcCr)a Return the specified option as boolean value. If the value of the option is one of "yes", "true", "enabled", "on", or "1", this method wll return `True`, otherwise `False`. Valid default input is a string or a bool. Returns a bool. getboolrr(r(r)rzConfiguration.getboolcCr)Return the value of the specified option as integer. If the specified option can not be converted to an integer, a `ConfigurationError` exception is raised. Valid default input is a string or an int. Returns an int. getintrr(r(r)rrzConfiguration.getintcCr)Return the value of the specified option as float. If the specified option can not be converted to a float, a `ConfigurationError` exception is raised. Valid default input is a string, float or int. Returns a float. getfloatrr(r(r)rrzConfiguration.getfloat,FcCs||||||S)aReturn a list of values that have been specified as a single comma-separated option. A different separator can be specified using the `sep` parameter. The `sep` parameter can specify multiple values using a list or a tuple. If the `keep_empty` parameter is set to `True`, empty elements are included in the list. Valid default input is a string or a list. Returns a string. )getlist)rPrhrrrBrCr(r(r)r zConfiguration.getlistcCr)zReturn a configuration value as an absolute path. Relative paths are resolved relative to the location of this configuration file. Valid default input is a string. Returns a normalized path. getpathrr(r(r)rrzConfiguration.getpathcCs||||dSzlChange a configuration value. These changes are not persistent unless saved with `save()`. N)rj)rPrhrr'r(r(r)rjszConfiguration.setNcCs<i}t|D]\\}}}||j||i|<q |S)zReturns a dictionary of the default configuration values. If `compmgr` is specified, return only options declared in components that are enabled in the given `ComponentManager`. )r get_registryrEdumpsrr])rPcompmgrdefaultsrhrrar(r(r)rs   zConfiguration.defaultscCs|||S)aOReturn a list of `(name, value)` tuples for every option in the specified section. This includes options that have default values that haven't been overridden. If `compmgr` is specified, only return default option values for components that are enabled in the given `ComponentManager`. )options)rPrhrr(r(r)rs zConfiguration.optionscCs |r |||dS||=dS)z'Remove the specified option or section.N)remove)rPrhrr(r(r)rs zConfiguration.removeTcCs^t|j}|jD] }||j|ddq |r!||||r+|t|t|S)aLReturn a list of section names. If `compmgr` is specified, only the section names corresponding to options declared in components that are enabled in the given `ComponentManager` are returned. :param empty: If `True`, include sections from the registry that contain no options. Fr) rjrrrr|updaterrrsorted)rPrremptyrparentr(r(r)rs zConfiguration.sectionscCr)zReturns True if option exists in section in either the project trac.ini or one of the parents, or is available through the Option registry. )contains)rPrhrarr(r(r) has_option(rzConfiguration.has_optionc s`itD]\\}}}||i|<qfdd}g}|D]O}g}||D];}d}|jD]}|j||ddrH||||||}nq2|j||rf||||j||} | |krf| || fq+|rr| |t |fq#t } |D]\}}| ||D] \} } | || | qqxz|| Wntyt|j|_wt|j|_dS)z4Write the configuration options to the primary file.cs$|i|}|r||S|SrG)rf normalize)rhrr'ra all_optionsr(r)r6sz%Configuration.save..normalizeNFr)rrrEr]rr|rrfrrappendrrZ add_sectionrj_write Exceptionrprur{) rPrhrrarrrrrcurrentrrrvalr(rr)save/sN          zConfiguration.savec Cs|jr|jsdSd}tj|j}|s||jkrLt|_z|j|js-t t d|jdWnt y?}zt ||d}~ww||_t |j|_d}|rT||_n|jD] }||j|dO}qW|rgi|_|S)NFz3Error reading '%(file)s', make sure it is readable.)fileTry)rnrrrgetmtimer}rZrrrmr rrrprur{ _get_parentsr|r~rq)rPrzchangedmodtimeerr(r(r)r~\s4    zConfiguration.parse_if_neededcCs6|jr|jrt|jtjrt|jdSdSdSdSrG)rnrraccessW_OKrrr(r(r)touchxs  zConfiguration.touchcsfdd}|rP|dr|dd}|d}ddlm}|jD]*}|jd|jd}|dt||krM|j D] }t |t rL||qAq#dSt | D]}||qWdS) zRetrieve all default values and store them explicitly in the configuration, so that they can be saved to file. Values already set in the configuration are not overwritten. cs>|j}|j}j||dds||j}|||dSdS)NFr)rhrrrrrj)rarhrr'rr(r)set_option_defaults  z6Configuration.set_defaults..set_option_defaultz.*N.r ComponentMeta)endswithr`r> trac.corer _componentsrWrVlen__dict__valuesr9rr)rPr componentrrclsclsnamerar(rr) set_defaults}s&       zConfiguration.set_defaultscCsjg}|jddr3|jdddD]}|}tj|s+tjtj |j |}| t |q|S)Ninheritrr) rrrrfr>r0rrisabsr?dirnamernrr)rP_parentsrnr(r(r)rs zConfiguration._get_parentscCs^|jsdSt|jt|jd}|ddg||WddS1s(wYdS)Nwz# -*- coding: utf-8 -*-  )rnrr writelineswrite)rPrrfdr(r(r)rs  "zConfiguration._writer7)r7rFrG)NTFrx)F)NN)rVrWrXrHrOrrrrpropertyrrfrrrrrrjrrrrrrr~rrrrr(r(r(r)rs6          -  rc@seZdZdZgdZddZddZd!dd ZeZd"d d Z e Z d#ddZ d#ddZ d#ddZ d#ddZd$ddZd#ddZd%ddZddZdd Zd S)&rzpProxy for a specific configuration section. Objects of this class should not be instantiated directly. configr_cachecCs||_||_i|_dSrGr)rPrrr(r(r)rOs zSection.__init__cCrNz <%s [%s]>rUrVrrr(r(r)rrzSection.__repr__TcCsR|jj|j|r dS|jjD]}||jj|ddrdSq|o(|j|ftjvS)NTFr)rrrrrr|rrregistry)rPrrrr(r(r)rs zSection.containsNccst}|jj|jr!|jj|jD] }|||Vq|jjD]}||jj ddD]}|}||vrB|||Vq0q%|r`t | D]\}}||jkr_||vr_|VqMdSdS)zIterate over the options in this section. If `compmgr` is specified, only return default option values for components that are enabled in the given `ComponentManager`. FrN) rjrrr has_sectionrraddr`r|iteraterrkeys)rPrrrrarloptionrhr(r(r)rs*  zSection.iterater7cCs|j|t}|tur |S|jj|j|r |jj|j|}n0|jjD]}||j|t}|tur5nq$|turNtj |j|f}|rK| |j nt}nt}|turV|S||j|<|Sr) rrfrgrrrrrr|rrrr)rPrrcachedr'rrar(r(r)rfs(  z Section.getcCst|||S)a6Return the value of the specified option as boolean. This method returns `True` if the option value is one of "yes", "true", "enabled", "on", or non-zero numbers, ignoring case. Otherwise `False` is returned. Valid default input is a string or a bool. Returns a bool. )r rf)rPrrr(r(r)rs zSection.getboolc C@|||}zt|WStyttd|j|t|dw)rz8[%(section)s] %(entry)s: expected integer, got %(value)srhentryr')rfr* ValueErrorr#rrreprrPrrr'r(r(r)r   zSection.getintc Cr)rz6[%(section)s] %(entry)s: expected float, got %(value)sr)rfr-rr#rrrrr(r(r)rrzSection.getfloatrcCst|||||S)aReturn a list of values that have been specified as a single comma-separated option. A different separator can be specified using the `sep` parameter. The `sep` parameter can specify multiple values using a list or a tuple. If the `keep_empty` parameter is set to `True`, empty elements are included in the list. Valid default input is a string or a list. Returns a list. )rFrf)rPrrrBrCr(r(r)r'rzSection.getlistcCsN|||}|s |Stj|stjtj|jj|}tjtj |S)zReturn the value of the specified option as a path, relative to the location of this configuration file. Valid default input is a string. Returns a normalized path. ) rfrrrr?rrrnnormcaserealpath)rPrrrr(r(r)r4s  zSection.getpathccs&||D] }|||fVqdS)a*Return `(key, value)` tuples for every option in the section. This includes options that have default values that haven't been overridden. If `compmgr` is specified, only return default option values for components that are enabled in the given `ComponentManager`. N)rrf)rPrrr(r(r)rAszSection.optionscCsB|j|d|jj|js|jj|j|jj|j||Sr)rrrrrrrrrj)rPrr'r(r(r)rjKsz Section.setcCsV|j|d|jj|jr'|jj|j||jj|js)|j|j=dSdSdS)zDelete a key from this section. Like for `set()`, the changes won't persist until `save()` gets called. N)rrrrrrr remove_optionr)rPrr(r(r)rUszSection.removerx)NTr)r7rTrG)rVrWrXrH __slots__rOrrrr__iter__rfrrrrrrrjrr(r(r(r)rs$        rcsjdur|jSddlm}i|jD]}|jD] }t||r$||<qqtfdd|jDS)zReturn the descriptor registry. If `compmgr` is specified, only return descriptors for components that are enabled in the given `ComponentManager`. Nrrc3s2|]}|dvs|dr|VqdS)N) is_enabled)r2eachr componentsr(r) rs z _get_registry..) rrrrrrr9dictrE)rrrcompattrr(rr) _get_registrybs   rc@sHeZdZdZiZedddZdddZdd Zd d Z e d d Z dS)rz&Descriptor for configuration sections.NcC tt|S)zReturn the section registry, as a `dict` mapping section names to `ConfigSection` objects. If `compmgr` is specified, only return sections for components that are enabled in the given `ComponentManager`. )rrrr(r(r)r| zConfigSection.get_registrytracinicCs,||_||j|j<t||_||_||_dS)z!Create the configuration section.N)rrrrHrIrJ)rPrrLrIrJr(r(r)rOs    zConfigSection.__init__cCs8|dur|St|dd}|rt|tr||jSdSdSNr)getattrr9rr)rPinstanceownerrr(r(r)__get__s   zConfigSection.__get__cCrrrrr(r(r)rrzConfigSection.__repr__cCt|S)z(Return localized document of the sectionrMrr(r(r)rLzConfigSection.docrG)rN) rVrWrXrHr staticmethodrrOr rrrLr(r(r(r)rws  rc@sleZdZdZiZddZedddZ  dd d Zd d Z d dZ ddZ e ddZ ddZddZdS)rz%Descriptor for configuration options.cC |||SrGrrPrhrrr(r(r)accessorr+zOption.accessorNcCr)zReturn the option registry, as a `dict` mapping `(section, key)` tuples to `Option` objects. If `compmgr` is specified, only return options for components that are enabled in the given `ComponentManager`. )rrrr(r(r)rrzOption.get_registryr7rcCsD||_||_|||_||j|j|jf<t||_||_||_dS)a,Create the configuration option. :param section: the name of the configuration section this option belongs to :param name: the name of the option :param default: the default value for the option :param doc: documentation of the option N) rhrrrrrrHrIrJ)rPrhrrrLrIrJr(r(r)rOs    zOption.__init__cCsN|dur|St|dd}|r#t|tr%||j}|||j|j}|SdSdSr)rr9rrhrrr)rPr r rrhr'r(r(r)r s  zOption.__get__cCs ttd)Nz!Setting attribute is not allowed.)AttributeErrorr)rPr r'r(r(r)__set__r+zOption.__set__cCsd|jj|j|jfS)Nz <%s [%s] %r>)rUrVrhrrr(r(r)rs zOption.__repr__cCr )z'Return localized document of the optionr rr(r(r)rLrz Option.doccCs:|durdS|dur dS|durdSt|tr|St|S)z8Return the value as a string to write to a trac.ini fileNr7TenabledFdisabled)r9r:rrPr'r(r(r)rs z Option.dumpscCs ||S)z5Normalize the given value to write to a trac.ini file)rrr(r(r)rs zOption.normalizerGNr7rN)rVrWrXrHrrrrrOr rrrrLrrr(r(r(r)rs       rc@ eZdZdZddZddZdS)rz-Descriptor for boolean configuration options.cCrrGrrr(r(r)rr+zBoolOption.accessorcCs|dvrt|}||S)N)TF)r rrr(r(r)rs zBoolOption.normalizeNrVrWrXrHrrr(r(r(r)r rc@r)rz-Descriptor for integer configuration options.cCrrGrrr(r(r)rr+zIntOption.accessorcC*zt|}Wn tyYnw||SrG)r*rrrr(r(r)r    zIntOption.normalizeNrr(r(r(r)rrrc@r)rz+Descriptor for float configuration options.cCrrGrrr(r(r)rr+zFloatOption.accessorcCrrG)r-rrrr(r(r)rrzFloatOption.normalizeNrr(r(r(r)rrrc@s6eZdZdZ  dddZd d Zd d Zd dZdS)rzmDescriptor for configuration options that contain multiple values separated by a specific character. NrFr7rc Cs&||_||_t|||||||dSrG)rBrCrrO) rPrhrrrBrCrLrIrJr(r(r)rOs zListOption.__init__cCs||||j|jSrG)rrBrCrr(r(r)rszListOption.accessorcsNt|ttfr!j}t|ttfr|d}|fdd|DSt|S)Nrc3s |] }t|p dVqdS)r7N)rr)r2vrr(r)r$sz#ListOption.dumps..)r9r;r<rBr?rr)rPr'rBr(rr)rs  zListOption.dumpscCs|t||j|jSrG)rrFrBrCrr(r(r)r'szListOption.normalize)NrFr7rN)rVrWrXrHrOrrrr(r(r(r)rs  rc@s&eZdZdZ  d ddZdd ZdS) rzDescriptor for configuration options providing a choice among a list of items. The default value is the first choice in the list. r7rNTc Cs<t|||t|d|||tdd|D|_||_dS)NrcSsh|]}t|qSr()rr0r2cr(r(r) 6r8z(ChoiceOption.__init__..)rrOrr;choicescase_sensitive)rPrhrr"rLrIrJr#r(r(r)rO2s  zChoiceOption.__init__cCs|||}|jdd}|jsdd|D}|}z||}Wn tyBttd|j|t |d ddt |jDdw|j|S)NcSr/r()r`rr(r(r)r4=r5z)ChoiceOption.accessor..zE[%(section)s] %(entry)s: expected one of (%(choices)s), got %(value)s, css|]}d|VqdS)z"%s"Nr(rr(r(r)rFsz(ChoiceOption.accessor..)rhrr'r") rfr"r#r`indexrr#rrrr?r)rPrhrrr'r"idxr(r(r)r9s$     zChoiceOption.accessor)r7rNT)rVrWrXrHrOrr(r(r(r)r+s  rc@seZdZdZddZdS)r zDescriptor for file system path configuration options. Relative paths are resolved to absolute paths using the directory containing the configuration file as the reference. cCrrGrrr(r(r)rRr+zPathOption.accessorN)rVrWrXrHrr(r(r(r)r Ks r c@s&eZdZdZ  d ddZddZdS) r!zName of a component implementing `interface`. Raises a `ConfigurationError` if the component cannot be found in the list of active components implementing the interface.Nr7rc Cs$t|||||||t||_dSrG)rrOr xtnpt)rPrhr interfacerrLrIrJr(r(r)rO[szExtensionOption.__init__c Csx|dur|St|||}|j|D] }|jj|kr|Sqttdt |jj jt |t d|j |j fd)NzCannot find an implementation of the %(interface)s interface named %(implementation)s. Please check that the Component is enabled or update the option %(option)s in trac.ini.[%s] %sr(implementationra) rr r' extensionsrUrVr#rrcoder(rhr)rPr r r'implr(r(r)r as zExtensionOption.__get__rrVrWrXrHrOr r(r(r(r)r!Vs  r!c@s(eZdZdZ   d ddZdd ZdS) r"zA comma separated, ordered, list of components implementing `interface`. Can be empty. If `include_missing` is true (the default) all components implementing the interface are returned, with those specified by the option ordered first. NTr7rc Cs,tj|||||||dt||_||_dS)N)rLrIrJ)rrOr r'include_missing) rPrhrr(rr0rLrIrJr(r(r)rOzs   z OrderedExtensionsOption.__init__c s|dur|St|||gg}|j|D]}||jj|js)|jjvr.|qtt t |}|r]t t dt |jjjt ddt|Dt d|j|jfdfdd}t|dS) NzCannot find implementation(s) of the %(interface)s interface named %(implementation)s. Please check that the Component is enabled or update the option %(option)s in trac.ini.css.|]\}}|dkr dndt|fVqdS)rr$N)rr-)r2r&r.r(r(r)rs  z2OrderedExtensionsOption.__get__..r)r*cs,|jj}|vrd|fSd|fS)Nrr)rUrVr%)r.rrorderr(r)rsz,OrderedExtensionsOption.__get__..keyr)rr r'r,rrUrVr0rrjr#rrr-r( enumeraterhr)rPr r implementing_classesr. not_foundrr(r1r)r s.  zOrderedExtensionsOption.__get__)NTr7rNr/r(r(r(r)r"rs r"c@sBeZdZdZeeddZddZddZdd Z d d d Z d S)ConfigurationAdminz8trac-admin command provider for trac.ini administration.ccsBddd|j|jfVddd|j|jfVddd |j|jfVdS) Nz config getz