Visitar URL original
increasing next_version 'prerelease' with different prerelease_token · Issue #339 · python-semver/python-semver · GitHub
Skip to content

increasing next_version 'prerelease' with different prerelease_token #339

Closed

Description

@hokreb

Situation

I am not shure if this should be seen as a bug or an enhancement. I have observed this behaviour in version 2.13 of semver.

If I have a version 1.2.3

ver = semver.VersionInfo.parse('1.2.3')

and would like to get the next dev Version,
I will get the version 1.2.4-dev.1 by calling

ver_dev1 = ver.next_version('prerelease', prerelease_token='dev')

If I would like to get the next release candidate, I would call

ver_rc1 = ver_dev1.next_version('prerelease', prerelease_token='rc')

which should be 1.2.4-rc.1

but the result is 1.2.4-dev.2

To Reproduce

import semver
ver = semver.VersionInfo.parse('1.2.3')
ver_dev1 = ver.next_version('prerelease', prerelease_token='dev')
ver_rc1 = ver_dev1.next_version('prerelease', prerelease_token='rc')
print(ver_rc1)

The result is

1.2.4-dev.2

Expected Behavior

I would assume, that according to semantic versioning the result should be

1.2.4-rc.1

Environment

  • OS: Linux
  • Python version 3.6.13
  • Version of semver library 2.13

Activity

  1. added
    BugError, flaw or fault to produce incorrect or unexpected results
    on May 17, 2021
  2. fleetingbytes commented on Nov 14, 2022

    @fleetingbytes
    Contributor

    Similar behavior is also observed with build bumps. A custom build string once set, cannot be reset in a subsequent call of the bump_build method.

  3. tomschr commented on Nov 23, 2022

    @tomschr
    Member

    Yes, this is similar to issue #369.

  4. tomschr commented on Mar 5, 2023

    @tomschr
    Member

    @hokreb Time flies! Sorry for the delay.

    I've tried to confirm it, but if I use the latest version from the master branch, it works:

    >>> import semver
    >>> ver = semver.VersionInfo.parse('1.2.3')
    >>> str(ver.next_version('prerelease', prerelease_token='dev'))
    '1.2.4-dev.1'

    Can you confirm? If yes, I'd like to close this issue. Thanks!

  5. Mukller commented on Jul 29, 2026

    @Mukller
    Contributor

    Root cause confirmed: bump_prerelease(token, ...) ignores the token parameter when a prerelease already exists.

    Inside bump_prerelease:

    if self._prerelease is not None:
        prerelease = cls._increment_prerelease(self._prerelease)  # token ignored!
    else:
        prerelease = str(token) + '.1'  # token only used for brand-new prerelease

    _increment_prerelease simply finds the trailing number and increments it, so dev.1 → dev.2 regardless of the requested token.

    The maintainer's 2023 confirmation only tested starting from a plain version (1.2.3), where there is no existing prerelease, so the token IS used. The bug reproduces when the token changes between calls:

    import semver
    ver = semver.Version.parse('1.2.3')
    dev1 = ver.next_version('prerelease', prerelease_token='dev')  # 1.2.4-dev.1
    rc1  = dev1.next_version('prerelease', prerelease_token='rc')  # 1.2.4-dev.2 (bug!)
    # expected: 1.2.4-rc.1

    Fix: in next_version, detect when the existing prerelease token differs from the requested one and reset to {new_token}.1 directly:

    if version.prerelease is not None and prerelease_token:
        current_token = version.prerelease.split('.')[0]
        if current_token != prerelease_token:
            return version.replace(prerelease=f'{prerelease_token}.1', build=None)
    return version.bump_prerelease(prerelease_token, bump_when_empty=True)

    I have a PR ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugError, flaw or fault to produce incorrect or unexpected results

    Type

    No type

    Fields

    SIze

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions