From 1dc8f9c574f3347d3e50365452d0d2096b250f12 Mon Sep 17 00:00:00 2001 From: Thomas Schraitle Date: Sun, 24 Nov 2019 20:08:42 +0100 Subject: [PATCH 1/2] Fix #201: Reformat source code with black * Add `pyproject.toml` containing black configuration * Add batch image in `README.rst` * Reformat source code with `black` --- CHANGELOG.rst | 2 +- README.rst | 5 +- docs/conf.py | 92 +++--- pyproject.toml | 20 ++ semver.py | 214 +++++++------- setup.py | 71 ++--- test_semver.py | 765 +++++++++++++++++++++++++++---------------------- 7 files changed, 631 insertions(+), 538 deletions(-) create mode 100644 pyproject.toml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 53079d3c..df88ddcc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -19,7 +19,7 @@ Features * :gh:`187` (:pr:`188`): Added logo for python-semver organization and documentation * :gh:`191` (:pr:`194`): Created manpage for pysemver * :gh:`196` (:pr:`197`): Added distribution specific installation instructions - +* :gh:`201` (:pr:`202`): Reformatted source code with black Bug Fixes --------- diff --git a/README.rst b/README.rst index 62e6b92a..5c35b423 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ Quickstart A Python module for `semantic versioning`_. Simplifies comparing versions. -|build-status| |python-support| |downloads| |license| |docs| +|build-status| |python-support| |downloads| |license| |docs| |black| .. teaser-end @@ -125,3 +125,6 @@ There are other functions to discover. Read on! :target: http://python-semver.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status .. _semantic versioning: http://semver.org/ +.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + :alt: Black Formatter diff --git a/docs/conf.py b/docs/conf.py index 107765f2..a07c94a8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,7 +18,8 @@ # import os import sys -sys.path.insert(0, os.path.abspath('..')) + +sys.path.insert(0, os.path.abspath("..")) from semver import __version__ # noqa: E402 @@ -32,27 +33,27 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.napoleon', - 'sphinx.ext.extlinks', + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", + "sphinx.ext.extlinks", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # -source_suffix = '.rst' +source_suffix = ".rst" # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = 'python-semver' -copyright = '2018, Kostiantyn Rybnikov and all' -author = 'Kostiantyn Rybnikov and all' +project = "python-semver" +copyright = "2018, Kostiantyn Rybnikov and all" +author = "Kostiantyn Rybnikov and all" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -73,21 +74,20 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # Markup to shorten external links # See https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html -extlinks = {'gh': ('https://github.com/python-semver/python-semver/issues/%s', - '#'), - 'pr': ('https://github.com/python-semver/python-semver/pull/%s', - 'PR #'), - } +extlinks = { + "gh": ("https://github.com/python-semver/python-semver/issues/%s", "#"), + "pr": ("https://github.com/python-semver/python-semver/pull/%s", "PR #"), +} # -- Options for HTML output ---------------------------------------------- @@ -95,7 +95,7 @@ # a list of builtin themes. # # html_theme = 'alabaster' -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -106,9 +106,9 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] -html_css_files = ['css/default.css'] +html_css_files = ["css/default.css"] # Custom sidebar templates, must be a dictionary that maps document names # to template names. @@ -116,12 +116,12 @@ # This is required for the alabaster theme # refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'relations.html', # needs 'show_related': True theme option to display - 'searchbox.html', - 'donate.html', + "**": [ + "about.html", + "navigation.html", + "relations.html", # needs 'show_related': True theme option to display + "searchbox.html", + "donate.html", ] } @@ -130,7 +130,7 @@ # -- Options for HTMLHelp output ------------------------------------------ # Output file base name for HTML help builder. -htmlhelp_basename = 'semverdoc' +htmlhelp_basename = "semverdoc" # -- Options for LaTeX output --------------------------------------------- @@ -139,15 +139,12 @@ # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. # # 'preamble': '', - # Latex figure (float) alignment # # 'figure_align': 'htbp', @@ -157,8 +154,13 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'semver.tex', 'python-semver Documentation', - 'Kostiantyn Rybnikov and all', 'manual'), + ( + master_doc, + "semver.tex", + "python-semver Documentation", + "Kostiantyn Rybnikov and all", + "manual", + ) ] @@ -169,11 +171,13 @@ manpage_doc = "pysemver" man_pages = [ - (manpage_doc, - 'pysemver', - 'Helper script for Semantic Versioning', - ["Thomas Schraitle"], - 1) + ( + manpage_doc, + "pysemver", + "Helper script for Semantic Versioning", + ["Thomas Schraitle"], + 1, + ) ] @@ -183,7 +187,13 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'semver', 'python-semver Documentation', - author, 'semver', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "semver", + "python-semver Documentation", + author, + "semver", + "One line description of project.", + "Miscellaneous", + ) ] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..eca41891 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,20 @@ +[tool.black] +line-length = 88 +target-version = ['py37'] +include = '\.pyi?$' +# diff = true +exclude = ''' +( + /( + \.eggs # exclude a few common directories in the + | \.git # root of the project + | \.mypy_cache + | \.tox + | \.venv + | \.env + | _build + | build + | dist + )/ +) +''' diff --git a/semver.py b/semver.py index af7dec66..efe1102e 100644 --- a/semver.py +++ b/semver.py @@ -10,14 +10,14 @@ import sys -__version__ = '2.9.0' -__author__ = 'Kostiantyn Rybnikov' -__author_email__ = 'k-bx@k-bx.com' -__maintainer__ = 'Sebastien Celles' +__version__ = "2.9.0" +__author__ = "Kostiantyn Rybnikov" +__author_email__ = "k-bx@k-bx.com" +__maintainer__ = "Sebastien Celles" __maintainer_email__ = "s.celles@gmail.com" _REGEX = re.compile( - r""" + r""" ^ (?P0|[1-9]\d*) \. @@ -33,15 +33,18 @@ (?:\.[0-9a-zA-Z-]+)* ))? $ - """, re.VERBOSE) + """, + re.VERBOSE, +) -_LAST_NUMBER = re.compile(r'(?:[^\d]*(\d+)[^\d]*)+') +_LAST_NUMBER = re.compile(r"(?:[^\d]*(\d+)[^\d]*)+") #: Contains the implemented semver.org version of the spec SEMVER_SPEC_VERSION = "2.0.0" -if not hasattr(__builtins__, 'cmp'): +if not hasattr(__builtins__, "cmp"): + def cmp(a, b): return (a > b) - (a < b) @@ -69,26 +72,29 @@ def parse(version): """ match = _REGEX.match(version) if match is None: - raise ValueError('%s is not valid SemVer string' % version) + raise ValueError("%s is not valid SemVer string" % version) version_parts = match.groupdict() - version_parts['major'] = int(version_parts['major']) - version_parts['minor'] = int(version_parts['minor']) - version_parts['patch'] = int(version_parts['patch']) + version_parts["major"] = int(version_parts["major"]) + version_parts["minor"] = int(version_parts["minor"]) + version_parts["patch"] = int(version_parts["patch"]) return version_parts def comparator(operator): """ Wrap a VersionInfo binary op method in a type-check """ + @wraps(operator) def wrapper(self, other): comparable_types = (VersionInfo, dict, tuple) if not isinstance(other, comparable_types): - raise TypeError("other type %r must be in %r" - % (type(other), comparable_types)) + raise TypeError( + "other type %r must be in %r" % (type(other), comparable_types) + ) return operator(self, other) + return wrapper @@ -101,7 +107,8 @@ class VersionInfo(object): :param str prerelease: an optional prerelease string :param str build: an optional build string """ - __slots__ = ('_major', '_minor', '_patch', '_prerelease', '_build') + + __slots__ = ("_major", "_minor", "_patch", "_prerelease", "_build") def __init__(self, major, minor=0, patch=0, prerelease=None, build=None): self._major = int(major) @@ -156,17 +163,18 @@ def build(self, value): raise AttributeError("attribute 'build' is readonly") def _astuple(self): - return (self.major, self.minor, self.patch, - self.prerelease, self.build) + return (self.major, self.minor, self.patch, self.prerelease, self.build) def _asdict(self): - return collections.OrderedDict(( - ("major", self.major), - ("minor", self.minor), - ("patch", self.patch), - ("prerelease", self.prerelease), - ("build", self.build) - )) + return collections.OrderedDict( + ( + ("major", self.major), + ("minor", self.minor), + ("patch", self.patch), + ("prerelease", self.prerelease), + ("build", self.build), + ) + ) def __iter__(self): """Implement iter(self).""" @@ -213,7 +221,7 @@ def bump_patch(self): """ return parse_version_info(bump_patch(str(self))) - def bump_prerelease(self, token='rc'): + def bump_prerelease(self, token="rc"): """Raise the prerelease part of the version, return a new object but leave self untouched @@ -228,7 +236,7 @@ def bump_prerelease(self, token='rc'): """ return parse_version_info(bump_prerelease(str(self), token)) - def bump_build(self, token='build'): + def bump_build(self, token="build"): """Raise the build part of the version, return a new object but leave self untouched @@ -268,8 +276,7 @@ def __ge__(self, other): return _compare_by_keys(self._asdict(), _to_dict(other)) >= 0 def __repr__(self): - s = ", ".join("%s=%r" % (key, val) - for key, val in self._asdict().items()) + s = ", ".join("%s=%r" % (key, val) for key, val in self._asdict().items()) return "%s(%s)" % (type(self).__name__, s) def __str__(self): @@ -308,10 +315,10 @@ def replace(self, **parts): return VersionInfo(**version) except TypeError: unknownkeys = set(parts) - set(self._asdict()) - error = ("replace() got %d unexpected keyword " - "argument(s): %s" % (len(unknownkeys), - ", ".join(unknownkeys)) - ) + error = "replace() got %d unexpected keyword " "argument(s): %s" % ( + len(unknownkeys), + ", ".join(unknownkeys), + ) raise TypeError(error) @@ -344,18 +351,22 @@ def parse_version_info(version): """ parts = parse(version) version_info = VersionInfo( - parts['major'], parts['minor'], parts['patch'], - parts['prerelease'], parts['build']) + parts["major"], + parts["minor"], + parts["patch"], + parts["prerelease"], + parts["build"], + ) return version_info def _nat_cmp(a, b): def convert(text): - return int(text) if re.match('^[0-9]+$', text) else text + return int(text) if re.match("^[0-9]+$", text) else text def split_key(key): - return [convert(c) for c in key.split('.')] + return [convert(c) for c in key.split(".")] def cmp_prerelease_tag(a, b): if isinstance(a, int) and isinstance(b, int): @@ -367,7 +378,7 @@ def cmp_prerelease_tag(a, b): else: return cmp(a, b) - a, b = a or '', b or '' + a, b = a or "", b or "" a_parts, b_parts = split_key(a), split_key(b) for sub_a, sub_b in zip(a_parts, b_parts): cmp_result = cmp_prerelease_tag(sub_a, sub_b) @@ -378,12 +389,12 @@ def cmp_prerelease_tag(a, b): def _compare_by_keys(d1, d2): - for key in ['major', 'minor', 'patch']: + for key in ["major", "minor", "patch"]: v = cmp(d1.get(key), d2.get(key)) if v: return v - rc1, rc2 = d1.get('prerelease'), d2.get('prerelease') + rc1, rc2 = d1.get("prerelease"), d2.get("prerelease") rccmp = _nat_cmp(rc1, rc2) if not rccmp: @@ -438,24 +449,26 @@ def match(version, match_expr): False """ prefix = match_expr[:2] - if prefix in ('>=', '<=', '==', '!='): + if prefix in (">=", "<=", "==", "!="): match_version = match_expr[2:] - elif prefix and prefix[0] in ('>', '<'): + elif prefix and prefix[0] in (">", "<"): prefix = prefix[0] match_version = match_expr[1:] else: - raise ValueError("match_expr parameter should be in format , " - "where is one of " - "['<', '>', '==', '<=', '>=', '!=']. " - "You provided: %r" % match_expr) + raise ValueError( + "match_expr parameter should be in format , " + "where is one of " + "['<', '>', '==', '<=', '>=', '!=']. " + "You provided: %r" % match_expr + ) possibilities_dict = { - '>': (1,), - '<': (-1,), - '==': (0,), - '!=': (-1, 1), - '>=': (0, 1), - '<=': (-1, 0) + ">": (1,), + "<": (-1,), + "==": (0,), + "!=": (-1, 1), + ">=": (0, 1), + "<=": (-1, 0), } possibilities = possibilities_dict[prefix] @@ -533,7 +546,7 @@ def _increment_string(string): if match: next_ = str(int(match.group(1)) + 1) start, end = match.span(1) - string = string[:max(end - len(next_), start)] + next_ + string[end:] + string = string[: max(end - len(next_), start)] + next_ + string[end:] return string @@ -548,7 +561,7 @@ def bump_major(version): '4.0.0' """ verinfo = parse(version) - return format_version(verinfo['major'] + 1, 0, 0) + return format_version(verinfo["major"] + 1, 0, 0) def bump_minor(version): @@ -562,7 +575,7 @@ def bump_minor(version): '3.5.0' """ verinfo = parse(version) - return format_version(verinfo['major'], verinfo['minor'] + 1, 0) + return format_version(verinfo["major"], verinfo["minor"] + 1, 0) def bump_patch(version): @@ -576,11 +589,10 @@ def bump_patch(version): '3.4.6' """ verinfo = parse(version) - return format_version(verinfo['major'], verinfo['minor'], - verinfo['patch'] + 1) + return format_version(verinfo["major"], verinfo["minor"], verinfo["patch"] + 1) -def bump_prerelease(version, token='rc'): +def bump_prerelease(version, token="rc"): """Raise the prerelease part of the version :param version: version string @@ -592,14 +604,15 @@ def bump_prerelease(version, token='rc'): '3.4.5-dev.1' """ verinfo = parse(version) - verinfo['prerelease'] = _increment_string( - verinfo['prerelease'] or (token or 'rc') + '.0' + verinfo["prerelease"] = _increment_string( + verinfo["prerelease"] or (token or "rc") + ".0" + ) + return format_version( + verinfo["major"], verinfo["minor"], verinfo["patch"], verinfo["prerelease"] ) - return format_version(verinfo['major'], verinfo['minor'], verinfo['patch'], - verinfo['prerelease']) -def bump_build(version, token='build'): +def bump_build(version, token="build"): """Raise the build part of the version :param version: version string @@ -611,11 +624,14 @@ def bump_build(version, token='build'): '3.4.5-rc.1+build.10' """ verinfo = parse(version) - verinfo['build'] = _increment_string( - verinfo['build'] or (token or 'build') + '.0' + verinfo["build"] = _increment_string(verinfo["build"] or (token or "build") + ".0") + return format_version( + verinfo["major"], + verinfo["minor"], + verinfo["patch"], + verinfo["prerelease"], + verinfo["build"], ) - return format_version(verinfo['major'], verinfo['minor'], verinfo['patch'], - verinfo['prerelease'], verinfo['build']) def finalize_version(version): @@ -629,7 +645,7 @@ def finalize_version(version): '1.2.3' """ verinfo = parse(version) - return format_version(verinfo['major'], verinfo['minor'], verinfo['patch']) + return format_version(verinfo["major"], verinfo["minor"], verinfo["patch"]) def createparser(): @@ -638,49 +654,33 @@ def createparser(): :return: parser instance :rtype: :class:`argparse.ArgumentParser` """ - parser = argparse.ArgumentParser(prog=__package__, - description=__doc__) + parser = argparse.ArgumentParser(prog=__package__, description=__doc__) - parser.add_argument('--version', - action='version', - version='%(prog)s ' + __version__ - ) + parser.add_argument( + "--version", action="version", version="%(prog)s " + __version__ + ) s = parser.add_subparsers() # create compare subcommand - parser_compare = s.add_parser("compare", - help="Compare two versions" - ) + parser_compare = s.add_parser("compare", help="Compare two versions") parser_compare.set_defaults(which="compare") - parser_compare.add_argument("version1", - help="First version" - ) - parser_compare.add_argument("version2", - help="Second version" - ) + parser_compare.add_argument("version1", help="First version") + parser_compare.add_argument("version2", help="Second version") # create bump subcommand - parser_bump = s.add_parser("bump", - help="Bumps a version" - ) + parser_bump = s.add_parser("bump", help="Bumps a version") parser_bump.set_defaults(which="bump") - sb = parser_bump.add_subparsers(title="Bump commands", - dest="bump") + sb = parser_bump.add_subparsers(title="Bump commands", dest="bump") # Create subparsers for the bump subparser: - for p in (sb.add_parser("major", - help="Bump the major part of the version"), - sb.add_parser("minor", - help="Bump the minor part of the version"), - sb.add_parser("patch", - help="Bump the patch part of the version"), - sb.add_parser("prerelease", - help="Bump the prerelease part of the version"), - sb.add_parser("build", - help="Bump the build part of the version")): - p.add_argument("version", - help="Version to raise" - ) + for p in ( + sb.add_parser("major", help="Bump the major part of the version"), + sb.add_parser("minor", help="Bump the minor part of the version"), + sb.add_parser("patch", help="Bump the patch part of the version"), + sb.add_parser("prerelease", help="Bump the prerelease part of the version"), + sb.add_parser("build", help="Bump the build part of the version"), + ): + p.add_argument("version", help="Version to raise") return parser @@ -698,12 +698,13 @@ def process(args): args.parser.print_help() raise SystemExit() elif args.which == "bump": - maptable = {'major': 'bump_major', - 'minor': 'bump_minor', - 'patch': 'bump_patch', - 'prerelease': 'bump_prerelease', - 'build': 'bump_build', - } + maptable = { + "major": "bump_major", + "minor": "bump_minor", + "patch": "bump_patch", + "prerelease": "bump_prerelease", + "build": "bump_build", + } if args.bump is None: # When bump is called without arguments, # print the help and exit @@ -759,4 +760,5 @@ def replace(version, **parts): if __name__ == "__main__": import doctest + doctest.testmod() diff --git a/setup.py b/setup.py index 7c31635b..77f19e73 100755 --- a/setup.py +++ b/setup.py @@ -5,6 +5,7 @@ from os.path import dirname, join from setuptools import setup from setuptools.command.test import test as TestCommand + try: from setuptools.command.clean import clean as CleanCommand except ImportError: @@ -14,7 +15,7 @@ class Tox(TestCommand): - user_options = [('tox-args=', 'a', "Arguments to pass to tox")] + user_options = [("tox-args=", "a", "Arguments to pass to tox")] def initialize_options(self): TestCommand.initialize_options(self) @@ -27,6 +28,7 @@ def finalize_options(self): def run_tests(self): from tox import cmdline + args = self.tox_args if args: args = split(self.tox_args) @@ -37,35 +39,25 @@ def run_tests(self): class Clean(CleanCommand): def run(self): super(CleanCommand, self).run() - delete_in_root = [ - 'build', - '.cache', - 'dist', - '.eggs', - '*.egg-info', - '.tox', - ] - delete_everywhere = [ - '__pycache__', - '*.pyc', - ] + delete_in_root = ["build", ".cache", "dist", ".eggs", "*.egg-info", ".tox"] + delete_everywhere = ["__pycache__", "*.pyc"] for candidate in delete_in_root: rmtree_glob(candidate) - for visible_dir in glob('[A-Za-z0-9]*'): + for visible_dir in glob("[A-Za-z0-9]*"): for candidate in delete_everywhere: rmtree_glob(join(visible_dir, candidate)) - rmtree_glob(join(visible_dir, '*', candidate)) + rmtree_glob(join(visible_dir, "*", candidate)) def rmtree_glob(file_glob): for fobj in glob(file_glob): try: rmtree(fobj) - print('%s/ removed ...' % fobj) + print("%s/ removed ..." % fobj) except OSError: try: remove(fobj) - print('%s removed ...' % fobj) + print("%s removed ..." % fobj) except OSError: pass @@ -79,35 +71,30 @@ def read_file(filename): name=package.__name__, version=package.__version__, description=package.__doc__.strip(), - long_description=read_file('README.rst'), + long_description=read_file("README.rst"), author=package.__author__, author_email=package.__author_email__, - url='https://github.com/python-semver/python-semver', - download_url='https://github.com/python-semver/python-semver/downloads', + url="https://github.com/python-semver/python-semver", + download_url="https://github.com/python-semver/python-semver/downloads", py_modules=[package.__name__], include_package_data=True, - license='BSD', + license="BSD", classifiers=[ - 'Environment :: Web Environment', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: BSD License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Topic :: Software Development :: Libraries :: Python Modules', + "Environment :: Web Environment", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Topic :: Software Development :: Libraries :: Python Modules", ], - tests_require=['tox', 'virtualenv'], - cmdclass={ - 'clean': Clean, - 'test': Tox, - }, - entry_points={ - 'console_scripts': ['pysemver = semver:main'], - } + tests_require=["tox", "virtualenv"], + cmdclass={"clean": Clean, "test": Tox}, + entry_points={"console_scripts": ["pysemver = semver:main"]}, ) diff --git a/test_semver.py b/test_semver.py index 053031f6..b3d0929d 100644 --- a/test_semver.py +++ b/test_semver.py @@ -1,154 +1,181 @@ from argparse import Namespace import pytest # noqa -from semver import (VersionInfo, - bump_build, - bump_major, - bump_minor, - bump_patch, - bump_prerelease, - compare, - createparser, - finalize_version, - format_version, - main, - match, - max_ver, - min_ver, - parse, - parse_version_info, - process, - replace, - ) +from semver import ( + VersionInfo, + bump_build, + bump_major, + bump_minor, + bump_patch, + bump_prerelease, + compare, + createparser, + finalize_version, + format_version, + main, + match, + max_ver, + min_ver, + parse, + parse_version_info, + process, + replace, +) SEMVERFUNCS = [ - compare, createparser, - bump_build, bump_major, bump_minor, bump_patch, bump_prerelease, - finalize_version, format_version, - match, max_ver, min_ver, parse, process, replace, - ] - - -@pytest.mark.parametrize("string,expected", [ - ("rc", "rc"), - ("rc.1", "rc.2"), - ("2x", "3x"), -]) + compare, + createparser, + bump_build, + bump_major, + bump_minor, + bump_patch, + bump_prerelease, + finalize_version, + format_version, + match, + max_ver, + min_ver, + parse, + process, + replace, +] + + +@pytest.mark.parametrize( + "string,expected", [("rc", "rc"), ("rc.1", "rc.2"), ("2x", "3x")] +) def test_should_private_increment_string(string, expected): from semver import _increment_string + assert _increment_string(string) == expected @pytest.fixture def version(): - return VersionInfo(major=1, minor=2, patch=3, - prerelease='alpha.1.2', build='build.11.e0f985a') + return VersionInfo( + major=1, minor=2, patch=3, prerelease="alpha.1.2", build="build.11.e0f985a" + ) -@pytest.mark.parametrize("func", SEMVERFUNCS, - ids=[func.__name__ for func in SEMVERFUNCS]) +@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 -@pytest.mark.parametrize("version,expected", [ - # no. 1 - ("1.2.3-alpha.1.2+build.11.e0f985a", - { - 'major': 1, - 'minor': 2, - 'patch': 3, - 'prerelease': 'alpha.1.2', - 'build': 'build.11.e0f985a', - }), - # no. 2 - ("1.2.3-alpha-1+build.11.e0f985a", - { - 'major': 1, - 'minor': 2, - 'patch': 3, - 'prerelease': 'alpha-1', - 'build': 'build.11.e0f985a', - }), - ("0.1.0-0f", - { - 'major': 0, - 'minor': 1, - 'patch': 0, - 'prerelease': '0f', - 'build': None, - }), - ("0.0.0-0foo.1", - { - 'major': 0, - 'minor': 0, - 'patch': 0, - 'prerelease': '0foo.1', - 'build': None, - }), - ("0.0.0-0foo.1+build.1", - { - 'major': 0, - 'minor': 0, - 'patch': 0, - 'prerelease': '0foo.1', - 'build': 'build.1', - }), -]) +@pytest.mark.parametrize( + "version,expected", + [ + # no. 1 + ( + "1.2.3-alpha.1.2+build.11.e0f985a", + { + "major": 1, + "minor": 2, + "patch": 3, + "prerelease": "alpha.1.2", + "build": "build.11.e0f985a", + }, + ), + # no. 2 + ( + "1.2.3-alpha-1+build.11.e0f985a", + { + "major": 1, + "minor": 2, + "patch": 3, + "prerelease": "alpha-1", + "build": "build.11.e0f985a", + }, + ), + ( + "0.1.0-0f", + {"major": 0, "minor": 1, "patch": 0, "prerelease": "0f", "build": None}, + ), + ( + "0.0.0-0foo.1", + {"major": 0, "minor": 0, "patch": 0, "prerelease": "0foo.1", "build": None}, + ), + ( + "0.0.0-0foo.1+build.1", + { + "major": 0, + "minor": 0, + "patch": 0, + "prerelease": "0foo.1", + "build": "build.1", + }, + ), + ], +) def test_should_parse_version(version, expected): result = parse(version) assert result == expected -@pytest.mark.parametrize("version,expected", [ - # no. 1 - ("1.2.3-rc.0+build.0", - { - 'major': 1, - 'minor': 2, - 'patch': 3, - 'prerelease': 'rc.0', - 'build': 'build.0', - }), - # no. 2 - ("1.2.3-rc.0.0+build.0", - { - 'major': 1, - 'minor': 2, - 'patch': 3, - 'prerelease': 'rc.0.0', - 'build': 'build.0', - }), -]) +@pytest.mark.parametrize( + "version,expected", + [ + # no. 1 + ( + "1.2.3-rc.0+build.0", + { + "major": 1, + "minor": 2, + "patch": 3, + "prerelease": "rc.0", + "build": "build.0", + }, + ), + # no. 2 + ( + "1.2.3-rc.0.0+build.0", + { + "major": 1, + "minor": 2, + "patch": 3, + "prerelease": "rc.0.0", + "build": "build.0", + }, + ), + ], +) def test_should_parse_zero_prerelease(version, expected): result = parse(version) assert result == expected -@pytest.mark.parametrize("left,right", [ - ("1.0.0", "2.0.0"), - ('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'), -]) +@pytest.mark.parametrize( + "left,right", + [ + ("1.0.0", "2.0.0"), + ("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"), + ], +) def test_should_get_less(left, right): assert compare(left, right) == -1 -@pytest.mark.parametrize("left,right", [ - ("2.0.0", "1.0.0"), - ('1.0.0-alpha.1', '1.0.0-alpha'), - ('1.0.0-alpha.beta', '1.0.0-alpha.1'), - ('1.0.0-beta', '1.0.0-alpha.beta'), - ('1.0.0-beta.2', '1.0.0-beta'), - ('1.0.0-beta.11', '1.0.0-beta.2'), - ('1.0.0-rc.1', '1.0.0-beta.11'), - ('1.0.0', '1.0.0-rc.1') -]) +@pytest.mark.parametrize( + "left,right", + [ + ("2.0.0", "1.0.0"), + ("1.0.0-alpha.1", "1.0.0-alpha"), + ("1.0.0-alpha.beta", "1.0.0-alpha.1"), + ("1.0.0-beta", "1.0.0-alpha.beta"), + ("1.0.0-beta.2", "1.0.0-beta"), + ("1.0.0-beta.11", "1.0.0-beta.2"), + ("1.0.0-rc.1", "1.0.0-beta.11"), + ("1.0.0", "1.0.0-rc.1"), + ], +) def test_should_get_greater(left, right): assert compare(left, right) == 1 @@ -161,34 +188,38 @@ def test_should_no_match_simple(): assert match("2.3.7", ">=2.3.8") is False -@pytest.mark.parametrize("left,right,expected", [ - ("2.3.7", "!=2.3.8", True), - ("2.3.7", "!=2.3.6", True), - ("2.3.7", "!=2.3.7", False), -]) +@pytest.mark.parametrize( + "left,right,expected", + [ + ("2.3.7", "!=2.3.8", True), + ("2.3.7", "!=2.3.6", True), + ("2.3.7", "!=2.3.7", False), + ], +) def test_should_match_not_equal(left, right, expected): assert match(left, right) is expected -@pytest.mark.parametrize("left,right,expected", [ - ("2.3.7", "<2.4.0", True), - ("2.3.7", ">2.3.5", True), - ("2.3.7", "<=2.3.9", True), - ("2.3.7", ">=2.3.5", True), - ("2.3.7", "==2.3.7", True), - ("2.3.7", "!=2.3.7", False), -]) -def test_should_not_raise_value_error_for_expected_match_expression(left, - right, - expected): +@pytest.mark.parametrize( + "left,right,expected", + [ + ("2.3.7", "<2.4.0", True), + ("2.3.7", ">2.3.5", True), + ("2.3.7", "<=2.3.9", True), + ("2.3.7", ">=2.3.5", True), + ("2.3.7", "==2.3.7", True), + ("2.3.7", "!=2.3.7", False), + ], +) +def test_should_not_raise_value_error_for_expected_match_expression( + left, right, expected +): assert match(left, right) is expected -@pytest.mark.parametrize("left,right", [ - ("2.3.7", "=2.3.7"), - ("2.3.7", "~2.3.7"), - ("2.3.7", "^2.3.7"), -]) +@pytest.mark.parametrize( + "left,right", [("2.3.7", "=2.3.7"), ("2.3.7", "~2.3.7"), ("2.3.7", "^2.3.7")] +) def test_should_raise_value_error_for_unexpected_match_expression(left, right): with pytest.raises(ValueError): match(left, right) @@ -200,21 +231,17 @@ def test_should_raise_value_error_for_zero_prefixed_versions(version): parse(version) -@pytest.mark.parametrize("left,right", [ - ('foo', 'bar'), - ('1.0', '1.0.0'), - ('1.x', '1.0.0'), -]) +@pytest.mark.parametrize( + "left,right", [("foo", "bar"), ("1.0", "1.0.0"), ("1.x", "1.0.0")] +) def test_should_raise_value_error_for_invalid_value(left, right): with pytest.raises(ValueError): compare(left, right) -@pytest.mark.parametrize("left,right", [ - ('1.0.0', ''), - ('1.0.0', '!'), - ('1.0.0', '1.0.0'), -]) +@pytest.mark.parametrize( + "left,right", [("1.0.0", ""), ("1.0.0", "!"), ("1.0.0", "1.0.0")] +) def test_should_raise_value_error_for_invalid_match_expression(left, right): with pytest.raises(ValueError): match(left, right) @@ -229,78 +256,88 @@ def test_should_follow_specification_comparison(): and in backward too. """ chain = [ - '1.0.0-alpha', '1.0.0-alpha.1', '1.0.0-beta.2', '1.0.0-beta.11', - '1.0.0-rc.1', '1.0.0', '1.3.7+build', + "1.0.0-alpha", + "1.0.0-alpha.1", + "1.0.0-beta.2", + "1.0.0-beta.11", + "1.0.0-rc.1", + "1.0.0", + "1.3.7+build", ] versions = zip(chain[:-1], chain[1:]) for low_version, high_version in versions: - assert compare(low_version, high_version) == -1, \ - '%s should be lesser than %s' % (low_version, high_version) - assert compare(high_version, low_version) == 1, \ - '%s should be higher than %s' % (high_version, low_version) + assert ( + compare(low_version, high_version) == -1 + ), "%s should be lesser than %s" % (low_version, high_version) + assert ( + compare(high_version, low_version) == 1 + ), "%s should be higher than %s" % (high_version, low_version) -@pytest.mark.parametrize("left,right", [ - ('1.0.0-beta.2', '1.0.0-beta.11'), -]) +@pytest.mark.parametrize("left,right", [("1.0.0-beta.2", "1.0.0-beta.11")]) def test_should_compare_rc_builds(left, right): assert compare(left, right) == -1 -@pytest.mark.parametrize("left,right", [ - ('1.0.0-rc.1', '1.0.0'), - ('1.0.0-rc.1+build.1', '1.0.0'), -]) +@pytest.mark.parametrize( + "left,right", [("1.0.0-rc.1", "1.0.0"), ("1.0.0-rc.1+build.1", "1.0.0")] +) def test_should_compare_release_candidate_with_release(left, right): assert compare(left, right) == -1 -@pytest.mark.parametrize("left,right", [ - ('2.0.0', '2.0.0'), - ('1.1.9-rc.1', '1.1.9-rc.1'), - ('1.1.9+build.1', '1.1.9+build.1'), - ('1.1.9-rc.1+build.1', '1.1.9-rc.1+build.1'), -]) +@pytest.mark.parametrize( + "left,right", + [ + ("2.0.0", "2.0.0"), + ("1.1.9-rc.1", "1.1.9-rc.1"), + ("1.1.9+build.1", "1.1.9+build.1"), + ("1.1.9-rc.1+build.1", "1.1.9-rc.1+build.1"), + ], +) def test_should_say_equal_versions_are_equal(left, right): assert compare(left, right) == 0 -@pytest.mark.parametrize("left,right,expected", [ - ('1.1.9-rc.1', '1.1.9-rc.1+build.1', 0), - ('1.1.9-rc.1', '1.1.9+build.1', -1), -]) +@pytest.mark.parametrize( + "left,right,expected", + [("1.1.9-rc.1", "1.1.9-rc.1+build.1", 0), ("1.1.9-rc.1", "1.1.9+build.1", -1)], +) def test_should_compare_versions_with_build_and_release(left, right, expected): assert compare(left, right) == expected -@pytest.mark.parametrize("left,right,expected", [ - ('1.0.0+build.1', '1.0.0', 0), - ('1.0.0-alpha.1+build.1', '1.0.0-alpha.1', 0), - ('1.0.0+build.1', '1.0.0-alpha.1', 1), - ('1.0.0+build.1', '1.0.0-alpha.1+build.1', 1), -]) +@pytest.mark.parametrize( + "left,right,expected", + [ + ("1.0.0+build.1", "1.0.0", 0), + ("1.0.0-alpha.1+build.1", "1.0.0-alpha.1", 0), + ("1.0.0+build.1", "1.0.0-alpha.1", 1), + ("1.0.0+build.1", "1.0.0-alpha.1+build.1", 1), + ], +) def test_should_ignore_builds_on_compare(left, right, expected): assert compare(left, right) == expected def test_should_correctly_format_version(): - assert format_version(3, 4, 5) == '3.4.5' - assert format_version(3, 4, 5, 'rc.1') == '3.4.5-rc.1' - assert format_version(3, 4, 5, prerelease='rc.1') == '3.4.5-rc.1' - assert format_version(3, 4, 5, build='build.4') == '3.4.5+build.4' - assert format_version(3, 4, 5, 'rc.1', 'build.4') == '3.4.5-rc.1+build.4' + assert format_version(3, 4, 5) == "3.4.5" + assert format_version(3, 4, 5, "rc.1") == "3.4.5-rc.1" + assert format_version(3, 4, 5, prerelease="rc.1") == "3.4.5-rc.1" + assert format_version(3, 4, 5, build="build.4") == "3.4.5+build.4" + assert format_version(3, 4, 5, "rc.1", "build.4") == "3.4.5-rc.1+build.4" def test_should_bump_major(): - assert bump_major('3.4.5') == '4.0.0' + assert bump_major("3.4.5") == "4.0.0" def test_should_bump_minor(): - assert bump_minor('3.4.5') == '3.5.0' + assert bump_minor("3.4.5") == "3.5.0" def test_should_bump_patch(): - assert bump_patch('3.4.5') == '3.4.6' + assert bump_patch("3.4.5") == "3.4.6" def test_should_versioninfo_bump_major_and_minor(): @@ -344,159 +381,172 @@ def test_should_versioninfo_bump_multiple(): expected = parse_version_info("3.4.5-rc.2+build.2") assert v.bump_prerelease().bump_build().bump_build() == expected expected = parse_version_info("3.4.5-rc.3") - assert v.bump_prerelease().bump_build().bump_build().bump_prerelease() == \ - expected + assert v.bump_prerelease().bump_build().bump_build().bump_prerelease() == expected def test_should_ignore_extensions_for_bump(): - assert bump_patch('3.4.5-rc1+build4') == '3.4.6' + assert bump_patch("3.4.5-rc1+build4") == "3.4.6" def test_should_get_max(): - assert max_ver('3.4.5', '4.0.2') == '4.0.2' + assert max_ver("3.4.5", "4.0.2") == "4.0.2" def test_should_get_max_same(): - assert max_ver('3.4.5', '3.4.5') == '3.4.5' + assert max_ver("3.4.5", "3.4.5") == "3.4.5" def test_should_get_min(): - assert min_ver('3.4.5', '4.0.2') == '3.4.5' + assert min_ver("3.4.5", "4.0.2") == "3.4.5" def test_should_get_min_same(): - assert min_ver('3.4.5', '3.4.5') == '3.4.5' + assert min_ver("3.4.5", "3.4.5") == "3.4.5" def test_should_get_more_rc1(): assert compare("1.0.0-rc1", "1.0.0-rc0") == 1 -@pytest.mark.parametrize("left,right,expected", [ - ('1.2.3-rc.2', '1.2.3-rc.10', '1.2.3-rc.2'), - ('1.2.3-rc2', '1.2.3-rc10', '1.2.3-rc10'), - # identifiers with letters or hyphens are compared lexically in ASCII sort - # order. - ('1.2.3-Rc10', '1.2.3-rc10', '1.2.3-Rc10'), - # Numeric identifiers always have lower precedence than non-numeric - # identifiers. - ('1.2.3-2', '1.2.3-rc', '1.2.3-2'), - # A larger set of pre-release fields has a higher precedence than a - # smaller set, if all of the preceding identifiers are equal. - ('1.2.3-rc.2.1', '1.2.3-rc.2', '1.2.3-rc.2'), - # When major, minor, and patch are equal, a pre-release version has lower - # precedence than a normal version. - ('1.2.3', '1.2.3-1', '1.2.3-1'), - ('1.0.0-alpha', '1.0.0-alpha.1', '1.0.0-alpha') -]) +@pytest.mark.parametrize( + "left,right,expected", + [ + ("1.2.3-rc.2", "1.2.3-rc.10", "1.2.3-rc.2"), + ("1.2.3-rc2", "1.2.3-rc10", "1.2.3-rc10"), + # identifiers with letters or hyphens are compared lexically in ASCII sort + # order. + ("1.2.3-Rc10", "1.2.3-rc10", "1.2.3-Rc10"), + # Numeric identifiers always have lower precedence than non-numeric + # identifiers. + ("1.2.3-2", "1.2.3-rc", "1.2.3-2"), + # A larger set of pre-release fields has a higher precedence than a + # smaller set, if all of the preceding identifiers are equal. + ("1.2.3-rc.2.1", "1.2.3-rc.2", "1.2.3-rc.2"), + # When major, minor, and patch are equal, a pre-release version has lower + # precedence than a normal version. + ("1.2.3", "1.2.3-1", "1.2.3-1"), + ("1.0.0-alpha", "1.0.0-alpha.1", "1.0.0-alpha"), + ], +) def test_prerelease_order(left, right, expected): assert min_ver(left, right) == expected -@pytest.mark.parametrize("version,token,expected", [ - ('3.4.5-rc.9', None, '3.4.5-rc.10'), - ('3.4.5', None, '3.4.5-rc.1'), - ('3.4.5', 'dev', '3.4.5-dev.1'), - ('3.4.5', '', '3.4.5-rc.1'), -]) +@pytest.mark.parametrize( + "version,token,expected", + [ + ("3.4.5-rc.9", None, "3.4.5-rc.10"), + ("3.4.5", None, "3.4.5-rc.1"), + ("3.4.5", "dev", "3.4.5-dev.1"), + ("3.4.5", "", "3.4.5-rc.1"), + ], +) def test_should_bump_prerelease(version, token, expected): token = "rc" if not token else token assert bump_prerelease(version, token) == expected def test_should_ignore_build_on_prerelease_bump(): - assert bump_prerelease('3.4.5-rc.1+build.4') == '3.4.5-rc.2' - - -@pytest.mark.parametrize("version,expected", [ - ('3.4.5-rc.1+build.9', '3.4.5-rc.1+build.10'), - ('3.4.5-rc.1+0009.dev', '3.4.5-rc.1+0010.dev'), - ('3.4.5-rc.1', '3.4.5-rc.1+build.1'), - ('3.4.5', '3.4.5+build.1'), -]) + assert bump_prerelease("3.4.5-rc.1+build.4") == "3.4.5-rc.2" + + +@pytest.mark.parametrize( + "version,expected", + [ + ("3.4.5-rc.1+build.9", "3.4.5-rc.1+build.10"), + ("3.4.5-rc.1+0009.dev", "3.4.5-rc.1+0010.dev"), + ("3.4.5-rc.1", "3.4.5-rc.1+build.1"), + ("3.4.5", "3.4.5+build.1"), + ], +) def test_should_bump_build(version, expected): assert bump_build(version) == expected -@pytest.mark.parametrize("version,expected", [ - ('1.2.3', '1.2.3'), - ('1.2.3-rc.5', '1.2.3'), - ('1.2.3+build.2', '1.2.3'), - ('1.2.3-rc.1+build.5', '1.2.3'), - ('1.2.3-alpha', '1.2.3'), - ('1.2.0', '1.2.0'), -]) +@pytest.mark.parametrize( + "version,expected", + [ + ("1.2.3", "1.2.3"), + ("1.2.3-rc.5", "1.2.3"), + ("1.2.3+build.2", "1.2.3"), + ("1.2.3-rc.1+build.5", "1.2.3"), + ("1.2.3-alpha", "1.2.3"), + ("1.2.0", "1.2.0"), + ], +) def test_should_finalize_version(version, expected): assert finalize_version(version) == expected def test_should_compare_version_info_objects(): v1 = VersionInfo(major=0, minor=10, patch=4) - v2 = VersionInfo( - major=0, minor=10, patch=4, prerelease='beta.1', build=None) + v2 = VersionInfo(major=0, minor=10, patch=4, prerelease="beta.1", build=None) # use `not` to enforce using comparision operators assert v1 != v2 assert v1 > v2 assert v1 >= v2 - assert not(v1 < v2) - assert not(v1 <= v2) - assert not(v1 == v2) + assert not (v1 < v2) + assert not (v1 <= v2) + assert not (v1 == v2) v3 = VersionInfo(major=0, minor=10, patch=4) - assert not(v1 != v3) - assert not(v1 > v3) + assert not (v1 != v3) + assert not (v1 > v3) assert v1 >= v3 - assert not(v1 < v3) + assert not (v1 < v3) assert v1 <= v3 assert v1 == v3 v4 = VersionInfo(major=0, minor=10, patch=5) assert v1 != v4 - assert not(v1 > v4) - assert not(v1 >= v4) + assert not (v1 > v4) + assert not (v1 >= v4) assert v1 < v4 assert v1 <= v4 - assert not(v1 == v4) + assert not (v1 == v4) def test_should_compare_version_dictionaries(): v1 = VersionInfo(major=0, minor=10, patch=4) - v2 = dict(major=0, minor=10, patch=4, prerelease='beta.1', build=None) + v2 = dict(major=0, minor=10, patch=4, prerelease="beta.1", build=None) assert v1 != v2 assert v1 > v2 assert v1 >= v2 - assert not(v1 < v2) - assert not(v1 <= v2) - assert not(v1 == v2) + assert not (v1 < v2) + assert not (v1 <= v2) + assert not (v1 == v2) v3 = dict(major=0, minor=10, patch=4) - assert not(v1 != v3) - assert not(v1 > v3) + assert not (v1 != v3) + assert not (v1 > v3) assert v1 >= v3 - assert not(v1 < v3) + assert not (v1 < v3) assert v1 <= v3 assert v1 == v3 v4 = dict(major=0, minor=10, patch=5) assert v1 != v4 - assert not(v1 > v4) - assert not(v1 >= v4) + assert not (v1 > v4) + assert not (v1 >= v4) assert v1 < v4 assert v1 <= v4 - assert not(v1 == v4) + assert not (v1 == v4) def test_should_compare_version_tuples(): - v0 = VersionInfo(major=0, minor=4, patch=5, - prerelease='pre.2', build='build.4') - v1 = VersionInfo(major=3, minor=4, patch=5, - prerelease='pre.2', build='build.4') - for t in ((1, 0, 0), (1, 0), (1,), (1, 0, 0, 'pre.2'), - (1, 0, 0, 'pre.2', 'build.4')): + v0 = VersionInfo(major=0, minor=4, patch=5, prerelease="pre.2", build="build.4") + v1 = VersionInfo(major=3, minor=4, patch=5, prerelease="pre.2", build="build.4") + for t in ( + (1, 0, 0), + (1, 0), + (1,), + (1, 0, 0, "pre.2"), + (1, 0, 0, "pre.2", "build.4"), + ): assert v0 < t assert v0 <= t assert v0 != t @@ -513,8 +563,7 @@ def test_should_compare_version_tuples(): def test_should_not_allow_to_compare_version_with_string(): - v1 = VersionInfo(major=3, minor=4, patch=5, - prerelease='pre.2', build='build.4') + v1 = VersionInfo(major=3, minor=4, patch=5, prerelease="pre.2", build="build.4") with pytest.raises(TypeError): v1 > "1.0.0" with pytest.raises(TypeError): @@ -522,8 +571,7 @@ def test_should_not_allow_to_compare_version_with_string(): def test_should_not_allow_to_compare_version_with_int(): - v1 = VersionInfo(major=3, minor=4, patch=5, - prerelease='pre.2', build='build.4') + v1 = VersionInfo(major=3, minor=4, patch=5, prerelease="pre.2", build="build.4") with pytest.raises(TypeError): v1 > 1 with pytest.raises(TypeError): @@ -531,8 +579,8 @@ def test_should_not_allow_to_compare_version_with_int(): def test_should_compare_prerelease_with_numbers_and_letters(): - v1 = VersionInfo(major=1, minor=9, patch=1, prerelease='1unms', build=None) - v2 = VersionInfo(major=1, minor=9, patch=1, prerelease=None, build='1asd') + v1 = VersionInfo(major=1, minor=9, patch=1, prerelease="1unms", build=None) + v2 = VersionInfo(major=1, minor=9, patch=1, prerelease=None, build="1asd") assert v1 < v2 assert compare("1.9.1-1unms", "1.9.1+1") == -1 @@ -567,76 +615,96 @@ def test_immutable_patch(version): def test_immutable_prerelease(version): - with pytest.raises(AttributeError, - match="attribute 'prerelease' is readonly"): - version.prerelease = 'alpha.9.9' + with pytest.raises(AttributeError, match="attribute 'prerelease' is readonly"): + version.prerelease = "alpha.9.9" def test_immutable_build(version): with pytest.raises(AttributeError, match="attribute 'build' is readonly"): - version.build = 'build.99.e0f985a' + version.build = "build.99.e0f985a" def test_immutable_unknown_attribute(version): # "no new attribute can be set" with pytest.raises(AttributeError): - version.new_attribute = 'forbidden' + version.new_attribute = "forbidden" def test_version_info_should_be_iterable(version): - assert tuple(version) == (version.major, version.minor, version.patch, - version.prerelease, version.build) + assert tuple(version) == ( + version.major, + version.minor, + version.patch, + version.prerelease, + version.build, + ) def test_should_compare_prerelease_and_build_with_numbers(): - assert VersionInfo(major=1, minor=9, patch=1, prerelease=1, build=1) < \ - VersionInfo(major=1, minor=9, patch=1, prerelease=2, build=1) + assert VersionInfo(major=1, minor=9, patch=1, prerelease=1, build=1) < VersionInfo( + major=1, minor=9, patch=1, prerelease=2, build=1 + ) assert VersionInfo(1, 9, 1, 1, 1) < VersionInfo(1, 9, 1, 2, 1) - assert VersionInfo('2') < VersionInfo(10) - assert VersionInfo('2') < VersionInfo('10') + assert VersionInfo("2") < VersionInfo(10) + assert VersionInfo("2") < VersionInfo("10") def test_should_be_able_to_use_strings_as_major_minor_patch(): - v = VersionInfo('1', '2', '3') + v = VersionInfo("1", "2", "3") assert isinstance(v.major, int) assert isinstance(v.minor, int) assert isinstance(v.patch, int) assert v.prerelease is None assert v.build is None - assert VersionInfo('1', '2', '3') == VersionInfo(1, 2, 3) + assert VersionInfo("1", "2", "3") == VersionInfo(1, 2, 3) def test_using_non_numeric_string_as_major_minor_patch_throws(): with pytest.raises(ValueError): - VersionInfo('a') + VersionInfo("a") with pytest.raises(ValueError): - VersionInfo(1, 'a') + VersionInfo(1, "a") with pytest.raises(ValueError): - VersionInfo(1, 2, 'a') + VersionInfo(1, 2, "a") def test_should_be_able_to_use_integers_as_prerelease_build(): v = VersionInfo(1, 2, 3, 4, 5) assert isinstance(v.prerelease, str) assert isinstance(v.build, str) - assert VersionInfo(1, 2, 3, 4, 5) == VersionInfo(1, 2, 3, '4', '5') - - -@pytest.mark.parametrize("cli,expected", [ - (["bump", "major", "1.2.3"], - Namespace(which='bump', bump='major', version='1.2.3')), - (["bump", "minor", "1.2.3"], - Namespace(which='bump', bump='minor', version='1.2.3')), - (["bump", "patch", "1.2.3"], - Namespace(which='bump', bump='patch', version='1.2.3')), - (["bump", "prerelease", "1.2.3"], - Namespace(which='bump', bump='prerelease', version='1.2.3')), - (["bump", "build", "1.2.3"], - Namespace(which='bump', bump='build', version='1.2.3')), - # --- - (["compare", "1.2.3", "2.1.3"], - Namespace(which='compare', version1='1.2.3', version2='2.1.3')), -]) + assert VersionInfo(1, 2, 3, 4, 5) == VersionInfo(1, 2, 3, "4", "5") + + +@pytest.mark.parametrize( + "cli,expected", + [ + ( + ["bump", "major", "1.2.3"], + Namespace(which="bump", bump="major", version="1.2.3"), + ), + ( + ["bump", "minor", "1.2.3"], + Namespace(which="bump", bump="minor", version="1.2.3"), + ), + ( + ["bump", "patch", "1.2.3"], + Namespace(which="bump", bump="patch", version="1.2.3"), + ), + ( + ["bump", "prerelease", "1.2.3"], + Namespace(which="bump", bump="prerelease", version="1.2.3"), + ), + ( + ["bump", "build", "1.2.3"], + Namespace(which="bump", bump="build", version="1.2.3"), + ), + # --- + ( + ["compare", "1.2.3", "2.1.3"], + Namespace(which="compare", version1="1.2.3", version2="2.1.3"), + ), + ], +) def test_should_parse_cli_arguments(cli, expected): parser = createparser() assert parser @@ -644,26 +712,24 @@ def test_should_parse_cli_arguments(cli, expected): assert result == expected -@pytest.mark.parametrize("args,expected", [ - # bump subcommand - (Namespace(which='bump', bump='major', version='1.2.3'), - "2.0.0"), - (Namespace(which='bump', bump='minor', version='1.2.3'), - "1.3.0"), - (Namespace(which='bump', bump='patch', version='1.2.3'), - "1.2.4"), - (Namespace(which='bump', bump='prerelease', version='1.2.3-rc1'), - "1.2.3-rc2"), - (Namespace(which='bump', bump='build', version='1.2.3+build.13'), - "1.2.3+build.14"), - # compare subcommand - (Namespace(which='compare', version1='1.2.3', version2='2.1.3'), - "-1"), - (Namespace(which='compare', version1='1.2.3', version2='1.2.3'), - "0"), - (Namespace(which='compare', version1='2.4.0', version2='2.1.3'), - "1"), -]) +@pytest.mark.parametrize( + "args,expected", + [ + # bump subcommand + (Namespace(which="bump", bump="major", version="1.2.3"), "2.0.0"), + (Namespace(which="bump", bump="minor", version="1.2.3"), "1.3.0"), + (Namespace(which="bump", bump="patch", version="1.2.3"), "1.2.4"), + (Namespace(which="bump", bump="prerelease", version="1.2.3-rc1"), "1.2.3-rc2"), + ( + Namespace(which="bump", bump="build", version="1.2.3+build.13"), + "1.2.3+build.14", + ), + # compare subcommand + (Namespace(which="compare", version1="1.2.3", version2="2.1.3"), "-1"), + (Namespace(which="compare", version1="1.2.3", version2="1.2.3"), "0"), + (Namespace(which="compare", version1="2.4.0", version2="2.1.3"), "1"), + ], +) def test_should_process_parsed_cli_arguments(args, expected): assert process(args) == expected @@ -692,20 +758,25 @@ def test_should_raise_systemexit_when_bump_iscalled_with_empty_arguments(): main(["bump"]) -@pytest.mark.parametrize("version,parts,expected", [ - ("3.4.5", dict(major=2), '2.4.5'), - ("3.4.5", dict(major="2"), '2.4.5'), - ("3.4.5", dict(major=2, minor=5), '2.5.5'), - ("3.4.5", dict(minor=2), '3.2.5'), - ("3.4.5", dict(major=2, minor=5, patch=10), '2.5.10'), - ("3.4.5", dict(major=2, minor=5, patch=10, prerelease="rc1"), - '2.5.10-rc1'), - ("3.4.5", dict(major=2, minor=5, patch=10, prerelease="rc1", build="b1"), - '2.5.10-rc1+b1'), - ("3.4.5-alpha.1.2", dict(major=2), '2.4.5-alpha.1.2'), - ("3.4.5-alpha.1.2", dict(build="x1"), '3.4.5-alpha.1.2+x1'), - ("3.4.5+build1", dict(major=2), '2.4.5+build1'), -]) +@pytest.mark.parametrize( + "version,parts,expected", + [ + ("3.4.5", dict(major=2), "2.4.5"), + ("3.4.5", dict(major="2"), "2.4.5"), + ("3.4.5", dict(major=2, minor=5), "2.5.5"), + ("3.4.5", dict(minor=2), "3.2.5"), + ("3.4.5", dict(major=2, minor=5, patch=10), "2.5.10"), + ("3.4.5", dict(major=2, minor=5, patch=10, prerelease="rc1"), "2.5.10-rc1"), + ( + "3.4.5", + dict(major=2, minor=5, patch=10, prerelease="rc1", build="b1"), + "2.5.10-rc1+b1", + ), + ("3.4.5-alpha.1.2", dict(major=2), "2.4.5-alpha.1.2"), + ("3.4.5-alpha.1.2", dict(build="x1"), "3.4.5-alpha.1.2+x1"), + ("3.4.5+build1", dict(major=2), "2.4.5+build1"), + ], +) def test_replace_method_replaces_requested_parts(version, parts, expected): assert replace(version, **parts) == expected @@ -715,18 +786,18 @@ def test_replace_raises_TypeError_for_invalid_keyword_arg(): assert replace("1.2.3", unknown="should_raise") -@pytest.mark.parametrize("version,parts,expected", [ - ("3.4.5", dict(major=2, minor=5), '2.5.5'), - ("3.4.5", dict(major=2, minor=5, patch=10), '2.5.10'), - ("3.4.5-alpha.1.2", dict(major=2), '2.4.5-alpha.1.2'), - ("3.4.5-alpha.1.2", dict(build="x1"), '3.4.5-alpha.1.2+x1'), - ("3.4.5+build1", dict(major=2), '2.4.5+build1'), -]) -def test_should_return_versioninfo_with_replaced_parts(version, - parts, - expected): - assert VersionInfo.parse(version).replace(**parts) == \ - VersionInfo.parse(expected) +@pytest.mark.parametrize( + "version,parts,expected", + [ + ("3.4.5", dict(major=2, minor=5), "2.5.5"), + ("3.4.5", dict(major=2, minor=5, patch=10), "2.5.10"), + ("3.4.5-alpha.1.2", dict(major=2), "2.4.5-alpha.1.2"), + ("3.4.5-alpha.1.2", dict(build="x1"), "3.4.5-alpha.1.2+x1"), + ("3.4.5+build1", dict(major=2), "2.4.5+build1"), + ], +) +def test_should_return_versioninfo_with_replaced_parts(version, parts, expected): + assert VersionInfo.parse(version).replace(**parts) == VersionInfo.parse(expected) def test_replace_raises_ValueError_for_non_numeric_values(): From 437bcd2e9e66dfdf832e97935ab305daf4ff3071 Mon Sep 17 00:00:00 2001 From: Thomas Schraitle Date: Sun, 24 Nov 2019 20:52:51 +0100 Subject: [PATCH 2/2] Add config for flake8 Use max-line-length of 88 (default for black) --- setup.cfg | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/setup.cfg b/setup.cfg index 7967d292..b8a0ea49 100644 --- a/setup.cfg +++ b/setup.cfg @@ -7,3 +7,14 @@ addopts = --cov-report=term-missing --doctest-modules --doctest-report ndiff + +[flake8] +max-line-length = 88 +exclude = + .env, + .eggs, + .tox, + .git, + __pycache__, + build, + dist \ No newline at end of file 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