{"record":{"id":"ccec0f14437bcae9","repo":"pypa/pip","slug":"invalid-version-version-r","errorCode":null,"errorMessage":"Invalid version: {version!r}","messagePattern":"Invalid version: (.+?)","errorType":"validation","errorClass":"InvalidVersion","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/version.py","lineNumber":421,"sourceCode":"    _local: LocalType | None\n\n    _hash_cache: int | None\n    _key_cache: CmpKey | None\n\n    def __init__(self, version: str) -> None:\n        \"\"\"Initialize a Version object.\n\n        :param version:\n            The string representation of a version which will be parsed and normalized\n            before use.\n        :raises InvalidVersion:\n            If the ``version`` does not conform to PEP 440 in any way then this\n            exception will be raised.\n        \"\"\"\n        try:\n            is_simple = _SIMPLE_VERSION_INDICATORS.issuperset(version)\n        except TypeError:\n            raise InvalidVersion(f\"Invalid version: {version!r}\") from None\n\n        if is_simple:\n            try:\n                self._release = tuple(map(int, version.split(\".\")))\n            except AttributeError:\n                raise InvalidVersion(f\"Invalid version: {version!r}\") from None\n            except ValueError:\n                # Empty parts (from \"1..2\", \".1\", etc.) are invalid versions.\n                # Any other ValueError (e.g. int str-digits limit) should\n                # propagate to the caller.\n                if \"\" in version.split(\".\"):\n                    raise InvalidVersion(f\"Invalid version: {version!r}\") from None\n                # TODO: remove \"no cover\" when Python 3.9 is dropped.\n                raise  # pragma: no cover\n\n            self._epoch = 0\n            self._pre = None\n            self._post = None","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/version.py#L403-L439","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Always pass a string to Version(), e.g. Version('1.0') not Version(1.0).","Convert numeric versions with str(value) before constructing Version.","Add a type check or None-guard before calling Version()."],"exampleFix":"// before\nv = Version(1.0)\n// after\nv = Version(str(1.0))","handlingStrategy":"validation","validationCode":"from packaging.version import Version, InvalidVersion\n\ndef safe_version(version):\n    if not isinstance(version, str):\n        version = str(version)\n    return Version(version)","typeGuard":"def is_string_version(value) -> bool:\n    return isinstance(value, str)","tryCatchPattern":"from packaging.version import InvalidVersion\n\ntry:\n    v = Version(version)\nexcept InvalidVersion as e:\n    logger.error(\"Cannot parse version %r: %s\", version, e)\n    raise","preventionTips":["Always pass a string to Version()","Convert numeric types with str() before calling","Add isinstance(version, str) checks at API boundaries"],"tags":["version","type-error","packaging","pep440"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}