{"record":{"id":"0f0c6bc515b6d955","repo":"oraios/serena","slug":"the-given-argument-must-be-either-a-version-string","errorCode":null,"errorMessage":"The given argument must be either a version string or a package object with a __version__ attribute","messagePattern":"The given argument must be either a version string or a package object with a __version__ attribute","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/serena/util/version.py","lineNumber":22,"sourceCode":"\n    Suffixes like \"rc1\" or \"-dev\" are ignored, i.e. for a version string like \"1.2.3rc1\",\n    the components are [1, 2, 3].\n    \"\"\"\n\n    def __init__(self, package_or_version: object | str):\n        \"\"\"\n        :param package_or_version: a package object (with a `__version__` attribute) or a version string like \"1.2.3\".\n            If a version contains a suffix (like \"1.2.3rc1\" or \"1.2.3-dev\"), the suffix is ignored.\n        \"\"\"\n        if isinstance(package_or_version, str):\n            version_string = package_or_version\n        elif hasattr(package_or_version, \"__version__\"):\n            package_version_string = getattr(package_or_version, \"__version__\", None)\n            if package_version_string is None:\n                raise ValueError(f\"The given package object {package_or_version} has no __version__ attribute\")\n            version_string = package_version_string\n        else:\n            raise ValueError(\"The given argument must be either a version string or a package object with a __version__ attribute\")\n        self.version_string = version_string\n        self.components = self._get_version_components(version_string)\n\n    def __repr__(self) -> str:\n        return self.version_string\n\n    @staticmethod\n    def _get_version_components(version_string: str) -> list[int]:\n        components = version_string.split(\".\")\n        int_components = []\n        for c in components:\n            num_str = \"\"\n            for ch in c:\n                if ch.isdigit():\n                    num_str += ch\n                else:\n                    break\n            if num_str == \"\":","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/util/version.py#L4-L40","documentation":"Version's __init__ also raises when the argument is neither a string nor an object that has a __version__ attribute at all. It tells the caller the input type is wrong — only version strings or package-like objects are supported.","triggerScenarios":"Passing an int, a Version instance of another library, a dict, or an object without __version__ (e.g. a plain class or a function) to Version(...).","commonSituations":"Confusing a package's main class with its module; passing version tuples/ints from other tooling; refactors that changed the argument from a string to an object.","solutions":["Pass a version string: Version('2.1.0')","Pass the actual module object (import mypkg; Version(mypkg)) which carries __version__","Coerce other formats to str first, e.g. Version('.'.join(map(str, ver_tuple)))"],"exampleFix":"// before\nVersion((1, 4, 2))  # tuple, not supported\n// after\nVersion('.'.join(map(str, (1, 4, 2))))  # '1.4.2'","handlingStrategy":"type-guard","validationCode":"if not isinstance(arg, str) and not hasattr(arg, '__version__'):\n    raise TypeError('Version() needs a str or an object with __version__')","typeGuard":"def is_version_input(arg: object) -> TypeGuard[Union[str, object]]:\n    return isinstance(arg, str) or hasattr(arg, '__version__')","tryCatchPattern":"try:\n    v = Version(arg)\nexcept ValueError as e:\n    if 'must be either a version string' in str(e):\n        v = Version(str(arg))\n    else:\n        raise","preventionTips":["Pass the module object, not a class from it","Convert tuples/ints to strings before constructing","Add isinstance/hasattr checks at call sites"],"tags":["versioning","type-error","validation"],"backgroundTag":"invalid-argument-type","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}