Skip to content

Commit

Permalink
Allow the caching and static iterator to respect allow_prereleases
Browse files Browse the repository at this point in the history
  • Loading branch information
toddgardner committed Apr 6, 2017
1 parent 61da553 commit 2a8f19b
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 7 deletions.
21 changes: 14 additions & 7 deletions pex/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ class Unsatisfiable(Exception):
class StaticIterator(IteratorInterface):
"""An iterator that iterates over a static list of packages."""

def __init__(self, packages):
def __init__(self, packages, allow_prereleases=None):
self._packages = packages
self._allow_prereleases = allow_prereleases

def iter(self, req):
for package in self._packages:
if package.satisfies(req):
if package.satisfies(req, allow_prereleases=self._allow_prereleases):
yield package


Expand Down Expand Up @@ -150,13 +151,15 @@ def filter_packages_by_interpreter(cls, packages, interpreter, platform):
return [package for package in packages
if package.compatible(interpreter.identity, platform)]

def __init__(self, interpreter=None, platform=None):
def __init__(self, allow_prereleases=None, interpreter=None, platform=None):
self._interpreter = interpreter or PythonInterpreter.get()
self._platform = platform or Platform.current()
self._allow_prereleases = allow_prereleases

def package_iterator(self, resolvable, existing=None):
if existing:
existing = resolvable.compatible(StaticIterator(existing))
existing = resolvable.compatible(
StaticIterator(existing, allow_prereleases=self._allow_prereleases))
else:
existing = resolvable.packages()
return self.filter_packages_by_interpreter(existing, self._interpreter, self._platform)
Expand Down Expand Up @@ -239,7 +242,8 @@ def __init__(self, cache, cache_ttl, *args, **kw):

# Short-circuiting package iterator.
def package_iterator(self, resolvable, existing=None):
iterator = Iterator(fetchers=[Fetcher([self.__cache])])
iterator = Iterator(fetchers=[Fetcher([self.__cache])],
allow_prereleases=self._allow_prereleases)
packages = self.filter_packages_by_interpreter(
resolvable.compatible(iterator),
self._interpreter,
Expand Down Expand Up @@ -350,8 +354,11 @@ def resolve(
)

if cache:
resolver = CachingResolver(cache, cache_ttl, interpreter=interpreter, platform=platform)
resolver = CachingResolver(
cache, cache_ttl,
allow_prereleases=allow_prereleases, interpreter=interpreter, platform=platform)
else:
resolver = Resolver(interpreter=interpreter, platform=platform)
resolver = Resolver(
allow_prereleases=allow_prereleases, interpreter=interpreter, platform=platform)

return resolver.resolve(resolvables_from_iterable(requirements, builder))
61 changes: 61 additions & 0 deletions tests/test_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,67 @@ def assert_resolve(expected_version, **resolve_kwargs):
assert_resolve('3.0.0rc3', allow_prereleases=True)


def test_resolve_prereleases_cached():
stable_dep = make_sdist(name='dep', version='2.0.0')
prerelease_dep = make_sdist(name='dep', version='3.0.0rc3')

with temporary_dir() as td:
for sdist in (stable_dep, prerelease_dep):
safe_copy(sdist, os.path.join(td, os.path.basename(sdist)))
fetchers = [Fetcher([td])]

with temporary_dir() as cd:
def assert_resolve(dep, expected_version, **resolve_kwargs):
dists = resolve(
[dep], cache=cd, cache_ttl=1000, **resolve_kwargs)
assert 1 == len(dists)
dist = dists[0]
assert expected_version == dist.version

Crawler.reset_cache()

# First do a run to load it into the cache.
assert_resolve('dep>=1,<4', '3.0.0rc3', allow_prereleases=True, fetchers=fetchers)

# This simulates running from another pex command. The Crawler cache actually caches an empty
# cache so this fails in the same "process".
Crawler.reset_cache()

# Now assert that we can get it from the cache by removing the source.
assert_resolve('dep>=1,<4', '3.0.0rc3', allow_prereleases=True, fetchers=[])

# It should also be able to resolve without allow_prereleases, if explicitly requested.
Crawler.reset_cache()
assert_resolve('dep>=1.rc1,<4', '3.0.0rc3', fetchers=[])


def test_resolve_prereleases_multiple_set():
stable_dep = make_sdist(name='dep', version='2.0.0')
prerelease_dep1 = make_sdist(name='dep', version='3.0.0rc3')
prerelease_dep2 = make_sdist(name='dep', version='3.0.0rc4')
prerelease_dep3 = make_sdist(name='dep', version='3.0.0rc5')

with temporary_dir() as td:
for sdist in (stable_dep, prerelease_dep1, prerelease_dep2, prerelease_dep3):
safe_copy(sdist, os.path.join(td, os.path.basename(sdist)))
fetchers = [Fetcher([td])]

def assert_resolve(expected_version, **resolve_kwargs):
dists = resolve(
[
'dep>=3.0.0rc1',
'dep==3.0.0rc4',
],
fetchers=fetchers, **resolve_kwargs)
assert 1 == len(dists)
dist = dists[0]
assert expected_version == dist.version

# This should resolve with explicit prerelease being set or implicitly.
assert_resolve('3.0.0rc4', allow_prereleases=True)
assert_resolve('3.0.0rc4')


def test_resolvable_set():
builder = ResolverOptionsBuilder()
rs = _ResolvableSet()
Expand Down

0 comments on commit 2a8f19b

Please sign in to comment.