We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Parsing version string error with Keysight_34465A
When I try to connect a Keysight_34465A digital multimeter with 

```
from qcodes.instrument_drivers.Keysight.Keysight_34465A_submodules import Keysight_34465A
dmm = Keysight_34465A('dmm', 'TCPIP0::10.21.64.130::inst0::INSTR')
```

I get "InvalidVersion: Invalid version '65.02.17-02.40-02.17-00.52-04-01'", whereas the actual firmware version is 'A.02.17-02.40-02.17-00.52-04-01':

```
---------------------------------------------------------------------------
InvalidVersion                            Traceback (most recent call last)
Cell In[1], line 2
      1 from qcodes.instrument_drivers.Keysight.Keysight_34465A_submodules import Keysight_34465A
----> 2 dmm = Keysight_34465A('dmm', 'TCPIP0::10.21.64.130::inst0::INSTR')

File ~\.conda\envs\qcodes\lib\site-packages\qcodes\instrument\instrument_meta.py:36, in InstrumentMeta.__call__(cls, *args, **kwargs)
     31 def __call__(cls, *args: Any, **kwargs: Any) -> Any:
     32     """
     33     Overloads `type.__call__` to add code that runs only if __init__ completes
     34     successfully.
     35     """
---> 36     new_inst = super().__call__(*args, **kwargs)
     37     is_abstract = new_inst._is_abstract()
     38     if is_abstract:

File ~\.conda\envs\qcodes\lib\site-packages\qcodes\instrument_drivers\Keysight\Keysight_34465A_submodules.py:12, in Keysight34465A.__init__(self, name, address, silent, **kwargs)
     10 def __init__(self, name: str, address: str, silent: bool = False,
     11              **kwargs: Any):
---> 12     super().__init__(name, address, silent, **kwargs)

File ~\.conda\envs\qcodes\lib\site-packages\qcodes\instrument_drivers\Keysight\private\Keysight_344xxA_submodules.py:470, in _Keysight_344xxA.__init__(self, name, address, silent, **kwargs)
    463 ####################################
    464 # Instrument specifications
    466 options = self._options()
    467 self.has_DIG = self.is_34465A_34470A and (
    468     "DIG" in options
    469     or version.parse(convert_legacy_version_to_supported_version("A.03"))
--> 470     <= version.parse(
    471         convert_legacy_version_to_supported_version(idn["firmware"])
    472     )
    473 )
    474 # Note that the firmware version check is still needed because
    475 # ``_options`` (the ``*OPT?`` command) returns 'DIG' option for
    476 # firmware 3.0 only if it has been purchased before
    477 self.has_MEM = self.is_34465A_34470A and 'MEM' in options

File ~\.conda\envs\qcodes\lib\site-packages\packaging\version.py:52, in parse(version)
     43 def parse(version: str) -> "Version":
     44     """Parse the given version string.
     45 
     46     >>> parse('1.0.dev1')
   (...)
     50     :raises InvalidVersion: When the version string is not a valid version.
     51     """
---> 52     return Version(version)

File ~\.conda\envs\qcodes\lib\site-packages\packaging\version.py:197, in Version.__init__(self, version)
    195 match = self._regex.search(version)
    196 if not match:
--> 197     raise InvalidVersion(f"Invalid version: '{version}'")
    199 # Store the parsed out pieces of the version
    200 self._version = _Version(
    201     epoch=int(match.group("epoch")) if match.group("epoch") else 0,
    202     release=tuple(int(i) for i in match.group("release").split(".")),
   (...)
    208     local=_parse_local_version(match.group("local")),
    209 )
```

OS Windows 11
qcodes 0.37.0
Pyvisa 1.13.0
pyserial 3.5
Parsing version string error with Keysight_34465A
When I try to connect a Keysight_34465A digital multimeter with 

```
from qcodes.instrument_drivers.Keysight.Keysight_34465A_submodules import Keysight_34465A
dmm = Keysight_34465A('dmm', 'TCPIP0::10.21.64.130::inst0::INSTR')
```

I get "InvalidVersion: Invalid version '65.02.17-02.40-02.17-00.52-04-01'", whereas the actual firmware version is 'A.02.17-02.40-02.17-00.52-04-01':

```
---------------------------------------------------------------------------
InvalidVersion                            Traceback (most recent call last)
Cell In[1], line 2
      1 from qcodes.instrument_drivers.Keysight.Keysight_34465A_submodules import Keysight_34465A
----> 2 dmm = Keysight_34465A('dmm', 'TCPIP0::10.21.64.130::inst0::INSTR')

File ~\.conda\envs\qcodes\lib\site-packages\qcodes\instrument\instrument_meta.py:36, in InstrumentMeta.__call__(cls, *args, **kwargs)
     31 def __call__(cls, *args: Any, **kwargs: Any) -> Any:
     32     """
     33     Overloads `type.__call__` to add code that runs only if __init__ completes
     34     successfully.
     35     """
---> 36     new_inst = super().__call__(*args, **kwargs)
     37     is_abstract = new_inst._is_abstract()
     38     if is_abstract:

File ~\.conda\envs\qcodes\lib\site-packages\qcodes\instrument_drivers\Keysight\Keysight_34465A_submodules.py:12, in Keysight34465A.__init__(self, name, address, silent, **kwargs)
     10 def __init__(self, name: str, address: str, silent: bool = False,
     11              **kwargs: Any):
---> 12     super().__init__(name, address, silent, **kwargs)

File ~\.conda\envs\qcodes\lib\site-packages\qcodes\instrument_drivers\Keysight\private\Keysight_344xxA_submodules.py:470, in _Keysight_344xxA.__init__(self, name, address, silent, **kwargs)
    463 ####################################
    464 # Instrument specifications
    466 options = self._options()
    467 self.has_DIG = self.is_34465A_34470A and (
    468     "DIG" in options
    469     or version.parse(convert_legacy_version_to_supported_version("A.03"))
--> 470     <= version.parse(
    471         convert_legacy_version_to_supported_version(idn["firmware"])
    472     )
    473 )
    474 # Note that the firmware version check is still needed because
    475 # ``_options`` (the ``*OPT?`` command) returns 'DIG' option for
    476 # firmware 3.0 only if it has been purchased before
    477 self.has_MEM = self.is_34465A_34470A and 'MEM' in options

File ~\.conda\envs\qcodes\lib\site-packages\packaging\version.py:52, in parse(version)
     43 def parse(version: str) -> "Version":
     44     """Parse the given version string.
     45 
     46     >>> parse('1.0.dev1')
   (...)
     50     :raises InvalidVersion: When the version string is not a valid version.
     51     """
---> 52     return Version(version)

File ~\.conda\envs\qcodes\lib\site-packages\packaging\version.py:197, in Version.__init__(self, version)
    195 match = self._regex.search(version)
    196 if not match:
--> 197     raise InvalidVersion(f"Invalid version: '{version}'")
    199 # Store the parsed out pieces of the version
    200 self._version = _Version(
    201     epoch=int(match.group("epoch")) if match.group("epoch") else 0,
    202     release=tuple(int(i) for i in match.group("release").split(".")),
   (...)
    208     local=_parse_local_version(match.group("local")),
    209 )
```

OS Windows 11
qcodes 0.37.0
Pyvisa 1.13.0
pyserial 3.5

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `qcodes/utils/installation_info.py`
Content:
```
1 """
2 This module contains helper functions that provide information about how
3 QCoDeS is installed and about what other packages are installed along with
4 QCoDeS
5 """
6 import json
7 import logging
8 import subprocess
9 import sys
10 from typing import Dict, Optional
11 
12 if sys.version_info >= (3, 10):
13     # distribution.name used below became part of the
14     # official api in 3.10
15     from importlib.metadata import distributions
16 else:
17     # 3.9 and earlier
18     from importlib_metadata import distributions
19 
20 from qcodes.utils.deprecate import deprecate
21 
22 log = logging.getLogger(__name__)
23 
24 
25 def is_qcodes_installed_editably() -> Optional[bool]:
26     """
27     Try to ask pip whether QCoDeS is installed in editable mode and return
28     the answer a boolean. Returns None if pip somehow did not respond as
29     expected.
30     """
31 
32     answer: Optional[bool]
33 
34     try:
35         pipproc = subprocess.run(['python', '-m', 'pip', 'list', '-e', '--no-index',
36                                   '--format=json'],
37                                  check=True,
38                                  stdout=subprocess.PIPE)
39         e_pkgs = json.loads(pipproc.stdout.decode('utf-8'))
40         answer = any([d["name"] == 'qcodes' for d in e_pkgs])
41     except Exception as e:  # we actually do want a catch-all here
42         log.warning(f'{type(e)}: {str(e)}')
43         answer = None
44 
45     return answer
46 
47 
48 @deprecate("function 'get_qcodes_version'", alternative="qcodes.__version__")
49 def get_qcodes_version() -> str:
50     """
51     Get the version of the currently installed QCoDeS
52     """
53     from qcodes._version import __version__
54     return __version__
55 
56 
57 def get_all_installed_package_versions() -> Dict[str, str]:
58     """
59     Return a dictionary of the currently installed packages and their versions.
60     """
61     return {d.name: d.version for d in distributions()}
62 
63 
64 def convert_legacy_version_to_supported_version(ver: str) -> str:
65     """
66     Convert a legacy version str containing single chars rather than
67     numbers to a regular version string. This is done by replacing a char
68     by its ASCII code (using ``ord``). This assumes that the version number
69     only uses at most a single char per level and only ASCII chars.
70     """
71 
72     temp_list = []
73     for v in ver:
74         if v.isalpha():
75             temp_list.append(str(ord(v.upper())))
76         else:
77             temp_list.append(v)
78     return "".join(temp_list)
79
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/qcodes/utils/installation_info.py b/qcodes/utils/installation_info.py
--- a/qcodes/utils/installation_info.py
+++ b/qcodes/utils/installation_info.py
@@ -67,6 +67,11 @@
     numbers to a regular version string. This is done by replacing a char
     by its ASCII code (using ``ord``). This assumes that the version number
     only uses at most a single char per level and only ASCII chars.
+
+    It also splits off anything that comes after the first ``-`` in the version str.
+
+    This is meant to pass versions like ``'A.02.17-02.40-02.17-00.52-04-01'``
+    primarily used by Keysight instruments.
     """
 
     temp_list = []
@@ -75,4 +80,5 @@
             temp_list.append(str(ord(v.upper())))
         else:
             temp_list.append(v)
-    return "".join(temp_list)
+    temp_str = "".join(temp_list)
+    return temp_str.split("-")[0]

{"golden_diff": "diff --git a/qcodes/utils/installation_info.py b/qcodes/utils/installation_info.py\n--- a/qcodes/utils/installation_info.py\n+++ b/qcodes/utils/installation_info.py\n@@ -67,6 +67,11 @@\n     numbers to a regular version string. This is done by replacing a char\n     by its ASCII code (using ``ord``). This assumes that the version number\n     only uses at most a single char per level and only ASCII chars.\n+\n+    It also splits off anything that comes after the first ``-`` in the version str.\n+\n+    This is meant to pass versions like ``'A.02.17-02.40-02.17-00.52-04-01'``\n+    primarily used by Keysight instruments.\n     \"\"\"\n \n     temp_list = []\n@@ -75,4 +80,5 @@\n             temp_list.append(str(ord(v.upper())))\n         else:\n             temp_list.append(v)\n-    return \"\".join(temp_list)\n+    temp_str = \"\".join(temp_list)\n+    return temp_str.split(\"-\")[0]\n", "issue": "Parsing version string error with Keysight_34465A\nWhen I try to connect a Keysight_34465A digital multimeter with \r\n\r\n```\r\nfrom qcodes.instrument_drivers.Keysight.Keysight_34465A_submodules import Keysight_34465A\r\ndmm = Keysight_34465A('dmm', 'TCPIP0::10.21.64.130::inst0::INSTR')\r\n```\r\n\r\nI get \"InvalidVersion: Invalid version '65.02.17-02.40-02.17-00.52-04-01'\", whereas the actual firmware version is 'A.02.17-02.40-02.17-00.52-04-01':\r\n\r\n```\r\n---------------------------------------------------------------------------\r\nInvalidVersion                            Traceback (most recent call last)\r\nCell In[1], line 2\r\n      1 from qcodes.instrument_drivers.Keysight.Keysight_34465A_submodules import Keysight_34465A\r\n----> 2 dmm = Keysight_34465A('dmm', 'TCPIP0::10.21.64.130::inst0::INSTR')\r\n\r\nFile ~\\.conda\\envs\\qcodes\\lib\\site-packages\\qcodes\\instrument\\instrument_meta.py:36, in InstrumentMeta.__call__(cls, *args, **kwargs)\r\n     31 def __call__(cls, *args: Any, **kwargs: Any) -> Any:\r\n     32     \"\"\"\r\n     33     Overloads `type.__call__` to add code that runs only if __init__ completes\r\n     34     successfully.\r\n     35     \"\"\"\r\n---> 36     new_inst = super().__call__(*args, **kwargs)\r\n     37     is_abstract = new_inst._is_abstract()\r\n     38     if is_abstract:\r\n\r\nFile ~\\.conda\\envs\\qcodes\\lib\\site-packages\\qcodes\\instrument_drivers\\Keysight\\Keysight_34465A_submodules.py:12, in Keysight34465A.__init__(self, name, address, silent, **kwargs)\r\n     10 def __init__(self, name: str, address: str, silent: bool = False,\r\n     11              **kwargs: Any):\r\n---> 12     super().__init__(name, address, silent, **kwargs)\r\n\r\nFile ~\\.conda\\envs\\qcodes\\lib\\site-packages\\qcodes\\instrument_drivers\\Keysight\\private\\Keysight_344xxA_submodules.py:470, in _Keysight_344xxA.__init__(self, name, address, silent, **kwargs)\r\n    463 ####################################\r\n    464 # Instrument specifications\r\n    466 options = self._options()\r\n    467 self.has_DIG = self.is_34465A_34470A and (\r\n    468     \"DIG\" in options\r\n    469     or version.parse(convert_legacy_version_to_supported_version(\"A.03\"))\r\n--> 470     <= version.parse(\r\n    471         convert_legacy_version_to_supported_version(idn[\"firmware\"])\r\n    472     )\r\n    473 )\r\n    474 # Note that the firmware version check is still needed because\r\n    475 # ``_options`` (the ``*OPT?`` command) returns 'DIG' option for\r\n    476 # firmware 3.0 only if it has been purchased before\r\n    477 self.has_MEM = self.is_34465A_34470A and 'MEM' in options\r\n\r\nFile ~\\.conda\\envs\\qcodes\\lib\\site-packages\\packaging\\version.py:52, in parse(version)\r\n     43 def parse(version: str) -> \"Version\":\r\n     44     \"\"\"Parse the given version string.\r\n     45 \r\n     46     >>> parse('1.0.dev1')\r\n   (...)\r\n     50     :raises InvalidVersion: When the version string is not a valid version.\r\n     51     \"\"\"\r\n---> 52     return Version(version)\r\n\r\nFile ~\\.conda\\envs\\qcodes\\lib\\site-packages\\packaging\\version.py:197, in Version.__init__(self, version)\r\n    195 match = self._regex.search(version)\r\n    196 if not match:\r\n--> 197     raise InvalidVersion(f\"Invalid version: '{version}'\")\r\n    199 # Store the parsed out pieces of the version\r\n    200 self._version = _Version(\r\n    201     epoch=int(match.group(\"epoch\")) if match.group(\"epoch\") else 0,\r\n    202     release=tuple(int(i) for i in match.group(\"release\").split(\".\")),\r\n   (...)\r\n    208     local=_parse_local_version(match.group(\"local\")),\r\n    209 )\r\n```\r\n\r\nOS Windows 11\r\nqcodes 0.37.0\r\nPyvisa 1.13.0\r\npyserial 3.5\nParsing version string error with Keysight_34465A\nWhen I try to connect a Keysight_34465A digital multimeter with \r\n\r\n```\r\nfrom qcodes.instrument_drivers.Keysight.Keysight_34465A_submodules import Keysight_34465A\r\ndmm = Keysight_34465A('dmm', 'TCPIP0::10.21.64.130::inst0::INSTR')\r\n```\r\n\r\nI get \"InvalidVersion: Invalid version '65.02.17-02.40-02.17-00.52-04-01'\", whereas the actual firmware version is 'A.02.17-02.40-02.17-00.52-04-01':\r\n\r\n```\r\n---------------------------------------------------------------------------\r\nInvalidVersion                            Traceback (most recent call last)\r\nCell In[1], line 2\r\n      1 from qcodes.instrument_drivers.Keysight.Keysight_34465A_submodules import Keysight_34465A\r\n----> 2 dmm = Keysight_34465A('dmm', 'TCPIP0::10.21.64.130::inst0::INSTR')\r\n\r\nFile ~\\.conda\\envs\\qcodes\\lib\\site-packages\\qcodes\\instrument\\instrument_meta.py:36, in InstrumentMeta.__call__(cls, *args, **kwargs)\r\n     31 def __call__(cls, *args: Any, **kwargs: Any) -> Any:\r\n     32     \"\"\"\r\n     33     Overloads `type.__call__` to add code that runs only if __init__ completes\r\n     34     successfully.\r\n     35     \"\"\"\r\n---> 36     new_inst = super().__call__(*args, **kwargs)\r\n     37     is_abstract = new_inst._is_abstract()\r\n     38     if is_abstract:\r\n\r\nFile ~\\.conda\\envs\\qcodes\\lib\\site-packages\\qcodes\\instrument_drivers\\Keysight\\Keysight_34465A_submodules.py:12, in Keysight34465A.__init__(self, name, address, silent, **kwargs)\r\n     10 def __init__(self, name: str, address: str, silent: bool = False,\r\n     11              **kwargs: Any):\r\n---> 12     super().__init__(name, address, silent, **kwargs)\r\n\r\nFile ~\\.conda\\envs\\qcodes\\lib\\site-packages\\qcodes\\instrument_drivers\\Keysight\\private\\Keysight_344xxA_submodules.py:470, in _Keysight_344xxA.__init__(self, name, address, silent, **kwargs)\r\n    463 ####################################\r\n    464 # Instrument specifications\r\n    466 options = self._options()\r\n    467 self.has_DIG = self.is_34465A_34470A and (\r\n    468     \"DIG\" in options\r\n    469     or version.parse(convert_legacy_version_to_supported_version(\"A.03\"))\r\n--> 470     <= version.parse(\r\n    471         convert_legacy_version_to_supported_version(idn[\"firmware\"])\r\n    472     )\r\n    473 )\r\n    474 # Note that the firmware version check is still needed because\r\n    475 # ``_options`` (the ``*OPT?`` command) returns 'DIG' option for\r\n    476 # firmware 3.0 only if it has been purchased before\r\n    477 self.has_MEM = self.is_34465A_34470A and 'MEM' in options\r\n\r\nFile ~\\.conda\\envs\\qcodes\\lib\\site-packages\\packaging\\version.py:52, in parse(version)\r\n     43 def parse(version: str) -> \"Version\":\r\n     44     \"\"\"Parse the given version string.\r\n     45 \r\n     46     >>> parse('1.0.dev1')\r\n   (...)\r\n     50     :raises InvalidVersion: When the version string is not a valid version.\r\n     51     \"\"\"\r\n---> 52     return Version(version)\r\n\r\nFile ~\\.conda\\envs\\qcodes\\lib\\site-packages\\packaging\\version.py:197, in Version.__init__(self, version)\r\n    195 match = self._regex.search(version)\r\n    196 if not match:\r\n--> 197     raise InvalidVersion(f\"Invalid version: '{version}'\")\r\n    199 # Store the parsed out pieces of the version\r\n    200 self._version = _Version(\r\n    201     epoch=int(match.group(\"epoch\")) if match.group(\"epoch\") else 0,\r\n    202     release=tuple(int(i) for i in match.group(\"release\").split(\".\")),\r\n   (...)\r\n    208     local=_parse_local_version(match.group(\"local\")),\r\n    209 )\r\n```\r\n\r\nOS Windows 11\r\nqcodes 0.37.0\r\nPyvisa 1.13.0\r\npyserial 3.5\n", "before_files": [{"content": "\"\"\"\nThis module contains helper functions that provide information about how\nQCoDeS is installed and about what other packages are installed along with\nQCoDeS\n\"\"\"\nimport json\nimport logging\nimport subprocess\nimport sys\nfrom typing import Dict, Optional\n\nif sys.version_info >= (3, 10):\n    # distribution.name used below became part of the\n    # official api in 3.10\n    from importlib.metadata import distributions\nelse:\n    # 3.9 and earlier\n    from importlib_metadata import distributions\n\nfrom qcodes.utils.deprecate import deprecate\n\nlog = logging.getLogger(__name__)\n\n\ndef is_qcodes_installed_editably() -> Optional[bool]:\n    \"\"\"\n    Try to ask pip whether QCoDeS is installed in editable mode and return\n    the answer a boolean. Returns None if pip somehow did not respond as\n    expected.\n    \"\"\"\n\n    answer: Optional[bool]\n\n    try:\n        pipproc = subprocess.run(['python', '-m', 'pip', 'list', '-e', '--no-index',\n                                  '--format=json'],\n                                 check=True,\n                                 stdout=subprocess.PIPE)\n        e_pkgs = json.loads(pipproc.stdout.decode('utf-8'))\n        answer = any([d[\"name\"] == 'qcodes' for d in e_pkgs])\n    except Exception as e:  # we actually do want a catch-all here\n        log.warning(f'{type(e)}: {str(e)}')\n        answer = None\n\n    return answer\n\n\n@deprecate(\"function 'get_qcodes_version'\", alternative=\"qcodes.__version__\")\ndef get_qcodes_version() -> str:\n    \"\"\"\n    Get the version of the currently installed QCoDeS\n    \"\"\"\n    from qcodes._version import __version__\n    return __version__\n\n\ndef get_all_installed_package_versions() -> Dict[str, str]:\n    \"\"\"\n    Return a dictionary of the currently installed packages and their versions.\n    \"\"\"\n    return {d.name: d.version for d in distributions()}\n\n\ndef convert_legacy_version_to_supported_version(ver: str) -> str:\n    \"\"\"\n    Convert a legacy version str containing single chars rather than\n    numbers to a regular version string. This is done by replacing a char\n    by its ASCII code (using ``ord``). This assumes that the version number\n    only uses at most a single char per level and only ASCII chars.\n    \"\"\"\n\n    temp_list = []\n    for v in ver:\n        if v.isalpha():\n            temp_list.append(str(ord(v.upper())))\n        else:\n            temp_list.append(v)\n    return \"\".join(temp_list)\n", "path": "qcodes/utils/installation_info.py"}], "after_files": [{"content": "\"\"\"\nThis module contains helper functions that provide information about how\nQCoDeS is installed and about what other packages are installed along with\nQCoDeS\n\"\"\"\nimport json\nimport logging\nimport subprocess\nimport sys\nfrom typing import Dict, Optional\n\nif sys.version_info >= (3, 10):\n    # distribution.name used below became part of the\n    # official api in 3.10\n    from importlib.metadata import distributions\nelse:\n    # 3.9 and earlier\n    from importlib_metadata import distributions\n\nfrom qcodes.utils.deprecate import deprecate\n\nlog = logging.getLogger(__name__)\n\n\ndef is_qcodes_installed_editably() -> Optional[bool]:\n    \"\"\"\n    Try to ask pip whether QCoDeS is installed in editable mode and return\n    the answer a boolean. Returns None if pip somehow did not respond as\n    expected.\n    \"\"\"\n\n    answer: Optional[bool]\n\n    try:\n        pipproc = subprocess.run(['python', '-m', 'pip', 'list', '-e', '--no-index',\n                                  '--format=json'],\n                                 check=True,\n                                 stdout=subprocess.PIPE)\n        e_pkgs = json.loads(pipproc.stdout.decode('utf-8'))\n        answer = any([d[\"name\"] == 'qcodes' for d in e_pkgs])\n    except Exception as e:  # we actually do want a catch-all here\n        log.warning(f'{type(e)}: {str(e)}')\n        answer = None\n\n    return answer\n\n\n@deprecate(\"function 'get_qcodes_version'\", alternative=\"qcodes.__version__\")\ndef get_qcodes_version() -> str:\n    \"\"\"\n    Get the version of the currently installed QCoDeS\n    \"\"\"\n    from qcodes._version import __version__\n    return __version__\n\n\ndef get_all_installed_package_versions() -> Dict[str, str]:\n    \"\"\"\n    Return a dictionary of the currently installed packages and their versions.\n    \"\"\"\n    return {d.name: d.version for d in distributions()}\n\n\ndef convert_legacy_version_to_supported_version(ver: str) -> str:\n    \"\"\"\n    Convert a legacy version str containing single chars rather than\n    numbers to a regular version string. This is done by replacing a char\n    by its ASCII code (using ``ord``). This assumes that the version number\n    only uses at most a single char per level and only ASCII chars.\n\n    It also splits off anything that comes after the first ``-`` in the version str.\n\n    This is meant to pass versions like ``'A.02.17-02.40-02.17-00.52-04-01'``\n    primarily used by Keysight instruments.\n    \"\"\"\n\n    temp_list = []\n    for v in ver:\n        if v.isalpha():\n            temp_list.append(str(ord(v.upper())))\n        else:\n            temp_list.append(v)\n    temp_str = \"\".join(temp_list)\n    return temp_str.split(\"-\")[0]\n", "path": "qcodes/utils/installation_info.py"}]}