Giter Site home page Giter Site logo

python-semver / python-semver Goto Github PK

View Code? Open in Web Editor NEW
447.0 13.0 97.0 857 KB

Python package to work with Semantic Versioning (https://semver.org/)

Home Page: https://python-semver.readthedocs.io/en/latest/

License: BSD 3-Clause "New" or "Revised" License

Python 99.92% Makefile 0.08%
semver versioning python release semantic-versioning versions version semantic-version semver-release semver-cli

python-semver's Introduction

Quickstart

A Python module to simplify semantic versioning.

Python Python versions Monthly downloads from PyPI Software license Documentation Status Black Formatter Percentage of open issues GitHub Discussion

The module follows the MAJOR.MINOR.PATCH style:

  • MAJOR version when you make incompatible API changes,
  • MINOR version when you add functionality in a backwards compatible manner, and
  • PATCH version when you make backwards compatible bug fixes.

Additional labels for pre-release and build metadata are supported.

To import this library, use:

>>> import semver

Working with the library is quite straightforward. To turn a version string into the different parts, use the semver.Version.parse function:

>>> ver = semver.Version.parse('1.2.3-pre.2+build.4')
>>> ver.major
1
>>> ver.minor
2
>>> ver.patch
3
>>> ver.prerelease
'pre.2'
>>> ver.build
'build.4'

To raise parts of a version, there are a couple of functions available for you. The function semver.Version.bump_major leaves the original object untouched, but returns a new semver.Version instance with the raised major part:

>>> ver = semver.Version.parse("3.4.5")
>>> ver.bump_major()
Version(major=4, minor=0, patch=0, prerelease=None, build=None)

It is allowed to concatenate different "bump functions":

>>> ver.bump_major().bump_minor()
Version(major=4, minor=1, patch=0, prerelease=None, build=None)

To compare two versions, semver provides the semver.compare function. The return value indicates the relationship between the first and second version:

>>> semver.compare("1.0.0", "2.0.0")
-1
>>> semver.compare("2.0.0", "1.0.0")
1
>>> semver.compare("2.0.0", "2.0.0")
0

There are other functions to discover. Read on!

python-semver's People

Contributors

anvil avatar b0uh avatar beatgammit avatar bittner avatar def- avatar dschwoerer avatar flamefire avatar jakul avatar jieter avatar jmi2k avatar k-bx avatar kxepal avatar mgorny avatar mssalvatore avatar mzjp2 avatar ofek avatar oidatiftla avatar peblair avatar pipermerriam avatar ppkt avatar robi-wan avatar sbrudenell avatar scls19fr avatar soneji avatar tazle avatar tlaferriere avatar tomschr avatar zanecodes avatar zgoda-mobica avatar zlalanne avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-semver's Issues

Complex filters

hi, I'm trying to use python-semver for more complex comparison :)

>>> semver.match('6.2.3', '>=6,<6.2.1|>=4.0.0-rc2,<4.2.4|>=5,<5.3.1')

which should match according to the rules composer does it. This is obviously currently not supported but I would really love it to have a method for something like this :)

Node

Is this package compatible with npm's semantic versioning?

semver-object

In my opinion your approach to parsing is quite "unpythonic", I would prefer smth like this:

info = semver('1.0.0')

that would allow easy comparison with

>> semver('1.0.0') > semver('2.0.0')
>> False

(yes I know there's semver.compare for that)
Python is a object-orientated language after all ;)

Version comparison does not conform to semver spec for prerelease tags.

The semver spec from http://semver.org/ states the following under section 11 of the spec with respect to how version precedence should be computed.

1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0

This library fails on some of these comparisons.

In [6]: pairs = (
 ('1.0.0-alpha', '1.0.0-alpha.1'),
 ('1.0.0-alpha.1', '1.0.0-alpha.beta'),
 ('1.0.0-alpha.beta', '1.0.0-beta'),
 ('1.0.0-beta', '1.0.0-beta.2'),
 ('1.0.0-beta.2', '1.0.0-beta.11'),
 ('1.0.0-beta.11', '1.0.0-rc.1'),
 ('1.0.0-rc.1', '1.0.0'))

In [7]: for a, b in pairs:
   ...:     print("Checking {0} < {1} =>".format(a, b), semver.cmp(a, b) == -1)
   ...:
Checking 1.0.0-alpha < 1.0.0-alpha.1 => True
Checking 1.0.0-alpha.1 < 1.0.0-alpha.beta => True
Checking 1.0.0-alpha.beta < 1.0.0-beta => True
Checking 1.0.0-beta < 1.0.0-beta.2 => True
Checking 1.0.0-beta.2 < 1.0.0-beta.11 => False
Checking 1.0.0-beta.11 < 1.0.0-rc.1 => True
Checking 1.0.0-rc.1 < 1.0.0 => False

Specifically, 1.0.0-beta.2 < 1.0.0-beta.11 and 1.0.0-rc.1 < 1.0.0 do not resolve to the correct comparison.

Rename tests.py test_semver.py

Hello,

Renaming tests.py test_semver.py could help contributors who don't use tox to simply run unit tests locally using py.test.
Anyway, even if they don't look at tox.ini, flake8 will be run on CI side.

Opinions?

Kind regards

VersionInfo string representation

It seems that the string representation is not available from VersionInfo. It should be quite straightforward to do with a custom string representation method:

def __str__(self) -> str:
    return (str(version.major) or '') \
           + (('.' + str(version.minor)) if version.minor is not None else '') \
           + (('.' + str(version.patch)) if version.patch is not None else '') \
           + (('-' + str(version.prerelease)) if version.prerelease is not None else '') \
           + (('+' + str(version.build)) if version.build is not None else '')

Note that we can keep __repr__ untouched so that it provides unambiguous representation.

semver 2.0 is broken

The following code

import semver
print semver.compare("2.0.0", "2.0.0")

prints 1 instead of 0

Bad rendering of VersionInfo in Pandas DataFrame

Hello,

