Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PyPiVersionRange.from_native not working #26

Open
Hritik14 opened this issue Jan 11, 2022 · 3 comments
Open

PyPiVersionRange.from_native not working #26

Hritik14 opened this issue Jan 11, 2022 · 3 comments

Comments

@Hritik14
Copy link
Collaborator

Hritik14 commented Jan 11, 2022

https://github.com/nexB/univers/blob/aa2253d17a11be3af36278be37e898c05fdbc4fd/src/univers/version_range.py#L501-L504

and PEP 440 shows an example for version specifier as follows:

~= 0.9, >= 1.0, != 1.3.4.*, < 2.0

See: https://www.python.org/dev/peps/pep-0440/#version-specifiers

Let's try:

>>> from univers.version_range import PypiVersionRange
>>> rng_from_native = PypiVersionRange.from_native("~= 0.9, >= 1.0, != 1.3.4.*, < 2.0")
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-22-af3412ff72fa> in <module>
----> 1 rng_from_native = PypiVersionRange.from_native("~= 0.9, >= 1.0, != 1.3.4.*, < 2.0")

~/Contrib/univers/src/univers/version_range.py in from_native(cls, string)
    514             operator = spec.operator
    515             version = spec.version
--> 516             assert isinstance(version, cls.version_class)
    517             comparator = cls.vers_by_native_comparators[operator]
    518             constraint = VersionConstraint(comparator=comparator, version=version)

AssertionError:

Something is not right

@GermanMT
Copy link

I have programmed a small piece of code that solves the problem with the ~= operator and the versions ending in *. I have disregarded the === operator as mentioned within the TODOs of the PypiVersionRange class as PEP 440 considers it a non-recommended approach. I haven't had time to add it to a pull request as I needed to add this to a project of my own, but if needed I could do so and contribute to the project.

def sanitize_pip_constraints(raw_constraints: str) -> str:
    constraints = []
    for raw_constraint in raw_constraints.split(','):
        operator, version = raw_constraint.strip().split(' ')
        if '==' in operator and '*' in version:
            pos = version.find('*')
            version = version[:pos - 1]
            constraints.append('>= ' + version)
            constraints.append('< ' + version[:pos - 2] + str(int(version[pos - 2]) + 1))
        elif '!=' in operator and '*' in version:
            pos = version.find('*')
            version = version[:pos - 1]
            constraints.append('< ' + version)
            constraints.append('>= ' + version[:pos - 2] + str(int(version[pos - 2]) + 1))
        elif '~=' in operator:
            parts = version.split('.')
            parts[-2] = str(int(parts[-2]) + 1)
            parts.pop()
            constraints.append('>= ' + version)
            constraints.append('< ' + '.'.join(parts))
        else:
            constraints.append(operator + ' ' + version)
    return ', '.join(constraints)

raw_constraints = '~= 0.9, >= 1.0, != 1.3.4.*, == 2.3.*, < 2.0'

print(sanitize_pip_constraints(raw_constraints))

@Hritik14
Copy link
Collaborator Author

@GermanMT This looks good! A PR with some tests would certainly be welcome and more discussion-able.

@GermanMT
Copy link

I have make a pull request, sorry for the delay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants