a oe;@sddlmZddlmZddlmZddlmmZddl Z ddl Z ddl Z ddl Z ddlZddlZddlmZddlmZmZmZmZmZmZddlmZdd lmZd Zd d ZGd ddejZddZGdddZ dS))partial)glob) convert_pathN)Path)DictIterableIteratorListOptionalTuple)unique_everseen)SetuptoolsDeprecationWarning)z*.pyizpy.typedcCst|t|jtjBdSN)oschmodstatst_modeS_IWRITE)targetrr?r@r1r$rrrget_data_files_without_manifest[sz(build_py.get_data_files_without_manifestcsJ||tjj|jg|d}fdd||D}|||fS)N.csg|]}tj|qSr)rpathrelpath).0filesrc_dirrr msz0build_py._get_pkg_data_files..)get_package_dirrrEjoin build_libsplitfind_data_files)r%r< build_dir filenamesrrIrr@es    zbuild_py._get_pkg_data_filescCsd|j|j||td}tttdd|}tj|}t t j j |}t|j |g|}||||S)z6Return filenames for package's data files in 'src_dir')extra_patternsT) recursive)_get_platform_patternsr _IMPLICIT_DATA_FILESr?rr itertoolschain from_iterablefilterrrEisfilerAgetexclude_data_files)r%r<rJpatternsZglobs_expandedZ globs_matchesZ glob_filesfilesrrrrPss  zbuild_py.find_data_files)returncs"|jrt|St|S)1See :class:`setuptools.commands.build.SubCommand`)rr>get_output_mappingkeysr)r3)r%r0r.rrr3szbuild_py.get_outputscCs(t||}tt|dddS)racSs|dS)Nrr)xrrrz-build_py.get_output_mapping..)key)rWrX _get_package_data_output_mapping_get_module_mappingdictsorted)r%mappingrrrrbs zbuild_py.get_output_mappingccs<|D].\}}}|d}||j||}||fVqdS)z5Iterate over all modules producing (dest, src) pairs.rDN)Zfind_all_modulesrOZget_module_outfilerN)r%r<r:r;filenamerrrris zbuild_py._get_module_mappingccsH|jD]<\}}}}|D]*}tj||}tj||}||fVqqdS)z6Iterate over package data producing (dest, src) pairs.N)rrrErM)r%r<rJrQrRrmrsrcfilerrrrhs z)build_py._get_package_data_output_mappingcCs@|D]2\}}|tj||||\}}t|qdS)z$Copy data files into build directoryN)rhZmkpathrrEdirnamer*r)r%rrnZ_outfZ_copiedrrrr2szbuild_py.build_package_datacCsji|_}|jjsdSi}|jp"dD]}||t||<q$t|ddrzt|jd rz|j}t|d}|j dd }n"| d| d}|j}|jj}t}|||D]} tjt| \} } d} | } | r | | kr | |vr | } tj| \} }tj|| } q| |vr| | kr.|| rNqn ||| | }|rN||||| g| qdS)Nrrz SOURCES.txtzutf-8)encodingegg_info)rArZinclude_package_datar1assert_relativerLgetattrrrexists read_text splitlinesZ run_commandget_finalized_commandrqZfilelistr__IncludePackageDataAbuse_filter_build_filesrrErOrM is_moduleimportable_subpackagewarnrBr9)r%ZmfZsrc_dirsr<Z egg_info_dirZmanifestr_Zei_cmdcheckrEdfprevZoldfZdf importablerrrr=sD        zbuild_py.analyze_manifest)r_rqr`c#sl|d}||j|j|jf}dd|D}|D]8}tj|tj|r`tfdd|Dr.|Vq.dS)a} ``build_meta`` may try to create egg_info outside of the project directory, and this can be problematic for certain plugins (reported in issue #3500). Extensions might also include between their sources files created on the ``build_lib`` and ``build_temp`` directories. This function should filter this case of invalid files out. buildcSsg|]}|rtj|qSr)rrEnormpath)rGprrrrKrfz0build_py._filter_build_files..c3s|]}|vVqdSrr)rGr~Z norm_pathrr rfz/build_py._filter_build_files..N) rwrNZ build_tempZ build_baserrErisabsall)r%r_rqrZ build_dirsZ norm_dirsrHrrrrys  "zbuild_py._filter_build_filescCsdSrrr$rrrget_data_filesszbuild_py.get_data_filescCsz |j|WStyYn0tj|||}||j|<|rF|jjsJ|S|jjD]}||ksl||drRqvqR|St|d}| }Wdn1s0Yd|vrt j d|f|S)z8Check namespace packages' __init__ for declare_namespacerDrbNsdeclare_namespacezNamespace package problem: %s is a namespace package, but its __init__.py does not call declare_namespace()! Please fix it. (See the setuptools manual under "Namespace Packages" for details.) ") packages_checkedKeyErrorrr check_packagerZnamespace_packages startswithopenread distutilserrorsZDistutilsError)r%r<Z package_dirZinit_pypkgrcontentsrrrrs*      &zbuild_py.check_packagecCs"i|_tj|d|_d|_dS)NF)rrrinitialize_optionsrrr$rrrrs zbuild_py.initialize_optionscCs0tj||}|jjdur,tj|jj|S|Sr)rrrLrZsrc_rootrrErM)r%r<resrrrrL s zbuild_py.get_package_dircs\t||j||}fdd|D}tj|}t|fddD}tt|S)z6Filter filenames for package's data files in 'src_dir'c3s|]}t|VqdSr)fnmatchrZrGpattern)r_rrrrfz.build_py.exclude_data_files..c3s|]}|vr|VqdSrr)rGfn)badrrrrf)r>rUr!rWrXrYsetr )r%r<rJr_r^Z match_groupsmatchesZkeepersr)rr_rr]s zbuild_py.exclude_data_filescs0t||dg||g}fdd|DS)z yield platform-specific path patterns (suitable for glob or fn_match) from a glob-based spec (such as self.package_data or self.exclude_package_data) matching package in src_dir. c3s |]}tjt|VqdSr)rrErMrrrIrrr/sz2build_py._get_platform_patterns..)rWrXr\)specr<rJrSZ raw_patternsrrIrrU"s   zbuild_py._get_platform_patterns)r&r&Nr&)r&)'__name__ __module__ __qualname____doc__rbool__annotations__rr r'rr*r4r6r8r5rCr@rPr r3rrbrr rirhr2r=rryrrrrLr] staticmethodrU __classcell__rrr.rrs6     )rcCs:tj|s|Sddlm}td|}||dS)Nr)DistutilsSetupErrorz Error: setup script specifies an absolute path: %s setup() arguments must *always* be /-separated paths relative to the setup.py directory, *never* absolute paths. )rrErdistutils.errorsrtextwrapdedentlstrip)rErmsgrrrrr6s    rrc@s@eZdZdZGdddeZddZddZdd Zd d Z d S) rxz>Inform users that package or module is included as 'data file'c@seZdZdZdZdS)z!_IncludePackageDataAbuse._WarningzU Package {importable!r} is absent from the `packages` configuration. a| ############################ # Package would be ignored # ############################ Python recognizes {importable!r} as an importable package[^1], but it is absent from setuptools' `packages` configuration. This leads to an ambiguous overall configuration. If you want to distribute this package, please make sure that {importable!r} is explicitly added to the `packages` configuration field. Alternatively, you can also rely on setuptools' discovery methods (for example by using `find_namespace_packages(...)`/`find_namespace:` instead of `find_packages(...)`/`find:`). You can read more about "package discovery" on setuptools documentation page: - https://setuptools.pypa.io/en/latest/userguide/package_discovery.html If you don't want {importable!r} to be distributed and are already explicitly excluding {importable!r} via `find_namespace_packages(...)/find_namespace` or `find_packages(...)/find`, you can try to use `exclude_package_data`, or `include-package-data=False` in combination with a more fine grained `package-data` configuration. You can read more about "package data files" on setuptools documentation page: - https://setuptools.pypa.io/en/latest/userguide/datafiles.html [^1]: For Python, any directory (with suitable naming) can be imported, even if it does not contain any `.py` files. On the other hand, currently there is no concept of package data directory, all directories are treated like packages. N)rrrZ_SUMMARYZ_DETAILSrrrr_WarningNsrcCs t|_dSr)r_already_warnedr$rrr__init__ysz!_IncludePackageDataAbuse.__init__cCs |do|dtd S)Nz.py)endswithlen isidentifier)r%rHrrrrz|sz"_IncludePackageDataAbuse.is_modulecCs6t|j}tttj|j}|r2d|g|SdS)NrD) rparentr>rW takewhiler'rpartsrM)r%rrHrrrrrr{s  z._IncludePackageDataAbuse.importable_subpackagecCs(||jvr$|jj|d|j|dS)N)r)rremitadd)r%rrrrr|s z_IncludePackageDataAbuse.warnN) rrrrrrrrzr{r|rrrrrxKs +rx)! functoolsrrZdistutils.utilrZdistutils.command.build_pyZcommandrrrrrrrrWrpathlibrtypingrrrr r r Zextern.more_itertoolsr warningsrrVrrrrxrrrrs(