We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Regression with versionsuffix types
Commit https://github.com/easybuilders/easybuild-framework/commit/0e5ba5c858
introduced a check for string-type for `versionsuffix`, while `None` used to be an accepted value for `versionsuffix`. Our hooks replace many version suffixes with `None`. 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `easybuild/tools/module_naming_scheme/utilities.py`
Content:
```
1 ##
2 # Copyright 2009-2023 Ghent University
3 #
4 # This file is part of EasyBuild,
5 # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
6 # with support of Ghent University (http://ugent.be/hpc),
7 # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
8 # Flemish Research Foundation (FWO) (http://www.fwo.be/en)
9 # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
10 #
11 # https://github.com/easybuilders/easybuild
12 #
13 # EasyBuild is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation v2.
16 #
17 # EasyBuild is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License
23 # along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
24 ##
25 """
26 Utility functions for implementating module naming schemes.
27 
28 Authors:
29 
30 * Stijn De Weirdt (Ghent University)
31 * Dries Verdegem (Ghent University)
32 * Kenneth Hoste (Ghent University)
33 * Pieter De Baets (Ghent University)
34 * Jens Timmerman (Ghent University)
35 * Fotis Georgatos (Uni.Lu, NTUA)
36 """
37 import os
38 import string
39 
40 from easybuild.base import fancylogger
41 from easybuild.tools.build_log import EasyBuildError
42 from easybuild.tools.module_naming_scheme.mns import ModuleNamingScheme
43 from easybuild.tools.py2vs3 import string_type
44 from easybuild.tools.toolchain.toolchain import SYSTEM_TOOLCHAIN_NAME, is_system_toolchain
45 from easybuild.tools.utilities import get_subclasses, import_available_modules
46 
47 _log = fancylogger.getLogger('module_naming_scheme.utilities', fname=False)
48 
49 
50 def det_full_ec_version(ec):
51     """
52     Determine exact install version, based on supplied easyconfig.
53     e.g. 1.2.3-goalf-1.1.0-no-OFED or 1.2.3 (for system toolchains)
54     """
55 
56     ecver = None
57     toolchain = ec.get('toolchain', {'name': SYSTEM_TOOLCHAIN_NAME})
58 
59     # determine main install version based on toolchain
60     if is_system_toolchain(toolchain['name']):
61         ecver = ec['version']
62     else:
63         ecver = "%s-%s-%s" % (ec['version'], toolchain['name'], toolchain['version'])
64 
65     # prepend/append version prefix/suffix
66     versionprefix = ec.get('versionprefix', '')
67     if not isinstance(versionprefix, string_type):
68         raise EasyBuildError("versionprefix value should be a string, found '%s': %s (full spec: %s)",
69                              type(versionprefix).__name__, versionprefix, ec)
70 
71     versionsuffix = ec.get('versionsuffix', '')
72     if not isinstance(versionsuffix, string_type):
73         raise EasyBuildError("versionsuffix value should be a string, found '%s': %s (full spec: %s)",
74                              type(versionsuffix).__name__, versionsuffix, ec)
75 
76     ecver = ''.join([x for x in [versionprefix, ecver, versionsuffix] if x])
77 
78     return ecver
79 
80 
81 def avail_module_naming_schemes():
82     """
83     Returns a list of available module naming schemes.
84     """
85     # all ModuleNamingScheme subclasses available in easybuild.tools.module_naming_scheme namespace are eligible
86     import_available_modules('easybuild.tools.module_naming_scheme')
87 
88     # construct name-to-class dict of available module naming scheme
89     avail_mnss = dict([(x.__name__, x) for x in get_subclasses(ModuleNamingScheme)])
90 
91     return avail_mnss
92 
93 
94 def is_valid_module_name(mod_name):
95     """Check whether the specified value is a valid module name."""
96     # module name must be a string
97     if not isinstance(mod_name, string_type):
98         _log.warning("Wrong type for module name %s (%s), should be a string" % (mod_name, type(mod_name)))
99         return False
100     # module name must be relative path
101     elif mod_name.startswith(os.path.sep):
102         _log.warning("Module name (%s) should be a relative file path" % mod_name)
103         return False
104     # module name should not be empty
105     elif not len(mod_name) > 0:
106         _log.warning("Module name (%s) should have length > 0." % mod_name)
107         return False
108     else:
109         # check whether module name only contains printable characters, since it's used as a filename
110         # (except for carriage-control characters \r, \x0b and \xoc)
111         invalid_chars = [x for x in mod_name if x not in string.printable or x in '\r\x0b\x0c']
112         if len(invalid_chars) > 0:
113             _log.warning("Module name %s contains invalid characters: %s" % (mod_name, invalid_chars))
114             return False
115     _log.debug("Module name %s validated" % mod_name)
116     return True
117 
118 
119 def det_hidden_modname(modname):
120     """Determine the hidden equivalent of the specified module name."""
121     moddir = os.path.dirname(modname)
122     modfile = os.path.basename(modname)
123     return os.path.join(moddir, '.%s' % modfile).lstrip(os.path.sep)
124
```
--- 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/easybuild/tools/module_naming_scheme/utilities.py b/easybuild/tools/module_naming_scheme/utilities.py
--- a/easybuild/tools/module_naming_scheme/utilities.py
+++ b/easybuild/tools/module_naming_scheme/utilities.py
@@ -64,16 +64,16 @@
 
     # prepend/append version prefix/suffix
     versionprefix = ec.get('versionprefix', '')
-    if not isinstance(versionprefix, string_type):
+    if versionprefix and not isinstance(versionprefix, string_type):
         raise EasyBuildError("versionprefix value should be a string, found '%s': %s (full spec: %s)",
                              type(versionprefix).__name__, versionprefix, ec)
 
     versionsuffix = ec.get('versionsuffix', '')
-    if not isinstance(versionsuffix, string_type):
+    if versionsuffix and not isinstance(versionsuffix, string_type):
         raise EasyBuildError("versionsuffix value should be a string, found '%s': %s (full spec: %s)",
                              type(versionsuffix).__name__, versionsuffix, ec)
 
-    ecver = ''.join([x for x in [versionprefix, ecver, versionsuffix] if x])
+    ecver = ''.join([x for x in [versionprefix or '', ecver, versionsuffix or ''] if x])
 
     return ecver

{"golden_diff": "diff --git a/easybuild/tools/module_naming_scheme/utilities.py b/easybuild/tools/module_naming_scheme/utilities.py\n--- a/easybuild/tools/module_naming_scheme/utilities.py\n+++ b/easybuild/tools/module_naming_scheme/utilities.py\n@@ -64,16 +64,16 @@\n \n     # prepend/append version prefix/suffix\n     versionprefix = ec.get('versionprefix', '')\n-    if not isinstance(versionprefix, string_type):\n+    if versionprefix and not isinstance(versionprefix, string_type):\n         raise EasyBuildError(\"versionprefix value should be a string, found '%s': %s (full spec: %s)\",\n                              type(versionprefix).__name__, versionprefix, ec)\n \n     versionsuffix = ec.get('versionsuffix', '')\n-    if not isinstance(versionsuffix, string_type):\n+    if versionsuffix and not isinstance(versionsuffix, string_type):\n         raise EasyBuildError(\"versionsuffix value should be a string, found '%s': %s (full spec: %s)\",\n                              type(versionsuffix).__name__, versionsuffix, ec)\n \n-    ecver = ''.join([x for x in [versionprefix, ecver, versionsuffix] if x])\n+    ecver = ''.join([x for x in [versionprefix or '', ecver, versionsuffix or ''] if x])\n \n     return ecver\n", "issue": "Regression with versionsuffix types\nCommit https://github.com/easybuilders/easybuild-framework/commit/0e5ba5c858\r\nintroduced a check for string-type for `versionsuffix`, while `None` used to be an accepted value for `versionsuffix`. Our hooks replace many version suffixes with `None`. \n", "before_files": [{"content": "##\n# Copyright 2009-2023 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n##\n\"\"\"\nUtility functions for implementating module naming schemes.\n\nAuthors:\n\n* Stijn De Weirdt (Ghent University)\n* Dries Verdegem (Ghent University)\n* Kenneth Hoste (Ghent University)\n* Pieter De Baets (Ghent University)\n* Jens Timmerman (Ghent University)\n* Fotis Georgatos (Uni.Lu, NTUA)\n\"\"\"\nimport os\nimport string\n\nfrom easybuild.base import fancylogger\nfrom easybuild.tools.build_log import EasyBuildError\nfrom easybuild.tools.module_naming_scheme.mns import ModuleNamingScheme\nfrom easybuild.tools.py2vs3 import string_type\nfrom easybuild.tools.toolchain.toolchain import SYSTEM_TOOLCHAIN_NAME, is_system_toolchain\nfrom easybuild.tools.utilities import get_subclasses, import_available_modules\n\n_log = fancylogger.getLogger('module_naming_scheme.utilities', fname=False)\n\n\ndef det_full_ec_version(ec):\n    \"\"\"\n    Determine exact install version, based on supplied easyconfig.\n    e.g. 1.2.3-goalf-1.1.0-no-OFED or 1.2.3 (for system toolchains)\n    \"\"\"\n\n    ecver = None\n    toolchain = ec.get('toolchain', {'name': SYSTEM_TOOLCHAIN_NAME})\n\n    # determine main install version based on toolchain\n    if is_system_toolchain(toolchain['name']):\n        ecver = ec['version']\n    else:\n        ecver = \"%s-%s-%s\" % (ec['version'], toolchain['name'], toolchain['version'])\n\n    # prepend/append version prefix/suffix\n    versionprefix = ec.get('versionprefix', '')\n    if not isinstance(versionprefix, string_type):\n        raise EasyBuildError(\"versionprefix value should be a string, found '%s': %s (full spec: %s)\",\n                             type(versionprefix).__name__, versionprefix, ec)\n\n    versionsuffix = ec.get('versionsuffix', '')\n    if not isinstance(versionsuffix, string_type):\n        raise EasyBuildError(\"versionsuffix value should be a string, found '%s': %s (full spec: %s)\",\n                             type(versionsuffix).__name__, versionsuffix, ec)\n\n    ecver = ''.join([x for x in [versionprefix, ecver, versionsuffix] if x])\n\n    return ecver\n\n\ndef avail_module_naming_schemes():\n    \"\"\"\n    Returns a list of available module naming schemes.\n    \"\"\"\n    # all ModuleNamingScheme subclasses available in easybuild.tools.module_naming_scheme namespace are eligible\n    import_available_modules('easybuild.tools.module_naming_scheme')\n\n    # construct name-to-class dict of available module naming scheme\n    avail_mnss = dict([(x.__name__, x) for x in get_subclasses(ModuleNamingScheme)])\n\n    return avail_mnss\n\n\ndef is_valid_module_name(mod_name):\n    \"\"\"Check whether the specified value is a valid module name.\"\"\"\n    # module name must be a string\n    if not isinstance(mod_name, string_type):\n        _log.warning(\"Wrong type for module name %s (%s), should be a string\" % (mod_name, type(mod_name)))\n        return False\n    # module name must be relative path\n    elif mod_name.startswith(os.path.sep):\n        _log.warning(\"Module name (%s) should be a relative file path\" % mod_name)\n        return False\n    # module name should not be empty\n    elif not len(mod_name) > 0:\n        _log.warning(\"Module name (%s) should have length > 0.\" % mod_name)\n        return False\n    else:\n        # check whether module name only contains printable characters, since it's used as a filename\n        # (except for carriage-control characters \\r, \\x0b and \\xoc)\n        invalid_chars = [x for x in mod_name if x not in string.printable or x in '\\r\\x0b\\x0c']\n        if len(invalid_chars) > 0:\n            _log.warning(\"Module name %s contains invalid characters: %s\" % (mod_name, invalid_chars))\n            return False\n    _log.debug(\"Module name %s validated\" % mod_name)\n    return True\n\n\ndef det_hidden_modname(modname):\n    \"\"\"Determine the hidden equivalent of the specified module name.\"\"\"\n    moddir = os.path.dirname(modname)\n    modfile = os.path.basename(modname)\n    return os.path.join(moddir, '.%s' % modfile).lstrip(os.path.sep)\n", "path": "easybuild/tools/module_naming_scheme/utilities.py"}], "after_files": [{"content": "##\n# Copyright 2009-2023 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n##\n\"\"\"\nUtility functions for implementating module naming schemes.\n\nAuthors:\n\n* Stijn De Weirdt (Ghent University)\n* Dries Verdegem (Ghent University)\n* Kenneth Hoste (Ghent University)\n* Pieter De Baets (Ghent University)\n* Jens Timmerman (Ghent University)\n* Fotis Georgatos (Uni.Lu, NTUA)\n\"\"\"\nimport os\nimport string\n\nfrom easybuild.base import fancylogger\nfrom easybuild.tools.build_log import EasyBuildError\nfrom easybuild.tools.module_naming_scheme.mns import ModuleNamingScheme\nfrom easybuild.tools.py2vs3 import string_type\nfrom easybuild.tools.toolchain.toolchain import SYSTEM_TOOLCHAIN_NAME, is_system_toolchain\nfrom easybuild.tools.utilities import get_subclasses, import_available_modules\n\n_log = fancylogger.getLogger('module_naming_scheme.utilities', fname=False)\n\n\ndef det_full_ec_version(ec):\n    \"\"\"\n    Determine exact install version, based on supplied easyconfig.\n    e.g. 1.2.3-goalf-1.1.0-no-OFED or 1.2.3 (for system toolchains)\n    \"\"\"\n\n    ecver = None\n    toolchain = ec.get('toolchain', {'name': SYSTEM_TOOLCHAIN_NAME})\n\n    # determine main install version based on toolchain\n    if is_system_toolchain(toolchain['name']):\n        ecver = ec['version']\n    else:\n        ecver = \"%s-%s-%s\" % (ec['version'], toolchain['name'], toolchain['version'])\n\n    # prepend/append version prefix/suffix\n    versionprefix = ec.get('versionprefix', '')\n    if versionprefix and not isinstance(versionprefix, string_type):\n        raise EasyBuildError(\"versionprefix value should be a string, found '%s': %s (full spec: %s)\",\n                             type(versionprefix).__name__, versionprefix, ec)\n\n    versionsuffix = ec.get('versionsuffix', '')\n    if versionsuffix and not isinstance(versionsuffix, string_type):\n        raise EasyBuildError(\"versionsuffix value should be a string, found '%s': %s (full spec: %s)\",\n                             type(versionsuffix).__name__, versionsuffix, ec)\n\n    ecver = ''.join([x for x in [versionprefix or '', ecver, versionsuffix or ''] if x])\n\n    return ecver\n\n\ndef avail_module_naming_schemes():\n    \"\"\"\n    Returns a list of available module naming schemes.\n    \"\"\"\n    # all ModuleNamingScheme subclasses available in easybuild.tools.module_naming_scheme namespace are eligible\n    import_available_modules('easybuild.tools.module_naming_scheme')\n\n    # construct name-to-class dict of available module naming scheme\n    avail_mnss = dict([(x.__name__, x) for x in get_subclasses(ModuleNamingScheme)])\n\n    return avail_mnss\n\n\ndef is_valid_module_name(mod_name):\n    \"\"\"Check whether the specified value is a valid module name.\"\"\"\n    # module name must be a string\n    if not isinstance(mod_name, string_type):\n        _log.warning(\"Wrong type for module name %s (%s), should be a string\" % (mod_name, type(mod_name)))\n        return False\n    # module name must be relative path\n    elif mod_name.startswith(os.path.sep):\n        _log.warning(\"Module name (%s) should be a relative file path\" % mod_name)\n        return False\n    # module name should not be empty\n    elif not len(mod_name) > 0:\n        _log.warning(\"Module name (%s) should have length > 0.\" % mod_name)\n        return False\n    else:\n        # check whether module name only contains printable characters, since it's used as a filename\n        # (except for carriage-control characters \\r, \\x0b and \\xoc)\n        invalid_chars = [x for x in mod_name if x not in string.printable or x in '\\r\\x0b\\x0c']\n        if len(invalid_chars) > 0:\n            _log.warning(\"Module name %s contains invalid characters: %s\" % (mod_name, invalid_chars))\n            return False\n    _log.debug(\"Module name %s validated\" % mod_name)\n    return True\n\n\ndef det_hidden_modname(modname):\n    \"\"\"Determine the hidden equivalent of the specified module name.\"\"\"\n    moddir = os.path.dirname(modname)\n    modfile = os.path.basename(modname)\n    return os.path.join(moddir, '.%s' % modfile).lstrip(os.path.sep)\n", "path": "easybuild/tools/module_naming_scheme/utilities.py"}]}