enthought / sat-solver

Default Repo description from terraform module
Other
3 stars 1 forks source link

Parsing issues with leading zeroes in version #251

Closed olofk closed 7 years ago

olofk commented 8 years ago

Hi,

I'm using sat-solver internally in my project, and noticed some strange problems with a package that has the version 2015.06. Digging a bit deeper, I noticed some peculiarities with the package/requirement parsing. Attaching a test case to show how slight changes to the requirements yield different results

from okonomiyaki.versions import EnpkgVersion
from simplesat.constraints import PrettyPackageStringParser, Requirement
from simplesat.dependency_solver import DependencySolver
from simplesat.errors import SatisfiabilityError
from simplesat.package import RepositoryInfo, RepositoryPackageMetadata
from simplesat.pool import Pool
from simplesat.repository import Repository
from simplesat.request import Request

request     = Request()
requirement = Requirement._from_string("pkg >= 01.0")  #works
requirement = Requirement._from_string("pkg >= 01.00") #works
requirement = Requirement._from_string("pkg >= 1.0")   #Fails
request.install(requirement)

remote_repo = Repository()
repository_info = RepositoryInfo(u"remote")

installed_repository = Repository()

parser = PrettyPackageStringParser(EnpkgVersion.from_string)
package = parser.parse_to_package("pkg 1.01")

_package = RepositoryPackageMetadata(package, repository_info)
remote_repo.add_package(_package)

pool = Pool([remote_repo])
pool.add_repository(installed_repository)

solver = DependencySolver(pool, remote_repo, installed_repository)

transaction = solver.solve(request)
cournape commented 7 years ago

@olofk sorry for the late reply, I missed this issue for some reason. The issue essentially boils down to EnpkgVersion.from_string(u"1.0") > EnpkgVersion.from_string(u"1.01")

This may be surprising, but this is because 1.01 is actually an invalid version as far as PEP 386 goes. Now, because we ourselves had packages that had invalid versions, we could not reject them outright, but instead marked invalid versions as "worked around". Worked around versions always compare lower than any valid version.

You can ensure that no version is workedaround as follows:


v = EnpkgVersion.from_string("1.0-1")
# EnpkgVersion is essentially an upstream version + a build number
# EnpkgVersion.upstream is PEP386WorkedAroundVersion that contains that comparison hack for
# invalid versions
print(v.upstream.is_workedaround)