o gK@sddlZddlZddlZddlZddlZddlZddlZddlm Z m Z m Z m Z m Z mZmZmZmZmZddlmZddlmZmZddlmZddlmZmZddlmZddlm Z m!Z!dd l"m#Z#m$Z$m%Z%dd l&m'Z'dd l(m)Z)m*Z*dd l+m,Z,m-Z-dd l.m/Z/e rddlm0Z0ne1Z0eeefZ2ee3ej4fZ5e6e7Z8Gddde0Z9dee3dfdee3dfde3fddZ:Gddde0Z;GdddZGdd d e=Z?dS)!N) IO TYPE_CHECKING Collection ContainerIterableIteratorListOptionalTupleUnion) Requirement)InvalidSpecifier SpecifierSet)NormalizedName) LegacyVersionVersion)NoneMetadataError) site_packages user_site)DIRECT_URL_METADATA_NAME DirectUrlDirectUrlValidationError) stdlib_pkgs)egg_link_path_from_locationegg_link_path_from_sys_path)is_localnormalize_path) url_to_path)Protocolc@sBeZdZedefddZedefddZedefddZdS) BaseEntryPointreturncCtNNotImplementedErrorselfr'=/usr/lib/python3/dist-packages/pip/_internal/metadata/base.pyname6zBaseEntryPoint.namecCr!r"r#r%r'r'r(value:r*zBaseEntryPoint.valuecCr!r"r#r%r'r'r(group>r*zBaseEntryPoint.groupN)__name__ __module__ __qualname__propertystrr)r+r,r'r'r'r(r5srentry.infor cCsj|r)|ddkr)|r|ddkr|d7}n|dd}|dd}|r)|ddksttjg||RS)aConvert a legacy installed-files.txt path into modern RECORD path. The legacy format stores paths relative to the info directory, while the modern format stores paths relative to the package root, e.g. the site-packages directory. :param entry: Path parts of the installed-files.txt entry. :param info: Path parts of the egg-info directory relative to package root. :returns: The converted entry. For best compatibility with symlinks, this does not use ``abspath()`` or ``Path.resolve()``, but tries to work with path parts: 1. While ``entry`` starts with ``..``, remove the equal amounts of parts from ``info``; if ``info`` is empty, start appending ``..`` instead. 2. Join the two directly. r..)r4Nr1pathlibPath)r2r3r'r'r(_convert_installed_files_pathCs   r:c@s|eZdZdefddZdefddZedeefddZedeefdd Z edeefd d Z edeefd d Z ede fddZ ede fddZede fddZede fddZedefddZedefddZedefddZedeefddZedefddZede fd d!Zede fd"d#Zede fd$d%Zede fd&d'Zd(ede fd)d*Zd(edee j!fd+d,Z"d(edefd-d.Z#de$e%fd/d0Z&ede'j(j)fd1d2Z*edeefd3d4Z+edefd5d6Z,ede-fd7d8Z.dFd:e/ede$e0fd;d<Z1de$efd=d>Z2deeefd?d@Z3deeefdAdBZ4deeefdCdDZ5dES)GBaseDistributionr cCs|jd|jd|jdS)N z ())raw_nameversionlocationr%r'r'r(__repr__bszBaseDistribution.__repr__cCs|jd|jS)Nr<)r>r?r%r'r'r(__str__eszBaseDistribution.__str__cCr!)aWhere the distribution is loaded from. A string value is not necessarily a filesystem path, since distributions can be loaded from other sources, e.g. arbitrary zip archives. ``None`` means the distribution is created in-memory. Do not canonicalize this value with e.g. ``pathlib.Path.resolve()``. If this is a symbolic link, we want to preserve the relative path between it and files in the distribution. r#r%r'r'r(r@hs zBaseDistribution.locationcCs8|j}|r|rt|jSdSt|j}|r|jSdS)zThe project location for editable distributions. This is the directory where pyproject.toml or setup.py is located. None if the distribution is not installed in editable mode. N) direct_urlis_local_editablerurlrr>r@)r&rC egg_link_pathr'r'r(editable_project_locationvs  z*BaseDistribution.editable_project_locationcCs2t|j}|r |}t|S|jr|j}t|SdS)aThe distribution's "installed" location. This should generally be a ``site-packages`` directory. This is usually ``dist.location``, except for legacy develop-installed packages, where ``dist.location`` is the source code location, and this is where the ``.egg-link`` file is. The returned location is normalized (in particular, with symlinks removed). N)rr>r@r)r&egg_linkr@r'r'r(installed_locations z#BaseDistribution.installed_locationcCr!)a/Location of the .[egg|dist]-info directory or file. Similarly to ``location``, a string value is not necessarily a filesystem path. ``None`` means the distribution is created in-memory. For a modern .dist-info installation on disk, this should be something like ``{location}/{raw_name}-{version}.dist-info``. Do not canonicalize this value with e.g. ``pathlib.Path.resolve()``. If this is a symbolic link, we want to preserve the relative path between it and other files in the distribution. r#r%r'r'r( info_locationszBaseDistribution.info_locationcCs|j}|sdSt|S)aWhether this distribution is installed with legacy distutils format. A distribution installed with "raw" distutils not patched by setuptools uses one single file at ``info_location`` to store metadata. We need to treat this specially on uninstallation. F)rJr8r9is_filer&rJr'r'r(installed_by_distutilssz'BaseDistribution.installed_by_distutilscCs|j}|sdS|dS)zWhether this distribution is installed as an egg. This usually indicates the distribution was installed by (older versions of) easy_install. Fz.egg)r@endswithr&r@r'r'r(installed_as_eggs z!BaseDistribution.installed_as_eggcC*|j}|sdS|dsdSt|S)aWhether this distribution is installed with the ``.egg-info`` format. This usually indicates the distribution was installed with setuptools with an old pip version or with ``single-version-externally-managed``. Note that this ensure the metadata store is a directory. distutils can also installs an ``.egg-info``, but as a file, not a directory. This property is *False* for that case. Also see ``installed_by_distutils``. Fz .egg-inforJrNr8r9is_dirrLr'r'r("installed_with_setuptools_egg_infos   z3BaseDistribution.installed_with_setuptools_egg_infocCrQ)aaWhether this distribution is installed with the "modern format". This indicates a "modern" installation, e.g. storing metadata in the ``.dist-info`` directory. This applies to installations made by setuptools (but through pip, not directly), or anything using the standardized build backend interface (PEP 517). Fz .dist-inforRrLr'r'r(installed_with_dist_infos   z)BaseDistribution.installed_with_dist_infocCr!r"r#r%r'r'r(canonical_namer*zBaseDistribution.canonical_namecCr!r"r#r%r'r'r(r?r*zBaseDistribution.versioncCs|jddS)zConvert a project name to its setuptools-compatible filename. This is a copy of ``pkg_resources.to_filename()`` for compatibility. -_)r>replacer%r'r'r(setuptools_filenamesz$BaseDistribution.setuptools_filenamec Csrz|t}Wn tyYdSwzt|WSttjtfy8}zt dt|j |WYd}~dSd}~ww)zObtain a DirectUrl from this distribution. Returns None if the distribution has no `direct_url.json` metadata, or if `direct_url.json` is invalid. NzError parsing %s for %s: %s) read_textrFileNotFoundErrorr from_jsonUnicodeDecodeErrorjsonJSONDecodeErrorrloggerwarningrV)r&contenter'r'r(rCs*   zBaseDistribution.direct_urlc CsPz|d}Wn tttfyYdSw|D] }|}|r%|SqdS)N INSTALLER)r[OSError ValueErrorr splitlinesstrip)r&installer_textline cleaned_liner'r'r( installers zBaseDistribution.installercCs t|jSr")boolrGr%r'r'r(editable!s zBaseDistribution.editablecCs|jdurdSt|jS)z|If distribution is installed in the current virtual environment. Always True if we're not in a virtualenv. NF)rIrr%r'r'r(local%s  zBaseDistribution.localcC&|jdus tdur dS|jttSNF)rIr startswithrr%r'r'r( in_usersite/zBaseDistribution.in_usersitecCrrrs)rIrrtrr%r'r'r(in_site_packages5rvz!BaseDistribution.in_site_packagespathcCr!)z7Check whether an entry in the info directory is a file.r#r&rxr'r'r(rK;r*zBaseDistribution.is_filecCr!)a$Iterate through a directory in the info directory. Each item yielded would be a path relative to the info directory. :raise FileNotFoundError: If ``name`` does not exist in the directory. :raise NotADirectoryError: If ``name`` does not point to a directory. r#ryr'r'r(iterdir?szBaseDistribution.iterdircCr!)zRead a file in the info directory. :raise FileNotFoundError: If ``name`` does not exist in the directory. :raise NoneMetadataError: If ``name`` exists in the info directory, but cannot be read. r#ryr'r'r(r[IzBaseDistribution.read_textcCr!r"r#r%r'r'r(iter_entry_pointsRz"BaseDistribution.iter_entry_pointscCr!)aMetadata of distribution parsed from e.g. METADATA or PKG-INFO. This should return an empty message if the metadata file is unavailable. :raises NoneMetadataError: If the metadata file is available, but does not contain valid metadata. r#r%r'r'r(metadataUs zBaseDistribution.metadatacCs |jdS)zDValue of "Metadata-Version:" in distribution metadata, if available.zMetadata-Version)r~getr%r'r'r(metadata_version`s z!BaseDistribution.metadata_versioncCs|jd|jS)z*Value of "Name:" in distribution metadata.Name)r~rrVr%r'r'r(r>eszBaseDistribution.raw_namec Csl|jd}|dur tSz tt|}W|Sty5}zd}t||j|tWYd}~Sd}~ww)zValue of "Requires-Python:" in distribution metadata. If the key does not exist or contains an invalid value, an empty SpecifierSet should be returned. zRequires-PythonNz-Package %r has an invalid Requires-Python: %s)r~rrr1r rarbr>)r&r+specrdmessager'r'r(requires_pythonls z BaseDistribution.requires_pythonr'extrascCr!)zDependencies of this distribution. For modern .dist-info distributions, this is the collection of "Requires-Dist:" entries in distribution metadata. r#)r&rr'r'r(iter_dependenciesz"BaseDistribution.iter_dependenciescCr!)zExtras provided by this distribution. For modern .dist-info distributions, this is the collection of "Provides-Extra:" entries in distribution metadata. r#r%r'r'r(iter_provided_extrasrz%BaseDistribution.iter_provided_extrascCs<z|d}Wn tyYdSwddt|DS)NRECORDcss"|] }tt|dVqdS)rNr7).0rowr'r'r( s zFBaseDistribution._iter_declared_entries_from_record..)r[r\csvreaderri)r&textr'r'r("_iter_declared_entries_from_records  z3BaseDistribution._iter_declared_entries_from_recordcsz|d}Wn tyYdSwdd|jddD}|j}|j}|dus+|dur-|Sz t||Wn tyB|YSwj sH|Sfdd|DS)Nzinstalled-files.txtcss|]}|r|VqdSr"r'rpr'r'r(rszFBaseDistribution._iter_declared_entries_from_legacy..F)keependsc3s$|] }tt|jjVqdSr")r:r8r9partsrinfo_relr'r(rs  ) r[r\rir@rJr8r9 relative_torhr)r&rpathsrootr3r'rr("_iter_declared_entries_from_legacys(   z3BaseDistribution._iter_declared_entries_from_legacycCs|p|S)aIterate through file entires declared in this distribution. For modern .dist-info distributions, this is the files listed in the ``RECORD`` metadata file. For legacy setuptools distributions, this comes from ``installed-files.txt``, with entries normalized to be compatible with the format used by ``RECORD``. :return: An iterator for listed entries, or None if the distribution contains neither ``RECORD`` nor ``installed-files.txt``. )rrr%r'r'r(iter_declared_entriess z&BaseDistribution.iter_declared_entriesN)r')6r-r.r/r1rArBr0r r@rGrIrJrorMrPrTrUrrVDistributionVersionr?rZrrCrnrprqrurwInfoPathrKrr8 PurePosixPathrzr[rrr|emailrMessager~rr>rrrr rrrrrr'r'r'r(r;asl        r;c@seZdZdZedddZedeeeddfddZ deded fd d Z de d fd d Z de d fddZ dedddfdedeedededede ef ddZdS)BaseEnvironmentz6An environment containing distributions to introspect.r cCr!r"r#)clsr'r'r(defaultr*zBaseEnvironment.defaultrcCr!r"r#)rrr'r'r( from_pathsr*zBaseEnvironment.from_pathsr)r;cCr!)zGiven a requirement name, return the installed distributions. The name may not be normalized. The implementation must canonicalize it for lookup. r#)r&r)r'r'r(get_distributionrz BaseEnvironment.get_distributioncCr!)aIterate through installed distributions. This function should be implemented by subclass, but never called directly. Use the public ``iter_distribution()`` instead, which implements additional logic to make sure the distributions are valid. r#r%r'r'r(_iter_distributionsr{z#BaseEnvironment._iter_distributionsccsF|D]}tjd|jtjd}|std|j|jq|VqdS)z(Iterate through installed distributions.z)^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$)flagsz%Ignoring invalid distribution %s (%s)N)rrematchrV IGNORECASErarbr@)r&distproject_name_validr'r'r(iter_distributionss  z"BaseEnvironment.iter_distributionsTF local_onlyskipinclude_editableseditables_only user_onlycsb|}|r dd|D}|sdd|D}|rdd|D}|r(dd|D}fdd|DS)aReturn a list of installed distributions. :param local_only: If True (default), only return installations local to the current virtualenv, if in a virtualenv. :param skip: An iterable of canonicalized project names to ignore; defaults to ``stdlib_pkgs``. :param include_editables: If False, don't report editables. :param editables_only: If True, only report editables. :param user_only: If True, only report installations in the user site directory. cs|]}|jr|VqdSr")rqrdr'r'r(rz?BaseEnvironment.iter_installed_distributions..css|]}|js|VqdSr"rprr'r'r(rrcsrr"rrr'r'r(rrcsrr")rurr'r'r(r rc3s|] }|jvr|VqdSr")rVrrr'r(r s)r)r&rrrrritr'rr(iter_installed_distributionssz,BaseEnvironment.iter_installed_distributionsN)r r)r-r.r/__doc__ classmethodrr rr1rrrrrrrorr;rr'r'r'r(rs6  rc@s&eZdZUeed<dejfddZdS)Wheelr@r cCr!r"r#r%r'r'r( as_zipfiler}zWheel.as_zipfileN)r-r.r/r1__annotations__zipfileZipFilerr'r'r'r(r s rc@s.eZdZdeddfddZdejfddZdS)FilesystemWheelr@r NcCs ||_dSr")r@rOr'r'r(__init__s zFilesystemWheel.__init__cCtj|jddSNT) allowZip64)rrr@r%r'r'r(rzFilesystemWheel.as_zipfile)r-r.r/r1rrrrr'r'r'r(rsrc@s6eZdZdedeeddfddZdejfddZ dS) MemoryWheelr@streamr NcCs||_||_dSr")r@r)r&r@rr'r'r(rs zMemoryWheel.__init__cCrr)rrrr%r'r'r(r!rzMemoryWheel.as_zipfile) r-r.r/r1rbytesrrrrr'r'r'r(rsr)@r email.messagerr_loggingr8rrtypingrrrrrrrr r r "pip._vendor.packaging.requirementsr pip._vendor.packaging.specifiersr rpip._vendor.packaging.utilsrpip._vendor.packaging.versionrrpip._internal.exceptionsrpip._internal.locationsrrpip._internal.models.direct_urlrrrpip._internal.utils.compatrpip._internal.utils.egg_linkrrpip._internal.utils.miscrrpip._internal.utils.urlsrrobjectrr1rr getLoggerr-rarr:r;rrrrr'r'r'r(sP0          ^P