Skip to content

Improve Usability with Docstrings #42

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

Merged
merged 3 commits into from
Dec 19, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 145 additions & 4 deletions semver.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,49 @@
"""
Python helper for Semantic Versioning (http://semver.org/)

Examples:
>>> import semver
>>> 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
>>> semver.match("2.0.0", ">=1.0.0")
True
>>> semver.match("1.0.0", ">1.0.0")
False
>>> semver.format_version(3, 4, 5, 'pre.2', 'build.4')
'3.4.5-pre.2+build.4'
>>> version_parts = semver.parse("3.4.5-pre.2+build.4")
>>> version_parts == {
... 'major': 3, 'minor': 4, 'patch': 5,
... 'prerelease': 'pre.2', 'build': 'build.4'}
True
>>> version_info = semver.parse_version_info("3.4.5-pre.2+build.4")
>>> version_info
VersionInfo(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')
>>> version_info.major
3
>>> version_info > (1, 0)
True
>>> version_info < (3, 5)
True
>>> semver.bump_major("3.4.5")
'4.0.0'
>>> semver.bump_minor("3.4.5")
'3.5.0'
>>> semver.bump_patch("3.4.5")
'3.4.6'
>>> semver.max_ver("1.0.0", "2.0.0")
'2.0.0'
>>> semver.min_ver("1.0.0", "2.0.0")
'1.0.0'
"""

import collections
import re
import sys


__version__ = '2.7.2'
Expand Down Expand Up @@ -37,8 +77,13 @@ def cmp(a, b):


def parse(version):
"""
Parse version to major, minor, patch, pre-release, build parts.
"""Parse version to major, minor, patch, pre-release, build parts.

:param version: version string
:return: dictionary with the keys 'build', 'major', 'minor', 'patch',
and 'prerelease'. The prerelease or build keys can be None
if not provided
:rtype: dict
"""
match = _REGEX.match(version)
if match is None:
Expand All @@ -56,10 +101,31 @@ def parse(version):
VersionInfo = collections.namedtuple(
'VersionInfo', 'major minor patch prerelease build')

# Only change it for Python > 3 as it is readonly
# for version 2
if sys.version_info > (3, 0):
VersionInfo.__doc__ = """
:param int major: version when you make incompatible API changes.
:param int minor: version when you add functionality in
a backwards-compatible manner.
:param int patch: version when you make backwards-compatible bug fixes.
:param str prerelease: an optional prerelease string
:param str build: an optional build string

>>> import semver
>>> ver = semver.parse('3.4.5-pre.2+build.4')
>>> ver
{'build': 'build.4', 'major': 3, 'minor': 4, 'patch': 5,
'prerelease': 'pre.2'}
"""


def parse_version_info(version):
"""
Parse version string to a VersionInfo instance.
"""Parse version string to a VersionInfo instance.

:param version: version string
:return: a :class:`VersionInfo` instance
:rtype: :class:`VersionInfo`
"""
parts = parse(version)
version_info = VersionInfo(
Expand All @@ -70,6 +136,14 @@ def parse_version_info(version):


def compare(ver1, ver2):
"""Compare two versions

:param ver1: version string 1
:param ver2: version string 2
:return: The return value is negative if ver1 < ver2,
zero if ver1 == ver2 and strictly positive if ver1 > ver2
:rtype: int
"""
def nat_cmp(a, b):
def convert(text):
return (2, int(text)) if re.match('[0-9]+', text) else (1, text)
Expand Down Expand Up @@ -104,6 +178,19 @@ def compare_by_keys(d1, d2):


def match(version, match_expr):
"""Compare two versions through a comparison

:param str version: a version string
:param str match_expr: operator and version; valid operators are
< smaller than
> greater than
>= greator or equal than
<= smaller or equal than
== equal
!= not equal
:return: True if the expression matches the version, otherwise False
:rtype: bool
"""
prefix = match_expr[:2]
if prefix in ('>=', '<=', '==', '!='):
match_version = match_expr[2:]
Expand Down Expand Up @@ -132,6 +219,13 @@ def match(version, match_expr):


def max_ver(ver1, ver2):
"""Returns the greater version of two versions

:param ver1: version string 1
:param ver2: version string 2
:return: the greater version of the two
:rtype: :class:`VersionInfo`
"""
cmp_res = compare(ver1, ver2)
if cmp_res == 0 or cmp_res == 1:
return ver1
Expand All @@ -140,6 +234,13 @@ def max_ver(ver1, ver2):


def min_ver(ver1, ver2):
"""Returns the smaller version of two versions

:param ver1: version string 1
:param ver2: version string 2
:return: the smaller version of the two
:rtype: :class:`VersionInfo`
"""
cmp_res = compare(ver1, ver2)
if cmp_res == 0 or cmp_res == -1:
return ver1
Expand All @@ -148,6 +249,16 @@ def min_ver(ver1, ver2):


def format_version(major, minor, patch, prerelease=None, build=None):
"""Format a version according to the Semantic Versioning specification

:param str major: the required major part of a version
:param str minor: the required minor part of a version
:param str patch: the required patch part of a version
:param str prerelease: the optional prerelease part of a version
:param str build: the optional build part of a version
:return: the formatted string
:rtype: str
"""
version = "%d.%d.%d" % (major, minor, patch)
if prerelease is not None:
version = version + "-%s" % prerelease
Expand All @@ -172,29 +283,59 @@ def _increment_string(string):


def bump_major(version):
"""Raise the major part of the version

:param: version string
:return: the raised version string
:rtype: str
"""
verinfo = parse(version)
return format_version(verinfo['major'] + 1, 0, 0)


def bump_minor(version):
"""Raise the minor part of the version

:param: version string
:return: the raised version string
:rtype: str
"""
verinfo = parse(version)
return format_version(verinfo['major'], verinfo['minor'] + 1, 0)


def bump_patch(version):
"""Raise the patch part of the version

:param: version string
:return: the raised version string
:rtype: str
"""
verinfo = parse(version)
return format_version(verinfo['major'], verinfo['minor'],
verinfo['patch'] + 1)


def bump_prerelease(version):
"""Raise the prerelease part of the version

:param: version string
:return: the raised version string
:rtype: str
"""
verinfo = parse(version)
verinfo['prerelease'] = _increment_string(verinfo['prerelease'] or 'rc.0')
return format_version(verinfo['major'], verinfo['minor'], verinfo['patch'],
verinfo['prerelease'])


def bump_build(version):
"""Raise the build part of the version

:param: version string
:return: the raised version string
:rtype: str
"""
verinfo = parse(version)
verinfo['build'] = _increment_string(verinfo['build'] or 'build.0')
return format_version(verinfo['major'], verinfo['minor'], verinfo['patch'],
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def read_file(filename):
with open(join(dirname(__file__), filename)) as f:
return f.read()


setup(
name=package.__name__,
version=package.__version__,
Expand Down
13 changes: 13 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@
from semver import max_ver


SEMVERFUNCS = [
compare, match, parse, format_version,
bump_major, bump_minor, bump_patch, bump_prerelease, bump_build,
max_ver, min_ver,
]


@pytest.mark.parametrize("func", SEMVERFUNCS,
ids=[func.__name__ for func in SEMVERFUNCS])
def test_fordocstrings(func):
assert func.__doc__, "Need a docstring for function %r" % func.__name


def test_should_parse_version():
result = parse("1.2.3-alpha.1.2+build.11.e0f985a")
assert result == {
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy