a oec@s$dZddlZddlZddlZddlmZddlmZddlmZddlm Z m Z m Z m Z m Z mZmZmZmZmZmZmZddlmZmZdd lmZdd lmZmZdd lmZdd l m!Z!m"Z"dd l#m$Z$ddl%m&Z&e rddl'm(Z(ddl)m*Z*ee+ej,fZ-e dede ffZ.e de.fZ/ededdZ0d;e-e1dddZ2de-ddddZ3dGd9d:d:e$Z?dS)>a< Load setuptools configuration from ``setup.cfg`` files. **API will be made private in the future** To read project metadata, consider using ``build.util.project_wheel_metadata`` (https://pypi.org/project/build/). For simple scenarios, you can also try parsing the file directly with the help of ``configparser``. N) defaultdict)partialwraps) TYPE_CHECKINGCallableAnyDictGenericIterableListOptionalSetTupleTypeVarUnion) FileError OptionError)default_environment)InvalidRequirement Requirement) SpecifierSet)InvalidVersionVersion)SetuptoolsDeprecationWarning)expand)DistributionMetadata DistributionstrTarget)r r)boundF)filepathreturncCs8ddlm}|}|r|ng}t||||}t|S)a,Read given configuration file and returns options from it as a dict. :param str|unicode filepath: Path to configuration file to get options from. :param bool find_others: Whether to search for other configuration files which could be on in various places. :param bool ignore_option_errors: Whether to silently ignore options, values of which could not be resolved (e.g. due to exceptions in directives such as file:, attr:, etc.). If False exceptions are propagated as expected. :rtype: dict rr)setuptools.distr Zfind_config_files_applyconfiguration_to_dict)r$Z find_othersignore_option_errorsr dist filenameshandlersr-;C:\Program Files\Certbot\pkgs\setuptools\config\setupcfg.pyread_configuration8s  r/r )r*r$r%cCst||||S)z`Apply the configuration from a ``setup.cfg`` file into an existing distribution object. )r'Z_finalize_requires)r*r$r-r-r.apply_configurationRs r0r-) ConfigHandler.)r*r$ other_filesr)r%c Csddlm}tj|}tj|s4td|dt}ttj |g||}z4|j ||dt ||j |d}| Wt|n t|0|S)zHRead configuration from ``filepath`` and applies to the ``dist`` object.r) _DistributionzConfiguration file z does not exist.)r+)r))r&r3ospathabspathisfilergetcwdchdirdirnameZparse_config_filesparse_configurationcommand_optionsZ_finalize_license_files)r*r$r2r)r3Zcurrent_directoryr+r,r-r-r.r'[s     r') target_objkeycCs*d|}tt||}t|||}|S)z Given a target object and option key, get that option from the target object, either through a get_{key} method or from an attribute directly. Zget_) functoolsrgetattr)r=r>Z getter_nameZ by_attributegetterr-r-r. _get_optionys  rB)r,r%cCs<tt}|D]*}|jD]}t|j|}|||j|<qq |S)zReturns configuration data gathered by given handlers as a dict. :param list[ConfigHandler] handlers: Handlers list, usually from parse_configuration() :rtype: dict )rdict set_optionsrBr=section_prefix)r,Z config_dictZhandleroptionvaluer-r-r.r(s   r()ConfigMetadataHandlerConfigOptionsHandler) distributionr<r%cCst|f}t||||}||js0|j|_t|j||||j|j}||j |j|jWdn1sv0Y||fS)aPerforms additional parsing of configuration options for a distribution. Returns a list of used option handlers. :param Distribution distribution: :param dict command_options: :param bool ignore_option_errors: Whether to silently ignore options, values of which could not be resolved (e.g. due to exceptions in directives such as file:, attr:, etc.). If False exceptions are propagated as expected. :rtype: list N) rEnsurePackagesDiscoveredrIparse package_dirrHmetadatasrc_root_referenced_filesupdate)rJr<r)ensure_discoveredoptionsmetar-r-r.r;s. "r;)label orig_valueparsedc sd|vstdkrdSt}z,td}|j|vrLtj|ddWnVty}z>tfdd|Drtj |dd}t||WYd}~n d}~00dS)amBecause users sometimes misinterpret this configuration: [options.extras_require] foo = bar;python_version<"4" It looks like one requirement with an environment marker but because there is no newline, it's parsed as two requirements with a semicolon as separator. Therefore, if: * input string does not contain a newline AND * parsed result contains two requirements AND * parsing of the two parts from the result (";") leads in a valid Requirement with a valid marker a UserWarning is shown to inform the user about the possible problem.  rNr)Zfieldreqc3s|]}d|VqdS)rN startswith).0ZmarkerrWr-r. z8_warn_accidental_env_marker_misconfig..) len marker_envkeysrname_AmbiguousMarkeremitranymessage)rUrVrWZmarkersrYexmsgr-r]r.%_warn_accidental_env_marker_misconfigs   rjc@seZdZUdZeed<iZeeefed<ee e j dddZ e e ddd Zed d Zd d Ze d)ddZe ddZe ddZe ddZedddZedddZe ddZe ddZe d*d!d"Zd#d$Zd%d&Zd'd(Zd S)+r1z1Handles metadata supplied in configuration files.rEaliases)r=rSrRcCs4||_||_t|||_g|_||_t|_dSN) r)r=rC_section_optionssectionsrDrRsetrPselfr=rSr)rRr-r-r.__init__szConfigHandler.__init__)rSccs>|D]0\}}||j\}}}|r(q|d|fVqdS)N.)items partitionrElstrip)clsrSZ full_namerGZpreseprcr-r-r.rms zConfigHandler._section_optionscCstd|jjdS).Metadata item name to parser function mapping.z!%s must provide .parsers propertyN)NotImplementedError __class____name__rqr-r-r.parserss zConfigHandler.parsersc Cs|j}|j||}zt||}Wnty<t|Yn0|rFdSz|j|dd|}Wntf|jy|YdS0t |j |}t|d||}|||j |dS)NcSs|Srlr-)xr-r-r.%r_z+ConfigHandler.__setitem__..zset_%s)r=rkgetr@AttributeErrorKeyErrorr~ Exceptionr)r?r __setattr__rDappend)rqZ option_namerGr=Z current_valuerWZ simple_settersetterr-r-r. __setitem__s  zConfigHandler.__setitem__,cCs8t|tr|Sd|vr |}n ||}dd|DS)zRepresents value as a list. Value is split either by separator (defaults to comma) or by lines. :param value: :param separator: List items separator character. :rtype: list rXcSsg|]}|r|qSr-strip)r\chunkr-r-r. Ar_z-ConfigHandler._parse_list..) isinstancelist splitlinessplit)rwrG separatorr-r-r. _parse_list/s   zConfigHandler._parse_listcCsRd}i}||D]:}||\}}}||krrxvalr-r-r. _parse_dictCszConfigHandler._parse_dictcCs|}|dvS)zQRepresents value as boolean. :param value: :rtype: bool )1trueZyes)lowerrwrGr-r-r. _parse_boolTszConfigHandler._parse_boolcsfdd}|S)zReturns a parser function to make sure field inputs are not files. Parses a value after getting the key so error messages are more informative. :param key: :rtype: callable cs d}||rtd|S)Nfile:zCOnly strings are accepted for the {0} field, files are not accepted)r[ ValueErrorformat)rGZexclude_directiver>r-r.parserjs z3ConfigHandler._exclude_files_parser..parserr-)rwr>rr-rr._exclude_files_parser^s z#ConfigHandler._exclude_files_parserroot_dircCs\d}t|ts|S||s |S|t|d}dd|dD}|j|t||S)aORepresents value as a string, allowing including text from nearest files using `file:` directive. Directive is sandboxed and won't reach anything outside directory with setup.py. Examples: file: README.rst, CHANGELOG.md, src/file.txt :param str value: :rtype: str rNcSsg|] }|qSr-r)r\r5r-r-r.rr_z-ConfigHandler._parse_file..r) rr!r[r`rrPrQrZ read_files)rqrGrZinclude_directivespecZ filepathsr-r-r. _parse_fileus    zConfigHandler._parse_filecCs:d}||s|S||d}||jjt|||S)zRepresents value as a module attribute. Examples: attr: package.attr attr: package.module.attr :param str value: :rtype: str zattr:)r[replacerQrRrMrZ read_attr)rqrGrMrZattr_directiveZ attr_descr-r-r. _parse_attrs   zConfigHandler._parse_attrcsfdd}|S)zReturns parser function to represents value as a list. Parses a value applying given methods one after another. :param parse_methods: :rtype: callable cs|}D] }||}q|Srlr-)rGrWmethod parse_methodsr-r.rLs z1ConfigHandler._get_parser_compound..parser-)rwrrLr-rr._get_parser_compounds z"ConfigHandler._get_parser_compoundcCs,i}|D]\}\}}|||||<q |S)aParses section options into a dictionary. Applies a given parser to each option in a section. :param dict section_options: :param callable values_parser: function with 2 args corresponding to key, value :rtype: dict )rt)rwsection_options values_parserrGr>_rr-r-r._parse_section_to_dict_with_keys z-ConfigHandler._parse_section_to_dict_with_keyNcs$rfddndd}|||S)aParses section options into a dictionary. Optionally applies a given parser to each value. :param dict section_options: :param callable values_parser: function with 1 arg corresponding to option value :rtype: dict cs|Srlr-rvrr-r.rr_z6ConfigHandler._parse_section_to_dict..cSs|Srlr-rr-r-r.rr_r)rwrrrr-rr._parse_section_to_dicts z$ConfigHandler._parse_section_to_dictc CsL|D]>\}\}}tt|||<Wdq1s<0YqdS)zQParses configuration file section. :param dict section_options: N)rt contextlibsuppressr)rqrrcrrGr-r-r. parse_sections zConfigHandler.parse_sectioncCsh|jD]X\}}d}|r"d|}t|d|ddd}|durZtd|jd|d||q dS) zTParses configuration file items from one or more related sections. rz_%szparse_section%srs__Nz*Unsupported distribution option section: [])rnrtr@rrrE)rqZ section_namerZmethod_postfixZsection_parser_methodr-r-r.rLs$zConfigHandler.parsec stfdd}|S)zthis function will wrap around parameters that are deprecated :param msg: deprecation message :param func: function to be wrapped around cs.ddtjdfi|i|S)N stacklevelrz Deprecated config in `setup.cfg`) setdefault_DeprecatedConfigre)argskwargsfunckwrir-r.config_handlers z@ConfigHandler._deprecated_config_handler..config_handlerr)rqrrirrr-rr._deprecated_config_handlersz(ConfigHandler._deprecated_config_handler)r)N)r| __module__ __qualname____doc__r!__annotations__rkr r"AllCommandOptionsrrKrr classmethodrmpropertyr~rrrrr_PathrrrrrrrLrr-r-r-r.r1s>            r1csdeZdZdZdddddZdZdejfd ee e j e e ed fd d Zed dZddZZS)rHrNurl description classifiers platforms)Z home_pageZsummaryZ classifierplatformFNr)r=rSr)rRrMrcs"t||||||_||_dSrl)superrrrMr)rqr=rSr)rRrMrr{r-r.rrs zConfigMetadataHandler.__init__c CsL|j}t|j|jd}|j}|j}||||||||d||||j|d S)ryrlicense) rkeywordsZprovidesZ obsoletesrrZ license_filesrZlong_descriptionversionZ project_urls)rrrrrrr_parse_version)rq parse_listZ parse_file parse_dictZexclude_files_parserr-r-r.r~#s  zConfigMetadataHandler.parserscCsn|||j}||krV|}z t|Wn&tyPtd|d|Yn0|St|||j |jS)zSParses `version` option value. :param value: :rtype: str zVersion loaded from z does not comply with PEP 440: ) rrrrrrrrrrM)rqrGrr-r-r.r9s   z$ConfigMetadataHandler._parse_version)r|rrrErkZ strict_moder4curdirrboolrrKr rCrrrrr~r __classcell__r-r-rr.rHs(   rHrcseZdZdZdeeejdfdd Ze ddZ dd Z e e d d d Z ed dZddZddZddZddZddZddZddZddZdd ZZS)!rIrSr )r=rSr)rRcs$t|||||j|_i|_dSrl)rrrrOrrMrprr-r.rrVszConfigOptionsHandler.__init__cCs|j|ddS)N;)r)rrr-r-r._parse_list_semicolonasz*ConfigOptionsHandler._parse_list_semicoloncCs|j||jdS)Nr)rr)rqrGr-r-r._parse_file_in_rootesz(ConfigOptionsHandler._parse_file_in_root)rUrGcCs*|||}t|||dd|DS)NcSsg|]}|ds|qS)#rZ)r\rr-r-r.rnr_zAConfigOptionsHandler._parse_requirements_list..)rrrj)rqrUrGrWr-r-r._parse_requirements_lisths z-ConfigOptionsHandler._parse_requirements_listcCsT|j}|j}|j}|j}||||||||dt|jd|j|j|j|j |t |dS)ryzeThe namespace_packages parameter is deprecated, consider using implicit namespaces instead (PEP 420).install_requires)Zzip_safeZinclude_package_datarMZscriptsZeager_resourcesZdependency_linksZnamespace_packagesrZsetup_requiresZ tests_requireZpackages entry_pointsZ py_modulesZpython_requirescmdclass) rrr_parse_cmdclassrrrr_parse_packagesrr)rqrZ parse_boolrZparse_cmdclassr-r-r.r~ps2zConfigOptionsHandler.parserscCs|jj}t||||jSrl)rRrMrrrr)rqrGrMr-r-r.rsz$ConfigOptionsHandler._parse_cmdclasscCsbddg}|}||vr"||S||jdi}|j||dk|j|jdtj fi|S)zTParses `packages` option value. :param value: :rtype: list zfind:zfind_namespace:z packages.findr)Z namespacesrZfill_package_dir) rrparse_section_packages__findrnrrQrrMrZ find_packages)rqrGZfind_directivesZ trimmed_value find_kwargsr-r-r.rs   z$ConfigOptionsHandler._parse_packagescsR|||j}gdtfdd|D}|d}|durN|d|d<|S)zParses `packages.find` configuration file section. To be used in conjunction with _parse_packages(). :param dict section_options: )whereZincludeZexcludecs$g|]\}}|vr|r||fqSr-r-)r\krZ valid_keysr-r.rr_zEConfigOptionsHandler.parse_section_packages__find..rNr)rrrCrtr)rqrZ section_datarrr-rr.rs  z1ConfigOptionsHandler.parse_section_packages__findcCs|||j}||d<dS)z`Parses `entry_points` configuration file section. :param dict section_options: rN)rrrqrrWr-r-r.parse_section_entry_pointssz/ConfigOptionsHandler.parse_section_entry_pointscCs|||j}t|Srl)rrrZcanonic_package_data)rqr package_datar-r-r._parse_package_datasz(ConfigOptionsHandler._parse_package_datacCs|||d<dS)z`Parses `package_data` configuration file section. :param dict section_options: rNrrqrr-r-r.parse_section_package_datasz/ConfigOptionsHandler.parse_section_package_datacCs|||d<dS)zhParses `exclude_package_data` configuration file section. :param dict section_options: Zexclude_package_dataNrrr-r-r."parse_section_exclude_package_datasz7ConfigOptionsHandler.parse_section_exclude_package_datacs |fdd}|d<dS)zbParses `extras_require` configuration file section. :param dict section_options: csd|d|S)Nzextras_require[r)r)rrr}r-r.rr_zCConfigOptionsHandler.parse_section_extras_require..Zextras_requireNrrr-r}r.parse_section_extras_requires  z1ConfigOptionsHandler.parse_section_extras_requirecCs$|||j}t||j|d<dS)z^Parses `data_files` configuration file section. :param dict section_options: Z data_filesN)rrrZcanonic_data_filesrrr-r-r.parse_section_data_filessz-ConfigOptionsHandler.parse_section_data_files)r|rrrErrrrKrrrrrr!rrr~rrrrrrrrrrr-r-rr.rISs*    rIc@s$eZdZdZdZdZeddZdS)rdzAmbiguous requirement marker.z One of the parsed requirements in `{field}` looks like a valid environment marker: {req!r} Please make sure that the configuration file is correct. You can use dangling lines to avoid this problem. z'userguide/declarative_config.html#opt-2cKs"d|j}|j|j|j||dS)Nz%https://setuptools.pypa.io/en/latest/)Zsee_urlZ format_args) _SEE_DOCS_format_SUMMARY_DETAILS)rwrZdocsr-r-r.rgs z_AmbiguousMarker.messageN)r|rrrrrrrgr-r-r-r.rds rdc@seZdZdZdS)rz!userguide/declarative_config.htmlN)r|rrrr-r-r-r.rsr)FF)r-F)F)@rrr?r4 collectionsrrrtypingrrrr r r r r rrrrerrorsrrZextern.packaging.markersrraZextern.packaging.requirementsrrZextern.packaging.specifiersrZextern.packaging.versionrrwarningsrrrZdistutils.distrr&r r!PathLikerZSingleCommandOptionsrr"rCr/r0rr'rBr(r;rrjr1rHrIrdrr-r-r-r.sj    8            . #M