0{Y@s6dZddlmZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z mZddlmZddlmZmZddlmZmZdd lmZmZmZmZmZmZmZd d d d dgZej e!Z"dZ#dZ$deddde#dfZ%dZ&Gddde'Z(Gddde'Z)Gdd d e'Z*Gdd d e*Z+Gdd d e+Z,Gdd d e+Z-e,Z.e-Z/Gddde'Z0d d!d"Z1d#d$Z2d%d&Z3d'd(Z4dS))zPEP 376 implementation.)unicode_literalsN)DistlibException resources)StringIO) get_schemeUnsupportedVersionError)MetadataMETADATA_FILENAME)parse_requirementcached_propertyparse_name_and_version read_exports write_exports CSVReader CSVWriter DistributionBaseInstalledDistributionInstalledDistributionEggInfoDistributionDistributionPathzpydist-exports.jsonzpydist-commands.jsonZ INSTALLERRECORD REQUESTED RESOURCESSHAREDz .dist-infoc@s:eZdZdZddZddZddZdS) _CachezL A simple cache mapping names and .dist-info paths to distributions cCsi|_i|_d|_dS)zZ Initialise an instance. There is normally one for each DistributionPath. FN)namepath generated)selfr 7/tmp/pip-ok8sy_ze-build/pip/_vendor/distlib/database.py__init__0s  z_Cache.__init__cCs'|jj|jjd|_dS)zC Clear the cache, setting it to its initial state. FN)rclearrr)rr r r!r#8s  z _Cache.clearcCsH|j|jkrD||j|j<|jj|jgj|ndS)z` Add a distribution to the cache. :param dist: The distribution to add. N)rr setdefaultkeyappend)rdistr r r!add@sz _Cache.addN)__name__ __module__ __qualname____doc__r"r#r(r r r r!r,s   rc@seZdZdZddddZddZdd ZeeeZd d Z d d Z ddZ e ddZ ddZddZdddZddZdddZdS)rzU Represents a set of distributions installed on a path (typically sys.path). NFcCsg|dkrtj}n||_d|_||_t|_t|_d|_td|_ dS)a 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. NTdefault) sysr _include_dist _include_eggr_cache _cache_egg_cache_enabledr_scheme)rrZ include_eggr r r!r"Ns        zDistributionPath.__init__cCs|jS)N)r3)rr r r!_get_cache_enabledbsz#DistributionPath._get_cache_enabledcCs ||_dS)N)r3)rvaluer r r!_set_cache_enabledesz#DistributionPath._set_cache_enabledcCs|jj|jjdS)z, Clears the internal cache. N)r1r#r2)rr r r! clear_cachejs zDistributionPath.clear_cachec cst}x|jD]}tj|}|dkr:qn|jd}| s|j r`qnt|j}x(|D] }|j|}| sv|j|krqvn|jrG|jt rGt j |t }|j|}|sqvnt d|jdd} tjd|j|j|jt|jd| d|Vqv|jrv|jd rvtjd|j|j|jt|j|VqvqvWqWdS) zD Yield .dist-info and/or .egg(-info) distributions. NfileobjschemelegacyzFound %smetadataenv .egg-info.egg)r?r@)setrrfinder_for_pathfind is_containersortedr/endswith DISTINFO_EXT posixpathjoinr r as_streamloggerdebugr(new_dist_classr0old_dist_class) rseenrfinderrZrsetentryZ metadata_pathZpydistr=r r r!_yield_distributionsrs:      z%DistributionPath._yield_distributionscCs|jj }|jo |jj }|s/|rxF|jD]8}t|trd|jj|q<|jj|q<W|rd|j_n|rd|j_qndS)zk Scan the path for distributions and populate the cache with those that are found. TN)r1rr0r2rS isinstancerr()rZgen_distZgen_eggr'r r r!_generate_caches  z DistributionPath._generate_cachecCs)|jdd}dj||gtS)ao 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: string-_)replacerIrG)clsrversionr r r!distinfo_dirnamesz!DistributionPath.distinfo_dirnameccs|js(xv|jD] }|VqWnZ|jx|jjjD] }|VqEW|jrx"|jjjD] }|VqpWndS)a5 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)r3rSrUr1rvaluesr0r2)rr'r r r!get_distributionss     z"DistributionPath.get_distributionscCsd}|j}|jsNx|jD]}|j|kr(|}Pq(q(Wne|j||jjkr|jj|d}n2|jr||jjkr|jj|d}n|S)a= 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`` Nr) lowerr3rSr%rUr1rr0r2)rrresultr'r r r!get_distributions     z!DistributionPath.get_distributionc csd}|dk r`y |jjd||f}Wq`tk r\td||fYq`Xnx|jD]z}|j}xh|D]`}t|\}}|dkr||kr|VPqq||kr|j|r|VPqqWqmWdS)a 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 Nz%s (%s)zinvalid name or version: %r, %r)r4matcher ValueErrorrr]providesr match) rrrZrar'providedpp_namep_verr r r!provides_distributions$       z&DistributionPath.provides_distributioncCs;|j|}|dkr.td|n|j|S)z5 Return the path to a resource file. Nzno distribution named %r found)r` LookupErrorget_resource_path)rr relative_pathr'r r r! get_file_paths zDistributionPath.get_file_pathccsxy|jD]k}|j}||kr ||}|dk rY||kru||Vquqxx|jD] }|VqfWq q WdS)z 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)r]exportsr\)rcategoryrr'rQdvr r r!get_exported_entriess     z%DistributionPath.get_exported_entries)r)r*r+r,r"r5r7propertyZ cache_enabledr8rSrU classmethodr[r]r`rirmrrr r r r!rJs     &   $ c@seZdZdZdZdZddZeddZeZ eddZ ed d Z d d Z ed dZ eddZeddZeddZeddZddZddZddZddZdS) rz 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. FcCs[||_|j|_|jj|_|j|_d|_d|_d|_d|_dS)z Initialise an instance. :param metadata: The instance of :class:`Metadata` describing this distribution. N) r=rr^r%rZlocatordigestextrascontext)rr=r r r!r"Cs      zDistribution.__init__cCs |jjS)zH The source archive download URL for this distribution. )r= source_url)rr r r!ryRszDistribution.source_urlcCsd|j|jfS)zX A utility property which displays the name and version in parentheses. z%s (%s))rrZ)rr r r!name_and_version[szDistribution.name_and_versioncCsB|jj}d|j|jf}||kr>|j|n|S)z A set of distribution names and versions provided by this distribution. :return: A set of "name (version)" strings. z%s (%s))r=rcrrZr&)rplistsr r r!rcbs   zDistribution.providescCs:t|j|}t|jj|d|jd|jS)Nrwr>)getattrr=rAZget_requirementsrwrx)rZreq_attrZreqtsr r r!_get_requirementsnszDistribution._get_requirementscCs |jdS)N run_requires)r~)rr r r!rsszDistribution.run_requirescCs |jdS)N meta_requires)r~)rr r r!rwszDistribution.meta_requirescCs |jdS)Nbuild_requires)r~)rr r r!r{szDistribution.build_requirescCs |jdS)N test_requires)r~)rr r r!rszDistribution.test_requirescCs |jdS)N dev_requires)r~)rr r r!rszDistribution.dev_requiresc Cst|}t|jj}y|j|j}WnAtk rwtjd||j d}|j|}YnX|j }d}x^|j D]S}t |\}} ||krqny|j | }PWqtk rYqXqW|S)z Say if this instance matches (fulfills) a requirement. :param req: The requirement to match. :rtype req: str :return: True if it matches, else False. z+could not read version %r - using name onlyrF)r rr=r;ra requirementrrKwarningsplitr%rcr rd) rreqrQr;rarr_rfrgrhr r r!matches_requirements*       z Distribution.matches_requirementcCs6|jrd|j}nd}d|j|j|fS)zC Return a textual representation of this instance, z [%s]r9z)ryrrZ)rsuffixr r r!__repr__s zDistribution.__repr__cCs[t|t|k r!d}n6|j|jkoT|j|jkoT|j|jk}|S)a< 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. F)typerrZry)rotherr_r r r!__eq__s  zDistribution.__eq__cCs't|jt|jt|jS)zH Compute hash in a way which matches the equality test. )hashrrZry)rr r r!__hash__szDistribution.__hash__N)r)r*r+r,Zbuild_time_dependency requestedr"rsry download_urlrzrcr~rrrrrrrrrr r r r!r1s$    " cs@eZdZdZdZdfddZdddZS)rz] This is the base class for installed distributions (whether PEP 376 or legacy). Ncs,tt|j|||_||_dS)a 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)superrr"r dist_path)rr=rr>) __class__r r!r"s  z"BaseInstalledDistribution.__init__cCs|dkr|j}n|dkr6tj}d}ntt|}d|j}||j}tj|jdjd}d||fS)a 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 Nr9z%s==asciiz%s%s) hasherhashlibmd5r}rvbase64urlsafe_b64encoderstripdecode)rdatarprefixrvr r r!get_hashs      !z"BaseInstalledDistribution.get_hash)r)r*r+r,rr"rr r )rr!rs cseZdZdZdZddfddZddZdd Zd d Ze d d Z ddZ ddZ ddZ ddZdddZddZe ddZdddZdd Zd!d"Zd#d$Zd%d&ZejZS)'ra  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). sha256Ncstj||_}|dkr;ddl}|jn|rr|jrr||jjkrr|jj|j}n|dkr|j t }|dkr|j d}n|dkrt dt |fnt j |j}td|dd}WdQXntt|j||||rD|jrD|jj|ny|j d}Wn(tk rddl}|jYnX|dk |_dS)NrMETADATAzno %s found in %sr:r;r<r)rrBrPpdbZ set_tracer3r1rr=rCr rb contextlibclosingrJr rrr"r(AttributeErrorr)rrr=r>rPrrQstream)rr r!r" s0  !      zInstalledDistribution.__init__cCsd|j|j|jfS)Nz#)rrZr)rr r r!r'szInstalledDistribution.__repr__cCsd|j|jfS)Nz%s %s)rrZ)rr r r!__str__+szInstalledDistribution.__str__c Csg}|jd}tj|j{}td|c}xY|D]Q}ddtt|dD}||\}}} |j||| fqFWWdQXWdQX|S)a" 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). rrcSsg|] }dqS)Nr ).0ir r r! =s z6InstalledDistribution._get_records..N)get_distinfo_resourcerrrJrrangelenr&) rresultsrQrZ record_readerrowmissingrchecksumsizer r r! _get_records.s "&z"InstalledDistribution._get_recordscCs.i}|jt}|r*|j}n|S)a 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. )rEXPORTS_FILENAMEr)rr_rQr r r!rnEs zInstalledDistribution.exportsc CsLi}|jt}|rHtj|j}t|}WdQXn|S)z 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)rrrrrJr)rr_rQrr r r!rSs z"InstalledDistribution.read_exportsc Cs8|jt}t|d}t||WdQXdS)a 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. wN)get_distinfo_fileropenr)rrnrffr r r!rbsz#InstalledDistribution.write_exportscCs|jd}tj|jF}td|.}x$|D]\}}||kr@|Sq@WWdQXWdQXtd|dS)aW 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. rrNz3no resource file with relative path %r is installed)rrrrJrKeyError)rrlrQrZresources_readerZrelativeZ destinationr r r!rkms  z'InstalledDistribution.get_resource_pathccs x|jD] }|Vq WdS)z Iterates over the ``RECORD`` entries and returns a tuple ``(path, hash, size)`` for each line. :returns: iterator of (path, hash, size) N)r)rr_r r r!list_installed_filessz*InstalledDistribution.list_installed_filesFc 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) z 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. r9rz creating %sN.pyc.pyoz%drb)rr)osrrIdirname startswithrrKinforisdirrFgetsizerrreadrelpathwriterow) rpathsrdry_runbaseZbase_under_prefix record_pathwriterr hash_valuerfpr r r!write_installed_filess. ! z+InstalledDistribution.write_installed_filesc Csg}tjj|j}|jd}xn|jD]`\}}}tjj|sptjj||}n||krq7ntjj|s|j|dddfq7tjj |r7t tjj |}|r||kr|j|d||fq|rd|kr3|j ddd}nd }t |d G} |j| j|} | |kr|j|d || fnWd QXqq7q7W|S) a 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. rexistsTFr=rrNrr)rrrrrisabsrIrr&isfilestrrrrrr) r mismatchesrrrrrZ actual_sizerrZ actual_hashr r r!check_installed_filess.    ,z+InstalledDistribution.check_installed_filesc Csi}tjj|jd}tjj|rtj|ddd}|jj}WdQXx[|D]P}|jdd\}}|dkr|j |gj |qj|||.set_name_and_version) rrr3r2r=rrZ _get_metadatar(rrr")rrr>rr=)rr r!r"Ls   !zEggInfoDistribution.__init__c sd}ddfdd}|jdr!tjj|rtjj|dd}td|d d }tjj|dd }||}qtj|}t|j d j d }td|d d }y(|j d} | j d}Wqt k rd}YqXn|jdrtjj|r{tjj|d}tjj|d }||}ntd|d d }nt d||r|j |n|S)NcSsg}|j}x|D]}|j}|jdrNtjd|Pnt|}|svtjd|qn|jrtjdn|js|j|j qdj dd|jD}|jd|j |fqW|S) zCreate a list of dependencies from a requires.txt file. *data*: the contents of a setuptools-produced requires.txt file. [z.Unexpected line: quitting requirement scan: %rz#Not recognised as a requirement: %rz4extra requirements in requires.txt are not supportedz, css|]}d|VqdS)z%s%sNr )rcr r r! {szQEggInfoDistribution._get_metadata..parse_requires_data..z%s (%s)) rstriprrKrr rw constraintsr&rrI)rreqsrrrQconsr r r!parse_requires_datads&       z>EggInfoDistribution._get_metadata..parse_requires_datacsSg}y4tj|dd}|j}WdQXWntk rNYnX|S)zCreate a list of dependencies from a requires.txt file. *req_path*: the path to a setuptools-produced requires.txt file. rQzutf-8N)rrrIOError)req_pathrr)rr r!parse_requires_paths z>EggInfoDistribution._get_metadata..parse_requires_pathz.eggzEGG-INFOzPKG-INFOrr;r<z requires.txtzEGG-INFO/PKG-INFOutf8r:zEGG-INFO/requires.txtzutf-8z .egg-infoz,path must end with .egg-info or .egg, got %r)rFrrrrIr zipimport zipimporterrget_datarrrZadd_requirements) rrrequiresr meta_pathr=rZzipfr:rr )rr!ras:   z!EggInfoDistribution._get_metadatacCsd|j|j|jfS)Nz!)rrZr)rr r r!rszEggInfoDistribution.__repr__cCsd|j|jfS)Nz%s %s)rrZ)rr r r!rszEggInfoDistribution.__str__cCsg}tjj|jd}tjj|rx`|jD]O\}}}||kr^q=ntjj|s=|j|dddfq=q=Wn|S)a 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. zinstalled-files.txtrTF)rrrIrrr&)rrrrrWr r r!rs  #z)EggInfoDistribution.check_installed_filesc Cs8dd}dd}tjj|jd}g}tjj|r4tj|ddd}x|D]}|j}tjjtjj|j|}tjj|stj d ||j d rqjqntjj |sj|j |||||fqjqjWWd QX|j |d d fn|S)z Iterates over the ``installed-files.txt`` entries and returns a tuple ``(path, hash, size)`` for each line. :returns: a list of (path, hash, size) c Ss@t|d}z|j}Wd|jXtj|jS)Nr)rrcloserr hexdigest)rrcontentr r r!_md5s  z6EggInfoDistribution.list_installed_files.._md5cSstj|jS)N)rstatst_size)rr r r!_sizesz7EggInfoDistribution.list_installed_files.._sizezinstalled-files.txtrQrzutf-8zNon-existent file: %s.pyc.pyoN)r r ) rrrIrrrrnormpathrKrrFrr&)rrr rr_rrrfr r r!rs"    $ /z(EggInfoDistribution.list_installed_filesFc cstjj|jd}d}tj|ddd}x|D]}|j}|dkrjd}q@n|s@tjjtjj|j|}|j|jr|r|Vq|Vqq@q@WWdQXdS) a  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 zinstalled-files.txtTrQrzutf-8z./FN)rrrIrrrr r)rZabsoluterskiprrrfr r r!rs    $z'EggInfoDistribution.list_distinfo_filescCst|to|j|jkS)N)rTrr)rrr r r!rszEggInfoDistribution.__eq__)r)r*r+r,rrr"rrrrrrrrrr r )rr!rCs  K    & c@seZdZdZddZddZdddZd d Zd d Zd ddZ dddZ ddZ ddZ dS)DependencyGrapha 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)adjacency_list reverse_listr)rr r r!r"#s  zDependencyGraph.__init__cCsg|j| "%s" [label="%s"] z "%s" -> "%s" zsubgraph disconnected { zlabel = "Disconnected" zbgcolor = red z"%s"rz} )rritemsrr&r)rrZskip_disconnectedZ disconnectedr'adjsrrr r r!to_dot\s&    %    zDependencyGraph.to_dotcsg}i}x1|jjD] \}}|dd||.zMoving to result: %scSs&g|]}d|j|jfqS)z%s (%s))rrZ)rrpr r r!rs )rrlistr&rKrLrkeys)rr_alistkrqr )r"r!topological_sort|s$) ! z DependencyGraph.topological_sortcCsIg}x3|jjD]"\}}|j|j|qWdj|S)zRepresentation of the graphr)rrr&rrI)rrr'r r r r!rszDependencyGraph.__repr__) r)r*r+r,r"rrrrrr!r'rr r r r!rs      rr-cCst|}t}i}xv|D]n}|j|xX|jD]M}t|\}}tjd||||j|gj||fq?Wq"Wx7|D]/}|j |j B|j B|j B}x|D]} y|j | } WnAtk r"tjd| | jd}|j |} YnX| j}d} ||krxl||D]]\}} y| j|} Wntk rd} YnX| rI|j|| | d} PqIqIWn| s|j|| qqWqW|S)a6Makes a dependency graph from the given distributions. :parameter dists: a list of distributions :type dists: list of :class:`distutils2.database.InstalledDistribution` and :class:`distutils2.database.EggInfoDistribution` instances :rtype: a :class:`DependencyGraph` instance zAdd to provided: %s, %s, %sz+could not read version %r - using name onlyrFT)rrrrcr rKrLr$r&rrrrrarrrr%rdrr)distsr;graphrer'rfrrZrrramatchedZproviderrdr r r! make_graphsD    '         r+cCs||kr"td|jnt|}|g}|j|}xW|r|j}|j|x1|j|D]"}||krt|j|qtqtWqGW|jd|S)zRecursively generate a list of distributions from *dists* that are dependent on *dist*. :param dists: a list of distributions :param dist: a distribution, member of *dists* for which we are interested z1given distribution %r is not a member of the listr)rrr+rpopr&)r(r'r)deptodorpsuccr r r!get_dependent_distss         r0cCs||kr"td|jnt|}g}|j|}x[|r|jd}|j|x1|j|D]"}||kru|j|ququWqDW|S)zRecursively generate a list of distributions from *dists* that are required by *dist*. :param dists: a list of distributions :param dist: a distribution, member of *dists* for which we are interested z1given distribution %r is not a member of the listr)rrr+rr,r&)r(r'r)rr.rppredr r r!get_required_distss      r2cKsI|jdd}t|}||_||_|p9d|_t|S)zO A convenience method for making a dist given just a name and version. summaryzPlaceholder for summaryzPlaeholder for summary)r,r rrZr3r)rrZkwargsr3Zmdr r r! make_dist s    r5)5r, __future__rrrrrloggingrrHr.rr9rrcompatrrZrrr=r r utilr r r rrrr__all__ getLoggerr)rKrZCOMMANDS_FILENAMErrGrrrrrrrrMrNrr+r0r2r5r r r r!sL         4  7C6