pypa/pip · error · InvalidVersion

Invalid version

Error message

Invalid version: {version!r}

What it means

Raised by Version.__init__() at version.py:419-421 when the version argument is not iterable, causing _SIMPLE_VERSION_INDICATORS.issuperset(version) to raise TypeError. This happens when a non-string, non-iterable value (like None, an int, or a float) is passed to the Version constructor. The TypeError is caught and re-raised as InvalidVersion.

Solutions

  1. Always pass a string to Version(), e.g. Version('1.0') not Version(1.0).
  2. Convert numeric versions with str(value) before constructing Version.
  3. Add a type check or None-guard before calling Version().

Example fix

// before
v = Version(1.0)
// after
v = Version(str(1.0))
Defensive patterns

Strategy: validation

Validate before calling

from packaging.version import Version, InvalidVersion

def safe_version(version):
    if not isinstance(version, str):
        version = str(version)
    return Version(version)

Type guard

def is_string_version(value) -> bool:
    return isinstance(value, str)

Try / catch

from packaging.version import InvalidVersion

try:
    v = Version(version)
except InvalidVersion as e:
    logger.error("Cannot parse version %r: %s", version, e)
    raise

Prevention

When it happens

Trigger: Calling Version(None), Version(123), Version(1.0), or Version() with any non-string scalar type. The issuperset() call on the frozenset requires an iterable; non-iterable values raise TypeError.

Common situations: Passing a numeric version (int/float) instead of a string, passing None from a missing config value, or a variable that was expected to be a string but holds a different type.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/ccec0f14437bcae9. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_vendor/packaging/version.py:421

    _local: LocalType | None

    _hash_cache: int | None
    _key_cache: CmpKey | None

    def __init__(self, version: str) -> None:
        """Initialize a Version object.

        :param version:
            The string representation of a version which will be parsed and normalized
            before use.
        :raises InvalidVersion:
            If the ``version`` does not conform to PEP 440 in any way then this
            exception will be raised.
        """
        try:
            is_simple = _SIMPLE_VERSION_INDICATORS.issuperset(version)
        except TypeError:
            raise InvalidVersion(f"Invalid version: {version!r}") from None

        if is_simple:
            try:
                self._release = tuple(map(int, version.split(".")))
            except AttributeError:
                raise InvalidVersion(f"Invalid version: {version!r}") from None
            except ValueError:
                # Empty parts (from "1..2", ".1", etc.) are invalid versions.
                # Any other ValueError (e.g. int str-digits limit) should
                # propagate to the caller.
                if "" in version.split("."):
                    raise InvalidVersion(f"Invalid version: {version!r}") from None
                # TODO: remove "no cover" when Python 3.9 is dropped.
                raise  # pragma: no cover

            self._epoch = 0
            self._pre = None
            self._post = None

View on GitHub (pinned to f399c37189)