def find(self, requirement, meta_extras=None, prereleases=False):
self.provided = {}<EOL>self.dists = {}<EOL>self.dists_by_name = {}<EOL>self.reqts = {}<EOL>meta_extras = set(meta_extras or [])<EOL>if '<STR_LIT>' in meta_extras:<EOL><INDENT>meta_extras.remove('<STR_LIT>')<EOL>meta_extras |= set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>'])<EOL><DEDENT>if isinstance(requirement, Distribution):<EOL><INDENT>dist = odist = requirement<EOL>logger.debug('<STR_LIT>', odist)<EOL><DEDENT>else:<EOL><INDENT>dist = odist = self.locator.locate(requirement,<EOL>prereleases=prereleases)<EOL>if dist is None:<EOL><INDENT>raise DistlibException('<STR_LIT>' % requirement)<EOL><DEDENT>logger.debug('<STR_LIT>', odist)<EOL><DEDENT>dist.requested = True<EOL>problems = set()<EOL>todo = set([dist])<EOL>install_dists = set([odist])<EOL>while todo:<EOL><INDENT>dist = todo.pop()<EOL>name = dist.key     <EOL>if name not in self.dists_by_name:<EOL><INDENT>self.add_distribution(dist)<EOL><DEDENT>else:<EOL><INDENT>other = self.dists_by_name[name]<EOL>if other != dist:<EOL><INDENT>self.try_to_replace(dist, other, problems)<EOL><DEDENT><DEDENT>ireqts = dist.run_requires | dist.meta_requires<EOL>sreqts = dist.build_requires<EOL>ereqts = set()<EOL>if dist in install_dists:<EOL><INDENT>for key in ('<STR_LIT:test>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>e = '<STR_LIT>' % key<EOL>if e in meta_extras:<EOL><INDENT>ereqts |= getattr(dist, '<STR_LIT>' % key)<EOL><DEDENT><DEDENT><DEDENT>all_reqts = ireqts | sreqts | ereqts<EOL>for r in all_reqts:<EOL><INDENT>providers = self.find_providers(r)<EOL>if not providers:<EOL><INDENT>logger.debug('<STR_LIT>', r)<EOL>provider = self.locator.locate(r, prereleases=prereleases)<EOL>if provider is None and not prereleases:<EOL><INDENT>provider = self.locator.locate(r, prereleases=True)<EOL><DEDENT>if provider is None:<EOL><INDENT>logger.debug('<STR_LIT>', r)<EOL>problems.add(('<STR_LIT>', r))<EOL><DEDENT>else:<EOL><INDENT>n, v = provider.key, provider.version<EOL>if (n, v) not in self.dists:<EOL><INDENT>todo.add(provider)<EOL><DEDENT>providers.add(provider)<EOL>if r in ireqts and dist in install_dists:<EOL><INDENT>install_dists.add(provider)<EOL>logger.debug('<STR_LIT>',<EOL>provider.name_and_version)<EOL><DEDENT><DEDENT><DEDENT>for p in providers:<EOL><INDENT>name = p.key<EOL>if name not in self.dists_by_name:<EOL><INDENT>self.reqts.setdefault(p, set()).add(r)<EOL><DEDENT>else:<EOL><INDENT>other = self.dists_by_name[name]<EOL>if other != p:<EOL><INDENT>self.try_to_replace(p, other, problems)<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>dists = set(self.dists.values())<EOL>for dist in dists:<EOL><INDENT>dist.build_time_dependency = dist not in install_dists<EOL>if dist.build_time_dependency:<EOL><INDENT>logger.debug('<STR_LIT>',<EOL>dist.name_and_version)<EOL><DEDENT><DEDENT>logger.debug('<STR_LIT>', odist)<EOL>return dists, problems<EOL>
Find a distribution and all distributions it depends on.

:param requirement: The requirement specifying the distribution to
                    find, or a Distribution instance.
:param meta_extras: A list of meta extras such as :test:, :build: and
                    so on.
:param prereleases: If ``True``, allow pre-release versions to be
                    returned - otherwise, don't return prereleases
                    unless they're all that's available.

Return a set of :class:`Distribution` instances and a set of
problems.

The distributions returned should be such that they have the
:attr:`required` attribute set to ``True`` if they were
from the ``requirement`` passed to ``find()``, and they have the
:attr:`build_time_dependency` attribute set to ``True`` unless they
are post-installation dependencies of the ``requirement``.

The problems should be a tuple consisting of the string
``'unsatisfied'`` and the requirement which couldn't be satisfied
by any distribution known to the locator.