_dHf 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 r ddl'm(Z(ddl)m*Z*ee+ejXfZ-e dede ffZ. e de.fZ/ededZ0 d8de-de1fdZ2ddde-ddfdZ3 d9ddde-dee-de4dedf dZ5d e0d!e+fd"Z6d#edde1fd$Z7 d:d%dd&e/ded'fd(Z8d)e+d*e+d+e9fd,Z:Gd-d.e e0Z;Gd/d0e;d1Z<Gd2d3e;dZ=Gd4d5e$Z>Gd6d7e$Z?y);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)boundfilepathreturncvddlm}|}|r|jng}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!find_config_files_applyconfiguration_to_dict)r% find_othersignore_option_errorsr!dist filenameshandlerss D,7&&(RIdHi1EFH  **r.r!c>t|||j|S)z`Apply the configuration from a ``setup.cfg`` file into an existing distribution object. )r*_finalize_requires)r.r%s r1apply_configurationr6Rs 4 Kr3 other_filesr-) ConfigHandler.cddlm}tjj |}tjj |st d|dtj}tjtjj|g||} |j||t||j|}|jtj||S#tj|wxYw)zHRead configuration from ``filepath`` and applies to the ``dist`` object.r) _DistributionzConfiguration file z does not exist.)r/)r-)r(r:ospathabspathisfilergetcwdchdirdirnameparse_config_filesparse_configurationcommand_options_finalize_license_files)r.r%r7r-r:current_directoryr/r0s r1r*r*[s.wwx(H 77>>( #-hZ7GHII HHRWW__X &'(+(x(I$(((C& $&&=Q  $$& "# O "#s !;C33D  target_objkeycjd|}tjt||}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. get_) functoolsrgetattr)rGrH getter_name by_attributegetters r1 _get_optionrPys8 ,K$$Wj#>L Zl ;F 8Or3r0ctt}|D];}|jD]*}t|j|}|||j |<,=|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_optionsrPrGsection_prefix)r0 config_dicthandleroptionvalues r1r+r+se$D)K@)) @F 2 2F;E:?K.. / 7 @@ r3 distributionrD)ConfigMetadataHandlerConfigOptionsHandlerc tj|5}t||||}|j|js|j|_t |j ||||j|j}|j|jj|j|jddd||fS#1swYfSxYw)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) rEnsurePackagesDiscoveredr[parse package_dirrZmetadatasrc_root_referenced_filesupdate)rYrDr-ensure_discoveredoptionsmetas r1rCrCs$  ( ( 6 :K&       '''.':':L $$  ! !    $ $  ! !   &&--  % %t'='= + 2 =3 2 =s B*C  Clabel orig_valueparsedcld|vstdk7rytj} td}|j|vrt j |dyy#t$rD}tfd|Dr&t j|d}t||Yd}~yd}~wwxYw)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)fieldreqc3FK|]}dj|yw)rN) startswith).0markerris r1 z8_warn_accidental_env_marker_misconfig..s Bvay##F+Bs!) len marker_envkeysrname_AmbiguousMarkeremitranymessage)rgrhrimarkersrmexmsgs ` r1%_warn_accidental_env_marker_misconfigr~s" zS[A-l!G2&)$ 88w   ! !6!9 ! =  2 B'B B"**F1I*FC$S)r 1 C2s6A&& B3/:B..B3c*eZdZUdZeed< iZeeefed< dede de jfdZ e de fdZed Zd Ze dd Ze d Ze d Ze dZdefdZdefdZe dZe dZe ddZdZdZdZy)r8z1Handles metadata supplied in configuration files.rTaliasesrGrerdc||_||_t|j||_g|_||_t|_yN) r-rGrR_section_optionssectionsrSrdsetrb)selfrGrer-rds r1__init__zConfigHandler.__init__sI%9!$T227;< &(!2+.5 r3c#K|jD]<\}}|j|j\}}}|r(|jd|f>yw)N.)items partitionrTlstrip)clsre full_namerXpreseprvs r1rzConfigHandler._section_optionssV '  * Iu&001C1CDNCd++c"E) )  *sAAcFtd|jjz).Metadata item name to parser function mapping.z!%s must provide .parsers property)NotImplementedError __class____name__)rs r1parserszConfigHandler.parserss#" /$..2I2I I  r3c|j}|jj||} t||}|ry |j j|d|}tj|j|}t|d|z|}|||jj|y#t$r t |wxYw#tf|jz$rYywxYw)Nc|Sr)xs r1z+ConfigHandler.__setitem__..%sQr3zset_%s)rGrgetrLAttributeErrorKeyErrorr Exceptionr-rKr __setattr__rSappend)r option_namerXrG current_valueri simple_settersetters r1 __setitem__zConfigHandler.__setitem__s__ ll&&{K@  (#J .parserjs: '  12 --3VC[Lr3r)rrHrs ` r1_exclude_files_parserz#ConfigHandler._exclude_files_parser^s  r3root_dirc0d}t|ts|S|j|s|S|t|d}|j dDcgc]}|j }}|j j|tj||Scc}w)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 rN,) rr"rorsrrrbrcr read_files)rrXrinclude_directivespecr< filepathss r1 _parse_filezConfigHandler._parse_fileus$%%L 12LS*+-..2jjo>dTZZ\> > %%i0  H55?s Bcd}|j|s|S|j|d}|j|jjt j |||S)zRepresents value as a module attribute. Examples: attr: package.attr attr: package.module.attr :param str value: :rtype: str zattr:)roreplacercrdr_r read_attr)rrXr_rattr_directive attr_descs r1 _parse_attrzConfigHandler._parse_attrs]!/LMM."5  411==> ;AAr3cfd}|S)zReturns parser function to represents value as a list. Parses a value applying given methods one after another. :param parse_methods: :rtype: callable c*|}D] }||} |Srr)rXrimethod parse_methodss r1r^z1ConfigHandler._get_parser_compound..parses'F' ( (Mr3r)rrr^s ` r1_get_parser_compoundz"ConfigHandler._get_parser_compounds  r3cXi}|jD]\}\}}|||||<|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 )r)rsection_options values_parserrXrH_rs r1_parse_section_to_dict_with_keyz-ConfigHandler._parse_section_to_dict_with_keys>,224 1MC!S&sC0E#J 1 r3Nc<rfdnd}|j||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 c|Srr)rvrs r1rz6ConfigHandler._parse_section_to_dict..s }Q/r3c|Srr)rrs r1rz6ConfigHandler._parse_section_to_dict..sUVr3r)rrrrs ` r1_parse_section_to_dictz$ConfigHandler._parse_section_to_dicts#5B/22?FKKr3c|jD]/\}\}}tjt5|||<ddd1y#1swY "/ 2% 3r3c 6tfd}|S)zthis function will wrap around parameters that are deprecated :param msg: deprecation message :param func: function to be wrapped around cfjddtjdfi|i|S)N stacklevelrz Deprecated config in `setup.cfg`) setdefault_DeprecatedConfigrx)argskwargsfunckwr}s r1config_handlerz@ConfigHandler._deprecated_config_handler..config_handlers7 MM, *  " "#Es Qb Q(( (r3r)rrr}rrs ``` r1_deprecated_config_handlerz(ConfigHandler._deprecated_config_handlers# t )  ) r3)rr)r __module__ __qualname____doc__r"__annotations__rr r#AllCommandOptionsrr]r classmethodrpropertyrrrrrr_Pathrrrrrrr^rrr3r1r8r8s>; !GT#s(^    # "::  "*'8**  -4CC& --,6564BB(&   L L#32 r3r8c eZdZdZdddddZdZ dejfd d d ed e d e jde e def fd ZedZdZxZS)rZr`url description classifiers platforms) home_pagesummary classifierplatformFNrGrrer-rdr_rcFt|||||||_||_yr)superrr_r)rrGrer-rdr_rrs r1rzConfigMetadataHandler.__init__s) W.BDUV&  r3c@|j}t|j|j}|j}|j }||||j |dd||j|||d|j |ddd||||j|d S) rrz[The requires parameter is deprecated, please use install_requires for runtime dependencies.)i )due_datelicense license_filezDThe license_file parameter is deprecated, use license_files instead.) rkeywordsprovidesrequires obsoletesrrr license_filesrlong_descriptionversion project_urls) rrrrrrrr_parse_version)r parse_list parse_file parse_dictexclude_files_parsers r1rzConfigMetadataHandler.parsers#s%% T-- F %% #99$""77=' 8$44ZL+I6 ;;$^4-' <(% ***&3  r3c0|j||j}||k7r|j} t||St j|j||j|jS#t$rt d|d|wxYw)zSParses `version` option value. :param value: :rtype: str zVersion loaded from z does not comply with PEP 440: ) rrrrrrrrrr_)rrXrs r1rz$ConfigMetadataHandler._parse_versionGs""5$--8 e mmoG  N~~d..ud6F6F VWW" !*5'2,,396 s A::B)rrrrTr strict_moder;curdirrboolrr]rrRrrrrr __classcell__rs@r1rZrZsN # GK'+)) !* !# !# ! ":: ! d^ ! !! ! FXr3rZrceZdZdZdddededejffd Ze dZ dZ d e d e fd Z ed Zd ZdZdZdZdZdZdZdZdZxZS)r[rerGr!r-rdcZt||||||j|_i|_yr)r rrarr_)rrGrer-rdrs r1rzConfigOptionsHandler.__init__ds/ W.BDUV"++ +-r3c(|j|dS)N;)r)rrs r1_parse_list_semicolonz*ConfigOptionsHandler._parse_list_semicolonosu44r3c<|j||jS)Nr )rr)rrXs r1_parse_file_in_rootz(ConfigOptionsHandler._parse_file_in_rootss >>r3rgrXc|j|j|}t||||Dcgc]}|jdr|c}Scc}w)N#)r*r,r~ro)rrgrXrirs r1_parse_requirements_listz-ConfigOptionsHandler._parse_requirements_listvsJ++D,D,DU,KL-eUFC"(Dts/CDDDs A Ac&|j}|j}|j}|j}|||||||j |dt |j d|j|j|j|j|t|dS)rzeThe namespace_packages parameter is deprecated, consider using implicit namespaces instead (PEP 420).install_requires)zip_safeinclude_package_datar_scriptseager_resourcesdependency_linksnamespace_packagesr1setup_requires tests_requirepackages entry_points py_modulespython_requirescmdclass) rrr_parse_cmdclassrrr/r*_parse_packagesr,r)rr parse_boolrparse_cmdclasss r1rzConfigOptionsHandler.parsers~s%% %% %% --#$.%!) *"&"A"AH# !(--/A!#88!77,, 44$+&-  r3c|jj}tj|j |||j Sr)rdr_rr>rr)rrXr_s r1r?z$ConfigOptionsHandler._parse_cmdclasss5,,88 t//6 T]]SSr3c0ddg}|j}||vr|j|S|j|jj di}|j ||dk(|j |jtjdi|S)zTParses `packages` option value. :param value: :rtype: list zfind:zfind_namespace:z packages.findr) namespacesrfill_package_dirr) rrparse_section_packages__findrrrcrr_r find_packages)rrXfind_directives trimmed_value find_kwargss r1r@z$ConfigOptionsHandler._parse_packagess #$56  /##E* *77 MM  or 2  %);;]]!--  ##2k22r3c|j||j}gd}t|jDcgc]\}}||vs |s||fc}}}|j d}||d|d<|Scc}}w)zParses `packages.find` configuration file section. To be used in conjunction with _parse_packages(). :param dict section_options: )whereincludeexcluderMr)rrrRrr)rr section_data valid_keyskrrKrMs r1rGz1ConfigOptionsHandler.parse_section_packages__finds22?DDTDTU 4  , 2 2 4 N1ZAaV N (  #(8K  Os A4 A4 A4 cF|j||j}||d<y)z`Parses `entry_points` configuration file section. :param dict section_options: r;N)rrrrris r1parse_section_entry_pointsz/ConfigOptionsHandler.parse_section_entry_pointss& ,,_d>N>NO%^r3cd|j||j}tj|Sr)rrrcanonic_package_data)rr package_datas r1_parse_package_dataz(ConfigOptionsHandler._parse_package_datas+22?DDTDTU **<88r3c,|j||d<y)z`Parses `package_data` configuration file section. :param dict section_options: rXNrYrrs r1parse_section_package_dataz/ConfigOptionsHandler.parse_section_package_datas $77H^r3c,|j||d<y)zhParses `exclude_package_data` configuration file section. :param dict section_options: exclude_package_dataNr[r\s r1"parse_section_exclude_package_dataz7ConfigOptionsHandler.parse_section_exclude_package_datas (,'?'?'P #$r3c:j|fd}|d<y)zbParses `extras_require` configuration file section. :param dict section_options: c0jd|d|S)Nzextras_require[r)r/)rRrrs r1rzCConfigOptionsHandler.parse_section_extras_require..s6617MqQr3extras_requireNrrTs` r1parse_section_extras_requirez1ConfigOptionsHandler.parse_section_extras_requires( 55  Q  "( r3c|j||j}tj||j|d<y)z^Parses `data_files` configuration file section. :param dict section_options: data_filesN)rrrcanonic_data_filesrrTs r1parse_section_data_filesz-ConfigOptionsHandler.parse_section_data_filess7 ,,_d>N>NO#66vt}}M\r3)rrrrTrr#rr]rrr*r,r"r/rrr?r@rGrUrYr]r`rdrhr$r%s@r1r[r[asN ." .# .# . ":: .55?EcE#E  @T32*&9IQ (Nr3r[c(eZdZdZdZdZedZy)rwzAmbiguous 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-2c rd|j}|j|j|j||S)Nz%https://setuptools.pypa.io/en/latest/)see_url format_args) _SEE_DOCS_format_SUMMARY_DETAILS)rrdocss r1rzz_AmbiguousMarker.messages26s}}oF{{3<<tQS{TTr3N)rrrrorprmrrzrr3r1rwrws+.HH:IUUr3rwceZdZdZy)rz!userguide/declarative_config.htmlN)rrrrmrr3r1rrs3Ir3r)FF)rF)F)@rrrKr; collectionsrrrtypingrrr r r r r rrrrrerrorsrrextern.packaging.markersrrtextern.packaging.requirementsrrextern.packaging.specifiersrextern.packaging.versionrrwarningsrrrdistutils.distrr(r!r"PathLikerSingleCommandOptionsrr#rRr2r6r#r*rPr+rCrr~r8rZr[rwrrr3r1r~s  #    ,HK6>33, c2;;E5#445  445 'M!N O>C++ +4n.$&!&  %    < F  E*>$?D*+ +&+ :; +\22#2t2@^GFO^B XXM*@AXXv\N=8\N~U3U(444r3