I noticed that VersionInfo are rendered badly in Pandas DataFrame.
(see scls19fr/arduino_libraries_search#8 )

They are rendered as tuple.

In [1]: import pandas as pd
In [2]: import semver
In [3]: versions = ['4.0.0', '5.0.0', '5.0.1', '10.0.0']
In [4]: df = pd.DataFrame(versions, columns=['versions'])
In [5]: df  # version as string
In [6]: df.sort_values(by='versions')  # so they are not ordered correctly
Out[6]:
  versions
3   10.0.0
0    4.0.0
1    5.0.0
2    5.0.1
In [7]: df['versions'] = df['versions'].map(semver.parse_version_info)  # parse versions as `VersionInfo`
In [8]: df.sort_values(by='versions')  # VersionInfo are ordered correctly but are badly rendered
Out[8]:
                 versions
0   (4, 0, 0, None, None)
1   (5, 0, 0, None, None)
2   (5, 0, 1, None, None)
3  (10, 0, 0, None, None)

I don't know what method Pandas use for rendering them.
What I see is that it's neither using __str__ neither using __repr__ method

In [9]: v = df['versions'].iloc[-1]

In [10]: v
Out[10]: VersionInfo(major=10, minor=0, patch=0, prerelease=None, build=None)

In [11]: v.__str__()
Out[11]: '10.0.0'

In [12]: v.__repr__()
Out[12]: 'VersionInfo(major=10, minor=0, patch=0, prerelease=None, build=None)'

VersionInfo inherits from namedtuple so this is probably related.

Any idea?

Parse a version string to a version info tuple

The Python standard library provides a convention of a “version info tuple”, e.g. the sys.version_info tuple.

Please add a feature to parse a version string to a named tuple of the components.

String representation

At the moment semver just prints out the dictionary of the VersionInfo object.
It should have a decent print output like:
version = semver.parse('7.2.0')
print version

with output 7.2.0

Tag 2.7.9 release

Hello

I notice that https://pypi.org/project/semver/ have a 2.7.9 release
But there is no tag here.

We should have a tag for this version.

Maybe we should have a file with a release procedure (a kind of checklist to ensure that we don't forget something)

Kind regards

API for Moving to Final Releases

(Disclaimer: this is certainly something that could be "self-rolled" from what is already exposed by python-semver, but it seems like a useful API to provide)
To my knowledge, there is a gap in the bump_* family of functions. Consider the version v = 1.2.3-rc.4+build.5:

bump_major(v)      -> 2.0.0
bump_minor(v)      -> 1.3.0
bump_patch(v)      -> 1.2.4
bump_prerelease(v) -> 1.2.3-rc.5
bump_build(v)      -> 1.2.3-rc.4+build.6

What I think would be useful is something along the lines of a finalize_version function, which would convert both 1.2.3 and 1.2.3-rc.4+build.5 into 1.2.3 (i.e. the corresponding final version). Alternatively, if we want to look at node-semver as inspiration, the behavior of bump_patch could be changed such that 1.2.3-rc.4 would bump to 1.2.3, while 1.2.3 would bump to 1.2.4. The intuition is that, since the spec says that these final versions are greater than the prerelease builds, it would make sense to be able to "bump" to them.

Would you agree that this is worth adding?

Wrong version of semver

I was surprised the semver I got was different from the one I installed...

$ pip install semver
Collecting semver
  Downloading semver-2.7.9.tar.gz
Building wheels for collected packages: semver
  Running setup.py bdist_wheel for semver ... done
  Stored in directory: /cygdrive/c/Users/Ycr/Home/.cache/pip/wheels/50/53/f6/4b3f5e28484ca571be4c53373033a07c699d175cdd3337129d
Successfully built semver
Installing collected packages: semver
Successfully installed semver-2.7.9

And what I get is

>>> import semver
>>> semver.__path__
['/usr/lib/python2.7/site-packages/semver']
>>> semver.SEMVER_SPEC_VERSION
'2.0.0'

So it seems I got two semver packages that are in conflict:

$ ls /usr/lib/python2.7/site-packages | grep semver
node_semver-0.1.1.dist-info/
semver/
semver.py
semver.pyc
semver-2.7.9.dist-info/

So it seems Python uses the semver/ instead of semver.py. Is this something expected?

I am on Cygwin

$ uname -a
CYGWIN_NT-6.1 MYPC 2.9.0(0.318/5/3) 2017-09-08 10:19 x86_64 Cygwin

AttributeError: readonly attribute

python --version
Python 3.2.5 (b2091e973da6, Oct 19 2014, 18:29:55)
[PyPy 2.4.0 with GCC 4.6.3]
Collecting semver<3.0.0,>=2.2.1 (from pkutils<0.14.0,>=0.13.4->-r dev-requirements.txt (line 19))
  Downloading semver-2.7.5.tar.gz
    Traceback (most recent call last):
      File "<string>", line 20, in <module>
      File "/tmp/pip-build-8u5mmw/semver/setup.py", line 2, in <module>
        import semver as package
      File "semver.py", line 68, in <module>
        VersionInfo.__doc__ = """
    AttributeError: readonly attribute
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
    
      File "<string>", line 20, in <module>
    
      File "/tmp/pip-build-8u5mmw/semver/setup.py", line 2, in <module>
    
        import semver as package
    
      File "semver.py", line 68, in <module>
    
        VersionInfo.__doc__ = """
    
    AttributeError: readonly attribute

Sphynx doc with usage and also API

Maybe a real doc (using Sphynx for example) should be written.

Here is an example (which probably have room for improvement)
http://windrose.readthedocs.io/en/latest/install.html
https://github.com/python-windrose/windrose/tree/master/docs

Sphynx is not limited to reStructuredText, it also accept Markdown (which is better for most contributors)

API doc is generate automatically and can be build for each push using trigger and/or Travis build.

Doc can be available at Read The Docs or as GitHub pages.
I don't know what is the best...

Anyone want to tackle this?

Replicating usage docs results in '<' not supported between instances of 'VersionInfo' and 'tuple'

I feel like I must be missing something, but when I follow the docs here, I get:

In [1]: import semver

In [2]: semver.__version__
Out[2]: '2.8.1'

In [3]: from semver import VersionInfo

In [4]: version_info = VersionInfo.parse("3.4.5-pre.2+build.4")

In [5]: version_info
Out[5]: VersionInfo(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')

In [6]: version_info > (1, 0)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-d89d50dc6fc1> in <module>()
----> 1 version_info > (1, 0)

TypeError: '>' not supported between instances of 'VersionInfo' and 'tuple'

In [7]: version_info < (3, 5)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-3076f0f266b0> in <module>()
----> 1 version_info < (3, 5)

TypeError: '<' not supported between instances of 'VersionInfo' and 'tuple'

Parametrize tests

Hello,

Using version string as data (ie parameter) for unit tests simplifies (reduce number of lines of) tests code and also can help to easily improve number of test cases.

#47 from @tomschr adresses this issue but haven't been discussed and haven't been merged since Jan 2017

Any news?

Kind regards

How to get string from VersionInfo?

I have a Git tag v2.0.0 that I want to use in semver and add the commit build to it. Eventually I want to get 2.0.0+2ab23f4.

Ideally I would like to write this:

>>> import semver
>>> tag = 'v2.0.0'
>>> v = semver.parse_version_info(tag)
>>> v.bump_build('2ab23f4')
>>> str(v)
2.0.0+2ab23f4

Unfortunately VersionInfo is not a semver class which has no methods such as to-string.

How should I write this using semver?

Object comparison works different than function comparison

Hi there!

I'm trying to use object comparison but I'm not getting the expected results:

>>> import semver

>>> v1 = '0.10.4'
>>> v2 = '0.10.4-beta.1'

"""
from: semver#compare
The return value is negative if ver1 < ver2,
zero if ver1 == ver2 and strictly positive if ver1 > ver2
"""
>>> semver.compare(v1, v2) > 0
True
>>> semver.compare(v2, v1) < 0
True

# until here, everythings works as expected

>>> v1o = semver.parse_version_info(v1)
>>> v2o = semver.parse_version_info(v2)

>>> v1o
VersionInfo(major=0, minor=10, patch=4, prerelease=None, build=None)
>>> v2o
VersionInfo(major=0, minor=10, patch=4, prerelease='beta.1', build=None)

# this is where things go wrong:
>>> v1o > v2o
False
>>> v2o < v1o
False

VersionInfo should support string output

It may seem weird, but the VersionInfo object lacks the "opposite" thing of parsing a SemVer. I just like to have a str output like "3.0.0" from a VersionInfo - this is not implemented.
Wouldn't it be nice to have something like

def to_str(self):
    return self.format_version(
        self.major, 
        self.minor,
        self.patch,
        self.prerelease,
        self.build
    )

So if you have a VersionInfo object you can print out the original/created string again (for saving in a DB e.g.):

>>> version = VersionInfo(3, 4, 5)
>>> print(version.to_str())
3.4.5

Command Line Interface

I've been working on a continuous integration pipeline that needs to perform very basic operations on an applications current version. The application's pipeline is currently a series of Shell commands strung together and while it would be possible to rework much of the pipeline as a Python script that uses python-semver as-is, extending python-semver with a command line interface ended up being a much lower level of effort.

While the interface I wrote is far from comprehensive, I was wondering if a CLI was something you'd be interested in having as part of the python-semver core package.

Here is a Gist of what I'd written for my immediate needs: https://gist.github.com/mattrohland/43b47bd079bd3d47adf674cbdbd970c3

Prerelease comparisons not according to semver.org

It seems that comparisons of pre-release versions do not work according semver.org specification:

Example:

$ python -c "import semver; print(semver.min_ver('1.2.3-rc2', '1.2.3-rc10'))"
1.2.3-rc2

According to semver.org, the parts after dash should be split at '.', and alphanumeric parts compared lexicographically and numeric parts numerically. It seems that this is not the case in semver-the-module.

Add a max(ver1, ver2) function

Add a max function that compares two semver numbers and returns the larger of the two. Similar to the standard library max when passing in ints. Could also use a min version as well.

RTD - commits won't trigger new builds

Hello @k-bx ,

python-semver doc is available at ReadTheDocs (RTD)
See https://python-semver.readthedocs.io/en/latest/

Although

https://readthedocs.org/projects/python-semver/ displays

This repository doesn't have a valid webhook set up, commits won't trigger new builds for this project.  See your project integrations for more information.

Could you create an account at https://readthedocs.org/
so I could add you as a maintainer also.

You will have to setup webhook according
http://docs.readthedocs.io/en/latest/webhooks.html
in this GitHub repository to be able to automatically build doc

Kind regards

VersionInfo constructor should use keyword arguments for prerelease and build with default set as None

https://github.com/k-bx/python-semver/blob/d964b1668cb9ae0d941b9fdbec9f3b42121805c3/semver.py#L86

should be

 def __init__(self, major, minor, patch, prerelease=None, build=None): 

Code showing problem:

In [1]: from semver import VersionInfo

In [2]: VersionInfo(1, 2, 3)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-f524b302b2ba> in <module>()
----> 1 VersionInfo(1,2,3)

TypeError: __init__() missing 2 required positional arguments: 'prerelease' and 'build'

In [3]: VersionInfo(1, 2, 3, None, None)
Out[3]: VersionInfo(major=1, minor=2, patch=3, prerelease=None, build=None)

New version

Can we expect new version? (It was broken by #37)
Because current 2.7.1 fails my functionality with not able to parse 1.0.0-rc.0 version.

(not semver) Support for less than major.minor.patch

Althoug semver states that m.m.p should be present. That does not mean it always is. Some software only gives a major or major.minor number. I would like semver to parse those numbers with minor or patch numbers defaulting to 0. That's what is ment by those major only numbers anyway.

version = semver.parse('3.0')
Should result in 3.0.0

version = semver.parse('10')
Should result in 10.0.0

Add majorize/minorize

I have the following functions in my helper library:

def majorize(version):
    version_info = semver.parse(version)
    return "%d" % (version_info["major"])

def minorize(version):
    version_info = semver.parse(version)
    return "%d.%d" % (version_info["major"], version_info["minor"])

Although it assumes that the relevant versions are available, would you accept a PR for adding these functions?

problem with semver compare

semver is returning error with semver.compare with values:

VersionInfo(major=1, minor=9, patch=1, prerelease='1unms', build=None)
>>> semver.parse_version_info("1.9.1+1")
VersionInfo(major=1, minor=9, patch=1, prerelease=None, build='1')
>>> semver.compare("1.9.1-1unms","1.9.1+1")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/acid/Projects/firmware-update/.virtualenv/lib/python3.6/site-packages/semver.py", line 189, in compare
    return _compare_by_keys(v1, v2)
  File "/Users/acid/Projects/firmware-update/.virtualenv/lib/python3.6/site-packages/semver.py", line 165, in _compare_by_keys
    rccmp = _nat_cmp(rc1, rc2)
  File "/Users/acid/Projects/firmware-update/.virtualenv/lib/python3.6/site-packages/semver.py", line 149, in _nat_cmp
    a_parts, b_parts = split_key(a), split_key(b)
  File "/Users/acid/Projects/firmware-update/.virtualenv/lib/python3.6/site-packages/semver.py", line 136, in split_key
    return [convert(c) for c in key.split('.')]
  File "/Users/acid/Projects/firmware-update/.virtualenv/lib/python3.6/site-packages/semver.py", line 136, in <listcomp>
    return [convert(c) for c in key.split('.')]
  File "/Users/acid/Projects/firmware-update/.virtualenv/lib/python3.6/site-packages/semver.py", line 133, in convert
    return int(text) if re.match('[0-9]+', text) else text
ValueError: invalid literal for int() with base 10: '1unms'
>>>```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.