\e[c@s0dZddlmZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z mZddlmZddlmZmZddlmZmZmZdd lmZmZmZmZmZmZmZd d d d dgZ ej!e"Z#dZ$dZ%deddde$dfZ&dZ'de(fdYZ)de(fdYZ*de(fdYZ+de+fdYZ,de,fd YZ-d!e,fd"YZ.e-Z/e.Z0d#e(fd$YZ1d%d&Z2d'Z3d(Z4d)Z5dS(*uPEP 376 implementation.i(tunicode_literalsNi(tDistlibExceptiont resources(tStringIO(t get_schemetUnsupportedVersionError(tMetadatatMETADATA_FILENAMEtWHEEL_METADATA_FILENAME(tparse_requirementtcached_propertytparse_name_and_versiont read_exportst write_exportst CSVReadert CSVWriteru DistributionuBaseInstalledDistributionuInstalledDistributionuEggInfoDistributionuDistributionPathupydist-exports.jsonupydist-commands.jsonu INSTALLERuRECORDu REQUESTEDu RESOURCESuSHAREDu .dist-infot_CachecBs)eZdZdZdZdZRS(uL A simple cache mapping names and .dist-info paths to distributions cCsi|_i|_t|_dS(uZ Initialise an instance. There is normally one for each DistributionPath. N(tnametpathtFalset generated(tself((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt__init__0s  cCs'|jj|jjt|_dS(uC Clear the cache, setting it to its initial state. N(RtclearRRR(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyR8s  cCsH|j|jkrD||j|j<|jj|jgj|ndS(u` Add a distribution to the cache. :param dist: The distribution to add. N(RRt setdefaulttkeytappend(Rtdist((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytadd@s(t__name__t __module__t__doc__RRR(((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyR,s  tDistributionPathcBseZdZd edZdZdZeeeZ dZ dZ dZ e dZdZd Zd d Zd Zd d ZRS(uU Represents a set of distributions installed on a path (typically sys.path). cCsg|dkrtj}n||_t|_||_t|_t|_t|_ t d|_ dS(u Create an instance from a path, optionally including legacy (distutils/ setuptools/distribute) distributions. :param path: The path to use, as a list of directories. If not specified, sys.path is used. :param include_egg: If True, this instance will look for and return legacy distributions as well as those based on PEP 376. udefaultN( tNonetsysRtTruet _include_distt _include_eggRt_cachet _cache_eggt_cache_enabledRt_scheme(RRt include_egg((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRNs        cCs|jS(N(R((R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt_get_cache_enabledbscCs ||_dS(N(R((Rtvalue((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt_set_cache_enabledescCs|jj|jjdS(u, Clears the internal cache. N(R&RR'(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt clear_cachejs c cst}x|jD]}tj|}|dkr:qn|jd}| s|j r`qnt|j}x^|D]V}|j|}| sv|j|krqvn|jr}|j t r}t t g}x<|D]1}t j||} |j| } | rPqqWqvtj| j} td| dd} WdQXtjd|j|j|jt|jd| d|Vqv|jrv|j d rvtjd|j|j|jt|j|VqvqvWqWdS( uD Yield .dist-info and/or .egg(-info) distributions. utfileobjtschemeulegacyNuFound %stmetadatatenvu .egg-infou.egg(u .egg-infou.egg(tsetRRtfinder_for_pathR!tfindt is_containertsortedR$tendswitht DISTINFO_EXTRRt posixpathtjoint contextlibtclosingt as_streamRtloggertdebugRtnew_dist_classR%told_dist_class( RtseenRtfindertrtrsettentrytpossible_filenamestmetadata_filenamet metadata_pathtpydisttstreamR1((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt_yield_distributionsrs@       cCs|jj }|jo |jj }|s/|rxF|jD]8}t|trd|jj|q<|jj|q<W|rt|j_n|rt|j_qndS(uk Scan the path for distributions and populate the cache with those that are found. N( R&RR%R'RMt isinstancetInstalledDistributionRR#(Rtgen_disttgen_eggR((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt_generate_caches  cCs)|jdd}dj||gtS(uo The *name* and *version* parameters are converted into their filename-escaped form, i.e. any ``'-'`` characters are replaced with ``'_'`` other than the one in ``'dist-info'`` and the one separating the name from the version number. :parameter name: is converted to a standard distribution name by replacing any runs of non- alphanumeric characters with a single ``'-'``. :type name: string :parameter version: is converted to a standard version string. Spaces become dots, and all other non-alphanumeric characters (except dots) become dashes, with runs of multiple dashes condensed to a single dash. :type version: string :returns: directory name :rtype: stringu-u_(treplaceR;R9(tclsRtversion((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytdistinfo_dirnamesccs|js(xv|jD] }|VqWnZ|jx|jjjD] }|VqEW|jrx"|jjjD] }|VqpWndS(u5 Provides an iterator that looks for distributions and returns :class:`InstalledDistribution` or :class:`EggInfoDistribution` instances for each one of them. :rtype: iterator of :class:`InstalledDistribution` and :class:`EggInfoDistribution` instances N(R(RMRRR&RtvaluesR%R'(RR((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytget_distributionss     cCsd}|j}|jsNx|jD]}|j|kr(|}Pq(q(Wne|j||jjkr|jj|d}n2|jr||j jkr|j j|d}n|S(u= Looks for a named distribution on the path. This function only returns the first result found, as no more than one value is expected. If nothing is found, ``None`` is returned. :rtype: :class:`InstalledDistribution`, :class:`EggInfoDistribution` or ``None`` iN( R!tlowerR(RMRRRR&RR%R'(RRtresultR((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytget_distributions     c csd}|dk r_y |jjd||f}Wq_tk r[td||fq_Xnx|jD]}t|dstjd|ql|j }xh|D]`}t |\}}|dkr||kr|VPqq||kr|j |r|VPqqWqlWdS(u Iterates over all distributions to find which distributions provide *name*. If a *version* is provided, it will be used to filter the results. This function only returns the first result found, since no more than one values are expected. If the directory is not found, returns ``None``. :parameter version: a version specifier that indicates the version required, conforming to the format in ``PEP-345`` :type name: string :type version: string u%s (%s)uinvalid name or version: %r, %ruprovidesuNo "provides": %sN( R!R)tmatchert ValueErrorRRXthasattrR?R@tprovidesR tmatch( RRRUR\Rtprovidedtptp_nametp_ver((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytprovides_distributions(       cCs;|j|}|dkr.td|n|j|S(u5 Return the path to a resource file. uno distribution named %r foundN(R[R!t LookupErrortget_resource_path(RRt relative_pathR((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt get_file_paths ccsxy|jD]k}|j}||kr ||}|dk rY||kru||Vquqxx|jD] }|VqfWq q WdS(u Return all of the exported entries in a particular category. :param category: The category to search for entries. :param name: If specified, only entries with that name are returned. N(RXtexportsR!RW(RtcategoryRRREtdtv((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytget_exported_entries's     N(RRRR!RRR+R-tpropertyt cache_enabledR.RMRRt classmethodRVRXR[ReRiRn(((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyR Js    *    ) t DistributioncBseZdZeZeZdZedZeZ edZ edZ dZ edZ edZedZed Zed Zd Zd Zd ZdZRS(u A base class for distributions, whether installed or from indexes. Either way, it must have some metadata, so that's all that's needed for construction. cCsp||_|j|_|jj|_|j|_d|_d|_d|_d|_ t |_ i|_ dS(u Initialise an instance. :param metadata: The instance of :class:`Metadata` describing this distribution. N( R1RRYRRUR!tlocatortdigesttextrastcontextR3t download_urlstdigests(RR1((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRLs        cCs |jjS(uH The source archive download URL for this distribution. (R1t source_url(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRy]scCsd|j|jfS(uX A utility property which displays the name and version in parentheses. u%s (%s)(RRU(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytname_and_versionfscCsB|jj}d|j|jf}||kr>|j|n|S(u A set of distribution names and versions provided by this distribution. :return: A set of "name (version)" strings. u%s (%s)(R1R_RRUR(Rtplistts((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyR_ms   cCsS|j}tjd|jt||}t|j|d|jd|jS(Nu%Getting requirements from metadata %rRuR2( R1R?R@ttodicttgetattrR3tget_requirementsRuRv(Rtreq_attrtmdtreqts((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt_get_requirementsys  cCs |jdS(Nu run_requires(R(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt run_requiresscCs |jdS(Nu meta_requires(R(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt meta_requiresscCs |jdS(Nubuild_requires(R(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytbuild_requiresscCs |jdS(Nu test_requires(R(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt test_requiresscCs |jdS(Nu dev_requires(R(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt dev_requiressc Cst|}t|jj}y|j|j}Wn@tk rvtjd||j d}|j|}nX|j }t }x]|j D]R}t |\}} ||krqny|j| }PWqtk rqXqW|S(u Say if this instance matches (fulfills) a requirement. :param req: The requirement to match. :rtype req: str :return: True if it matches, else False. u+could not read version %r - using name onlyi(R RR1R0R\t requirementRR?twarningtsplitRRR_R R`( RtreqRER0R\RRZRbRcRd((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytmatches_requirements*      cCs6|jrd|j}nd}d|j|j|fS(uC Return a textual representation of this instance, u [%s]uu(RyRRU(Rtsuffix((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt__repr__s cCs[t|t|k r!t}n6|j|jkoT|j|jkoT|j|jk}|S(u< See if this distribution is the same as another. :param other: The distribution to compare with. To be equal to one another. distributions must have the same type, name, version and source_url. :return: True if it is the same, else False. (ttypeRRRURy(RtotherRZ((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt__eq__s  cCs't|jt|jt|jS(uH Compute hash in a way which matches the equality test. (thashRRURy(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt__hash__s(RRRRtbuild_time_dependencyt requestedRRoRyt download_urlRzR_RRRRRRRRRR(((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRr:s$   " tBaseInstalledDistributioncBs,eZdZdZddZddZRS(u] This is the base class for installed distributions (whether PEP 376 or legacy). cCs,tt|j|||_||_dS(u Initialise an instance. :param metadata: An instance of :class:`Metadata` which describes the distribution. This will normally have been initialised from a metadata file in the ``path``. :param path: The path of the ``.dist-info`` or ``.egg-info`` directory for the distribution. :param env: This is normally the :class:`DistributionPath` instance where this distribution was found. N(tsuperRRRt dist_path(RR1RR2((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRs  cCs|dkr|j}n|dkr6tj}d}ntt|}d|j}||j}tj|jdj d}d||fS(u Get the hash of some data, using a particular hash algorithm, if specified. :param data: The data to be hashed. :type data: bytes :param hasher: The name of a hash implementation, supported by hashlib, or ``None``. Examples of valid values are ``'sha1'``, ``'sha224'``, ``'sha384'``, '``sha256'``, ``'md5'`` and ``'sha512'``. If no hasher is specified, the ``hasher`` attribute of the :class:`InstalledDistribution` instance is used. If the hasher is determined to be ``None``, MD5 is used as the hashing algorithm. :returns: The hash of the data. If a hasher was explicitly specified, the returned hash will be prefixed with the specified hasher followed by '='. :rtype: str uu%s=t=uasciiu%s%sN( R!thasherthashlibtmd5R~Rttbase64turlsafe_b64encodetrstriptdecode(RtdataRtprefixRt((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytget_hashs      !N(RRRR!RRR(((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRs ROcBseZdZdZdddZdZdZdZe dZ dZ dZ d Z d Zed Zd Ze d ZedZdZdZdZdZejZRS(u  Created with the *path* of the ``.dist-info`` directory provided to the constructor. It reads the metadata contained in ``pydist.json`` when it is instantiated., or uses a passed in Metadata instance (useful for when dry-run mode is being used). usha256c Csg|_tj||_}|dkr>td|n|ru|jru||jjkru|jj|j }n|dkr'|j t }|dkr|j t }n|dkr|j d}n|dkrtdt |fnt j|j}td|dd}WdQXntt|j||||re|jre|jj|n|j d}|dk |_tjj|d}tjj|rt|d }|j} WdQX| j|_ndS( Nufinder unavailable for %suMETADATAuno %s found in %sR/R0ulegacyu REQUESTEDu top_level.txturb(tmodulesRR4RDR!R]R(R&RR1R5RRR<R=R>RRRORRRtosR;texiststopentreadt splitlines( RRR1R2RDRERLRbtfR((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRs6  !     cCsd|j|j|jfS(Nu#(RRUR(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyR:scCsd|j|jfS(Nu%s %s(RRU(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt__str__>sc Csg}|jd}tj|j}td|i}x_|D]W}gtt|dD] }d^qb}||\}} } |j|| | fqFWWdQXWdQX|S(u" Get the list of installed files for the distribution :return: A list of tuples of path, hash and size. Note that hash and size might be ``None`` for some entries. The path is exactly as stored in the file (which is as in PEP 376). uRECORDRLiN( tget_distinfo_resourceR<R=R>RtrangetlenR!R( RtresultsRERLt record_readertrowtitmissingRtchecksumtsize((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt _get_recordsAs (&cCs.i}|jt}|r*|j}n|S(u Return the information exported by this distribution. :return: A dictionary of exports, mapping an export category to a dict of :class:`ExportEntry` instances describing the individual export entries, and keyed by name. (RtEXPORTS_FILENAMER (RRZRE((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRjXs cCsLi}|jt}|rHtj|j}t|}WdQXn|S(u Read exports data from a file in .ini format. :return: A dictionary of exports, mapping an export category to a list of :class:`ExportEntry` instances describing the individual export entries. N(RRR<R=R>R (RRZRERL((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyR fs cCs8|jt}t|d}t||WdQXdS(u Write a dictionary of exports to a file in .ini format. :param exports: A dictionary of exports, mapping an export category to a list of :class:`ExportEntry` instances describing the individual export entries. uwN(tget_distinfo_fileRRR (RRjtrfR((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyR usc Cs|jd}tj|jF}td|.}x$|D]\}}||kr@|Sq@WWdQXWdQXtd|dS(uW NOTE: This API may change in the future. Return the absolute path to a resource file with the given relative path. :param relative_path: The path, relative to .dist-info, of the resource of interest. :return: The absolute path where the resource is to be found. u RESOURCESRLNu3no resource file with relative path %r is installed(RR<R=R>RtKeyError(RRhRERLtresources_readertrelativet destination((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRgs  ccs x|jD] }|Vq WdS(u Iterates over the ``RECORD`` entries and returns a tuple ``(path, hash, size)`` for each line. :returns: iterator of (path, hash, size) N(R(RRZ((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytlist_installed_filessc Cstjj|d}tjj|j}|j|}tjj|d}|jd}tjd||rwdSt |}x|D]}tjj |s|j d rd} } nCdtjj |} t |d} |j| j} WdQX|j|s(|r@|j|r@tjj||}n|j|| | fqW|j|rtjj||}n|j|ddfWdQX|S( u Writes the ``RECORD`` file, using the ``paths`` iterable passed in. Any existing ``RECORD`` file is silently overwritten. prefix is used to determine when to write absolute paths. uuRECORDu creating %su.pycu.pyou%durbN(u.pycu.pyo(RRR;tdirnamet startswithRR?tinfoR!RtisdirR8tgetsizeRRRtrelpathtwriterow( RtpathsRtdry_runtbasetbase_under_prefixt record_pathtwriterRt hash_valueRtfp((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytwrite_installed_filess. ! c Csg}tjj|j}|jd}xn|jD]`\}}}tjj|sptjj||}n||krq7ntjj|s|j|dt t fq7tjj |r7t tjj |}|r||kr|j|d||fq|rd|kr3|jddd}nd }t|dG} |j| j|} | |kr|j|d|| fnWd QXqq7q7W|S( u Checks that the hashes and sizes of the files in ``RECORD`` are matched by the files themselves. Returns a (possibly empty) list of mismatches. Each entry in the mismatch list will be a tuple consisting of the path, 'exists', 'size' or 'hash' according to what didn't match (existence is checked first, then size, then hash), the expected value and the actual value. uRECORDuexistsusizeu=iiurbuhashN(RRRRRtisabsR;RRR#RtisfiletstrRRR!RRR( Rt mismatchesRRRRRt actual_sizeRRt actual_hash((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytcheck_installed_filess.    ,cCsi}tjj|jd}tjj|rtj|ddd}|jj}WdQXx[|D]P}|jdd\}}|dkr|j |gj |qj|||s cCst|to|j|jkS(N(RNROR(RR((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRNsN(RRRRR!RRRRR RjR R RgRRRRRRRRRRtobjectR(((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyROs("      # #    tEggInfoDistributioncBsqeZdZeZiZd dZdZdZ dZ dZ dZ e dZdZejZRS( uCreated with the *path* of the ``.egg-info`` directory or file provided to the constructor. It reads the metadata contained in the file itself, or if the given path happens to be a directory, the metadata is read from the file ``PKG-INFO`` under that directory.cCsd}||_||_|rh|jrh||jjkrh|jj|j}|||j|jnG|j|}|||j|j|r|jr|jj|nt t |j |||dS(NcSs%||_|j|_||_dS(N(RRYRRU(R|tnRm((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytset_name_and_version`s ( RRR(R'R1RRUt _get_metadataRRRR(RRR2RR1((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyR_s   !csd}dfd}d}}|jdr`tjj|rtjj|d}tjj|d}td|dd}tjj|d } tjj|d }|| }qtj|} t | j d j d } td | dd}y@| j d} | j dj d}| j d}Wqt k r\d}qXn|jdrtjj|rtjj|d } || }tjj|d}tjj|d }ntd|dd}nt d||r |j|n|dkrj|dk rjtjj|rjt|d} | jj d}WdQXqjn|syg}n |j}||_|S(NcSsg}|j}x|D]}|j}|jdrNtjd|Pnt|}|svtjd|qn|jrtjdn|js|j|j qdj d|jD}|jd|j |fqW|S(uCreate a list of dependencies from a requires.txt file. *data*: the contents of a setuptools-produced requires.txt file. u[u.Unexpected line: quitting requirement scan: %ru#Not recognised as a requirement: %ru4extra requirements in requires.txt are not supportedu, css|]}d|VqdS(u%s%sN((t.0tc((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pys su%s (%s)( RtstripRR?RR Rut constraintsRRR;(RtreqsRRREtcons((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytparse_requires_dataws&       csRg}y4tj|dd}|j}WdQXWntk rMnX|S(uCreate a list of dependencies from a requires.txt file. *req_path*: the path to a setuptools-produced requires.txt file. uruutf-8N(RRRtIOError(treq_pathRR(R(s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytparse_requires_paths u.egguEGG-INFOuPKG-INFORR0ulegacyu requires.txtu top_level.txtuEGG-INFO/PKG-INFOuutf8R/uEGG-INFO/requires.txtuEGG-INFO/top_level.txtuutf-8u .egg-infou,path must end with .egg-info or .egg, got %rurb(R!R8RRRR;Rt zipimportt zipimporterRtget_dataRRRtadd_requirementsRRRRR(RRtrequiresRttl_pathttl_dataRbt meta_pathR1RtzipfR/RR((Rs;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRtsT       !   cCsd|j|j|jfS(Nu!(RRUR(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRscCsd|j|jfS(Nu%s %s(RRU(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRscCsg}tjj|jd}tjj|rx`|jD]O\}}}||kr^q=ntjj|s=|j|dttfq=q=Wn|S(u Checks that the hashes and sizes of the files in ``RECORD`` are matched by the files themselves. Returns a (possibly empty) list of mismatches. Each entry in the mismatch list will be a tuple consisting of the path, 'exists', 'size' or 'hash' according to what didn't match (existence is checked first, then size, then hash), the expected value and the actual value. uinstalled-files.txtuexists(RRR;RRRR#R(RRRRt_((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRs  #c Cs2d}d}tjj|jd}g}tjj|r.tj|ddd}x|D]}|j}tjjtjj|j|}tjj|stj d||j d rqdqntjj |sd|j |||||fqdqdWWd QX|j |d d fn|S( u Iterates over the ``installed-files.txt`` entries and returns a tuple ``(path, hash, size)`` for each line. :returns: a list of (path, hash, size) cSs@t|d}z|j}Wd|jXtj|jS(Nurb(RRtcloseRRt hexdigest(RRtcontent((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt_md5s  cSstj|jS(N(Rtstattst_size(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyt_sizesuinstalled-files.txturRuutf-8uNon-existent file: %su.pycu.pyoN(u.pycu.pyo(RRR;RRRRtnormpathR?RR8RRR!(RRRRRZRRRb((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRs"    $ /c cstjj|jd}tjj|rt}tj|ddd}x|D]}|j}|dkr|t}qRn|sRtjj tjj|j|}|j |jr|r|Vq|VqqRqRWWdQXndS(u  Iterates over the ``installed-files.txt`` entries and returns paths for each line if the path is pointing to a file located in the ``.egg-info`` directory or one of its subdirectories. :parameter absolute: If *absolute* is ``True``, each returned path is transformed into a local absolute path. Otherwise the raw value from ``installed-files.txt`` is returned. :type absolute: boolean :returns: iterator of paths uinstalled-files.txturRuutf-8u./N( RRR;RR#RRRRRR(RtabsoluteRtskipRRRb((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRs    $cCst|to|j|jkS(N(RNRR(RR((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyR+sN(RRRR#RRR!RRRRRRRRRRR(((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRVs  Z    &  tDependencyGraphcBsheZdZdZdZd dZdZdZddZ e dZ d Z d Z RS( u Represents a dependency graph between distributions. The dependency relationships are stored in an ``adjacency_list`` that maps distributions to a list of ``(other, label)`` tuples where ``other`` is a distribution and the edge is labeled with ``label`` (i.e. the version specifier, if such was provided). Also, for more efficient traversal, for every distribution ``x``, a list of predecessors is kept in ``reverse_list[x]``. An edge from distribution ``a`` to distribution ``b`` means that ``a`` depends on ``b``. If any missing dependencies are found, they are stored in ``missing``, which is a dictionary that maps distributions to a list of requirements that were not provided by any other distributions. cCsi|_i|_i|_dS(N(tadjacency_listt reverse_listR(R((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pyRFs  cCsg|j| "%s" [label="%s"] u "%s" -> "%s" usubgraph disconnected { ulabel = "Disconnected" ubgcolor = red u"%s"u u} N(RR titemsRRR!R(RRtskip_disconnectedt disconnectedRtadjsRR((s;/tmp/pip-install-0xiv62/pip/pip/_vendor/distlib/database.pytto_dots&    %    cCs=g}i}x(|jjD]\}}|||t|jD])\}}|sZ|j|||=qZqZW|sPnxO|jD]A\}}g|D]$\}}||kr||f^q||sL         4  7I 6