We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
setuptools changes underscore to dash for package name
After I pip install cx_oracle, I use python -m pip show cx_oracle command and it shows the package name is cx-Oracle
After discussed with cx_Oracle's author, it shows setuptools changed the underscore to dash for the package name.  Is that an issue for setuptools or is there any way to stop this auto-conversion? Thanks.

setup.cfg for cx_Oracle
[metadata]
name = cx_Oracle

PKG-INFO for cx_Oracle
Metadata-Version: 2.1
Name: cx-Oracle

setup.py used in cx_Oracel
# setup the extension
extension = setuptools.Extension(
        name = "cx_Oracle",
        include_dirs = includeDirs,
        extra_compile_args = extraCompileArgs,
        define_macros = [("CXO_BUILD_VERSION", BUILD_VERSION)],
        extra_link_args = extraLinkArgs,
        sources = sources + dpiSources,
        depends = depends,
        libraries = libraries,
        library_dirs = libraryDirs)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `setuptools/_normalization.py`
Content:
```
1 """
2 Helpers for normalization as expected in wheel/sdist/module file names
3 and core metadata
4 """
5 import re
6 from pathlib import Path
7 from typing import Union
8 
9 from .extern import packaging
10 
11 _Path = Union[str, Path]
12 
13 # https://packaging.python.org/en/latest/specifications/core-metadata/#name
14 _VALID_NAME = re.compile(r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.I)
15 _UNSAFE_NAME_CHARS = re.compile(r"[^A-Z0-9.]+", re.I)
16 _NON_ALPHANUMERIC = re.compile(r"[^A-Z0-9]+", re.I)
17 _PEP440_FALLBACK = re.compile(r"^v?(?P<safe>(?:[0-9]+!)?[0-9]+(?:\.[0-9]+)*)", re.I)
18 
19 
20 def safe_identifier(name: str) -> str:
21     """Make a string safe to be used as Python identifier.
22     >>> safe_identifier("12abc")
23     '_12abc'
24     >>> safe_identifier("__editable__.myns.pkg-78.9.3_local")
25     '__editable___myns_pkg_78_9_3_local'
26     """
27     safe = re.sub(r'\W|^(?=\d)', '_', name)
28     assert safe.isidentifier()
29     return safe
30 
31 
32 def safe_name(component: str) -> str:
33     """Escape a component used as a project name according to Core Metadata.
34     >>> safe_name("hello world")
35     'hello-world'
36     >>> safe_name("hello?world")
37     'hello-world'
38     """
39     # See pkg_resources.safe_name
40     return _UNSAFE_NAME_CHARS.sub("-", component)
41 
42 
43 def safe_version(version: str) -> str:
44     """Convert an arbitrary string into a valid version string.
45     Can still raise an ``InvalidVersion`` exception.
46     To avoid exceptions use ``best_effort_version``.
47     >>> safe_version("1988 12 25")
48     '1988.12.25'
49     >>> safe_version("v0.2.1")
50     '0.2.1'
51     >>> safe_version("v0.2?beta")
52     '0.2b0'
53     >>> safe_version("v0.2 beta")
54     '0.2b0'
55     >>> safe_version("ubuntu lts")
56     Traceback (most recent call last):
57     ...
58     setuptools.extern.packaging.version.InvalidVersion: Invalid version: 'ubuntu.lts'
59     """
60     v = version.replace(' ', '.')
61     try:
62         return str(packaging.version.Version(v))
63     except packaging.version.InvalidVersion:
64         attempt = _UNSAFE_NAME_CHARS.sub("-", v)
65         return str(packaging.version.Version(attempt))
66 
67 
68 def best_effort_version(version: str) -> str:
69     """Convert an arbitrary string into a version-like string.
70     Fallback when ``safe_version`` is not safe enough.
71     >>> best_effort_version("v0.2 beta")
72     '0.2b0'
73     >>> best_effort_version("ubuntu lts")
74     '0.dev0+sanitized.ubuntu.lts'
75     >>> best_effort_version("0.23ubuntu1")
76     '0.23.dev0+sanitized.ubuntu1'
77     >>> best_effort_version("0.23-")
78     '0.23.dev0+sanitized'
79     >>> best_effort_version("0.-_")
80     '0.dev0+sanitized'
81     >>> best_effort_version("42.+?1")
82     '42.dev0+sanitized.1'
83     """
84     # See pkg_resources._forgiving_version
85     try:
86         return safe_version(version)
87     except packaging.version.InvalidVersion:
88         v = version.replace(' ', '.')
89         match = _PEP440_FALLBACK.search(v)
90         if match:
91             safe = match["safe"]
92             rest = v[len(safe) :]
93         else:
94             safe = "0"
95             rest = version
96         safe_rest = _NON_ALPHANUMERIC.sub(".", rest).strip(".")
97         local = f"sanitized.{safe_rest}".strip(".")
98         return safe_version(f"{safe}.dev0+{local}")
99 
100 
101 def safe_extra(extra: str) -> str:
102     """Normalize extra name according to PEP 685
103     >>> safe_extra("_FrIeNdLy-._.-bArD")
104     'friendly-bard'
105     >>> safe_extra("FrIeNdLy-._.-bArD__._-")
106     'friendly-bard'
107     """
108     return _NON_ALPHANUMERIC.sub("-", extra).strip("-").lower()
109 
110 
111 def filename_component(value: str) -> str:
112     """Normalize each component of a filename (e.g. distribution/version part of wheel)
113     Note: ``value`` needs to be already normalized.
114     >>> filename_component("my-pkg")
115     'my_pkg'
116     """
117     return value.replace("-", "_").strip("_")
118 
119 
120 def safer_name(value: str) -> str:
121     """Like ``safe_name`` but can be used as filename component for wheel"""
122     # See bdist_wheel.safer_name
123     return filename_component(safe_name(value))
124 
125 
126 def safer_best_effort_version(value: str) -> str:
127     """Like ``best_effort_version`` but can be used as filename component for wheel"""
128     # See bdist_wheel.safer_verion
129     # TODO: Replace with only safe_version in the future (no need for best effort)
130     return filename_component(best_effort_version(value))
131
```
--- 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/setuptools/_normalization.py b/setuptools/_normalization.py
--- a/setuptools/_normalization.py
+++ b/setuptools/_normalization.py
@@ -12,7 +12,7 @@
 
 # https://packaging.python.org/en/latest/specifications/core-metadata/#name
 _VALID_NAME = re.compile(r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.I)
-_UNSAFE_NAME_CHARS = re.compile(r"[^A-Z0-9.]+", re.I)
+_UNSAFE_NAME_CHARS = re.compile(r"[^A-Z0-9._-]+", re.I)
 _NON_ALPHANUMERIC = re.compile(r"[^A-Z0-9]+", re.I)
 _PEP440_FALLBACK = re.compile(r"^v?(?P<safe>(?:[0-9]+!)?[0-9]+(?:\.[0-9]+)*)", re.I)
 
@@ -35,6 +35,8 @@
     'hello-world'
     >>> safe_name("hello?world")
     'hello-world'
+    >>> safe_name("hello_world")
+    'hello_world'
     """
     # See pkg_resources.safe_name
     return _UNSAFE_NAME_CHARS.sub("-", component)

{"golden_diff": "diff --git a/setuptools/_normalization.py b/setuptools/_normalization.py\n--- a/setuptools/_normalization.py\n+++ b/setuptools/_normalization.py\n@@ -12,7 +12,7 @@\n \n # https://packaging.python.org/en/latest/specifications/core-metadata/#name\n _VALID_NAME = re.compile(r\"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$\", re.I)\n-_UNSAFE_NAME_CHARS = re.compile(r\"[^A-Z0-9.]+\", re.I)\n+_UNSAFE_NAME_CHARS = re.compile(r\"[^A-Z0-9._-]+\", re.I)\n _NON_ALPHANUMERIC = re.compile(r\"[^A-Z0-9]+\", re.I)\n _PEP440_FALLBACK = re.compile(r\"^v?(?P<safe>(?:[0-9]+!)?[0-9]+(?:\\.[0-9]+)*)\", re.I)\n \n@@ -35,6 +35,8 @@\n     'hello-world'\n     >>> safe_name(\"hello?world\")\n     'hello-world'\n+    >>> safe_name(\"hello_world\")\n+    'hello_world'\n     \"\"\"\n     # See pkg_resources.safe_name\n     return _UNSAFE_NAME_CHARS.sub(\"-\", component)\n", "issue": "setuptools changes underscore to dash for package name\nAfter I pip install cx_oracle, I use python -m pip show cx_oracle command and it shows the package name is cx-Oracle\r\nAfter discussed with cx_Oracle's author, it shows setuptools changed the underscore to dash for the package name.  Is that an issue for setuptools or is there any way to stop this auto-conversion? Thanks.\r\n\r\nsetup.cfg for cx_Oracle\r\n[metadata]\r\nname = cx_Oracle\r\n\r\nPKG-INFO for cx_Oracle\r\nMetadata-Version: 2.1\r\nName: cx-Oracle\r\n\r\nsetup.py used in cx_Oracel\r\n# setup the extension\r\nextension = setuptools.Extension(\r\n        name = \"cx_Oracle\",\r\n        include_dirs = includeDirs,\r\n        extra_compile_args = extraCompileArgs,\r\n        define_macros = [(\"CXO_BUILD_VERSION\", BUILD_VERSION)],\r\n        extra_link_args = extraLinkArgs,\r\n        sources = sources + dpiSources,\r\n        depends = depends,\r\n        libraries = libraries,\r\n        library_dirs = libraryDirs)\n", "before_files": [{"content": "\"\"\"\nHelpers for normalization as expected in wheel/sdist/module file names\nand core metadata\n\"\"\"\nimport re\nfrom pathlib import Path\nfrom typing import Union\n\nfrom .extern import packaging\n\n_Path = Union[str, Path]\n\n# https://packaging.python.org/en/latest/specifications/core-metadata/#name\n_VALID_NAME = re.compile(r\"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$\", re.I)\n_UNSAFE_NAME_CHARS = re.compile(r\"[^A-Z0-9.]+\", re.I)\n_NON_ALPHANUMERIC = re.compile(r\"[^A-Z0-9]+\", re.I)\n_PEP440_FALLBACK = re.compile(r\"^v?(?P<safe>(?:[0-9]+!)?[0-9]+(?:\\.[0-9]+)*)\", re.I)\n\n\ndef safe_identifier(name: str) -> str:\n    \"\"\"Make a string safe to be used as Python identifier.\n    >>> safe_identifier(\"12abc\")\n    '_12abc'\n    >>> safe_identifier(\"__editable__.myns.pkg-78.9.3_local\")\n    '__editable___myns_pkg_78_9_3_local'\n    \"\"\"\n    safe = re.sub(r'\\W|^(?=\\d)', '_', name)\n    assert safe.isidentifier()\n    return safe\n\n\ndef safe_name(component: str) -> str:\n    \"\"\"Escape a component used as a project name according to Core Metadata.\n    >>> safe_name(\"hello world\")\n    'hello-world'\n    >>> safe_name(\"hello?world\")\n    'hello-world'\n    \"\"\"\n    # See pkg_resources.safe_name\n    return _UNSAFE_NAME_CHARS.sub(\"-\", component)\n\n\ndef safe_version(version: str) -> str:\n    \"\"\"Convert an arbitrary string into a valid version string.\n    Can still raise an ``InvalidVersion`` exception.\n    To avoid exceptions use ``best_effort_version``.\n    >>> safe_version(\"1988 12 25\")\n    '1988.12.25'\n    >>> safe_version(\"v0.2.1\")\n    '0.2.1'\n    >>> safe_version(\"v0.2?beta\")\n    '0.2b0'\n    >>> safe_version(\"v0.2 beta\")\n    '0.2b0'\n    >>> safe_version(\"ubuntu lts\")\n    Traceback (most recent call last):\n    ...\n    setuptools.extern.packaging.version.InvalidVersion: Invalid version: 'ubuntu.lts'\n    \"\"\"\n    v = version.replace(' ', '.')\n    try:\n        return str(packaging.version.Version(v))\n    except packaging.version.InvalidVersion:\n        attempt = _UNSAFE_NAME_CHARS.sub(\"-\", v)\n        return str(packaging.version.Version(attempt))\n\n\ndef best_effort_version(version: str) -> str:\n    \"\"\"Convert an arbitrary string into a version-like string.\n    Fallback when ``safe_version`` is not safe enough.\n    >>> best_effort_version(\"v0.2 beta\")\n    '0.2b0'\n    >>> best_effort_version(\"ubuntu lts\")\n    '0.dev0+sanitized.ubuntu.lts'\n    >>> best_effort_version(\"0.23ubuntu1\")\n    '0.23.dev0+sanitized.ubuntu1'\n    >>> best_effort_version(\"0.23-\")\n    '0.23.dev0+sanitized'\n    >>> best_effort_version(\"0.-_\")\n    '0.dev0+sanitized'\n    >>> best_effort_version(\"42.+?1\")\n    '42.dev0+sanitized.1'\n    \"\"\"\n    # See pkg_resources._forgiving_version\n    try:\n        return safe_version(version)\n    except packaging.version.InvalidVersion:\n        v = version.replace(' ', '.')\n        match = _PEP440_FALLBACK.search(v)\n        if match:\n            safe = match[\"safe\"]\n            rest = v[len(safe) :]\n        else:\n            safe = \"0\"\n            rest = version\n        safe_rest = _NON_ALPHANUMERIC.sub(\".\", rest).strip(\".\")\n        local = f\"sanitized.{safe_rest}\".strip(\".\")\n        return safe_version(f\"{safe}.dev0+{local}\")\n\n\ndef safe_extra(extra: str) -> str:\n    \"\"\"Normalize extra name according to PEP 685\n    >>> safe_extra(\"_FrIeNdLy-._.-bArD\")\n    'friendly-bard'\n    >>> safe_extra(\"FrIeNdLy-._.-bArD__._-\")\n    'friendly-bard'\n    \"\"\"\n    return _NON_ALPHANUMERIC.sub(\"-\", extra).strip(\"-\").lower()\n\n\ndef filename_component(value: str) -> str:\n    \"\"\"Normalize each component of a filename (e.g. distribution/version part of wheel)\n    Note: ``value`` needs to be already normalized.\n    >>> filename_component(\"my-pkg\")\n    'my_pkg'\n    \"\"\"\n    return value.replace(\"-\", \"_\").strip(\"_\")\n\n\ndef safer_name(value: str) -> str:\n    \"\"\"Like ``safe_name`` but can be used as filename component for wheel\"\"\"\n    # See bdist_wheel.safer_name\n    return filename_component(safe_name(value))\n\n\ndef safer_best_effort_version(value: str) -> str:\n    \"\"\"Like ``best_effort_version`` but can be used as filename component for wheel\"\"\"\n    # See bdist_wheel.safer_verion\n    # TODO: Replace with only safe_version in the future (no need for best effort)\n    return filename_component(best_effort_version(value))\n", "path": "setuptools/_normalization.py"}], "after_files": [{"content": "\"\"\"\nHelpers for normalization as expected in wheel/sdist/module file names\nand core metadata\n\"\"\"\nimport re\nfrom pathlib import Path\nfrom typing import Union\n\nfrom .extern import packaging\n\n_Path = Union[str, Path]\n\n# https://packaging.python.org/en/latest/specifications/core-metadata/#name\n_VALID_NAME = re.compile(r\"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$\", re.I)\n_UNSAFE_NAME_CHARS = re.compile(r\"[^A-Z0-9._-]+\", re.I)\n_NON_ALPHANUMERIC = re.compile(r\"[^A-Z0-9]+\", re.I)\n_PEP440_FALLBACK = re.compile(r\"^v?(?P<safe>(?:[0-9]+!)?[0-9]+(?:\\.[0-9]+)*)\", re.I)\n\n\ndef safe_identifier(name: str) -> str:\n    \"\"\"Make a string safe to be used as Python identifier.\n    >>> safe_identifier(\"12abc\")\n    '_12abc'\n    >>> safe_identifier(\"__editable__.myns.pkg-78.9.3_local\")\n    '__editable___myns_pkg_78_9_3_local'\n    \"\"\"\n    safe = re.sub(r'\\W|^(?=\\d)', '_', name)\n    assert safe.isidentifier()\n    return safe\n\n\ndef safe_name(component: str) -> str:\n    \"\"\"Escape a component used as a project name according to Core Metadata.\n    >>> safe_name(\"hello world\")\n    'hello-world'\n    >>> safe_name(\"hello?world\")\n    'hello-world'\n    >>> safe_name(\"hello_world\")\n    'hello_world'\n    \"\"\"\n    # See pkg_resources.safe_name\n    return _UNSAFE_NAME_CHARS.sub(\"-\", component)\n\n\ndef safe_version(version: str) -> str:\n    \"\"\"Convert an arbitrary string into a valid version string.\n    Can still raise an ``InvalidVersion`` exception.\n    To avoid exceptions use ``best_effort_version``.\n    >>> safe_version(\"1988 12 25\")\n    '1988.12.25'\n    >>> safe_version(\"v0.2.1\")\n    '0.2.1'\n    >>> safe_version(\"v0.2?beta\")\n    '0.2b0'\n    >>> safe_version(\"v0.2 beta\")\n    '0.2b0'\n    >>> safe_version(\"ubuntu lts\")\n    Traceback (most recent call last):\n    ...\n    setuptools.extern.packaging.version.InvalidVersion: Invalid version: 'ubuntu.lts'\n    \"\"\"\n    v = version.replace(' ', '.')\n    try:\n        return str(packaging.version.Version(v))\n    except packaging.version.InvalidVersion:\n        attempt = _UNSAFE_NAME_CHARS.sub(\"-\", v)\n        return str(packaging.version.Version(attempt))\n\n\ndef best_effort_version(version: str) -> str:\n    \"\"\"Convert an arbitrary string into a version-like string.\n    Fallback when ``safe_version`` is not safe enough.\n    >>> best_effort_version(\"v0.2 beta\")\n    '0.2b0'\n    >>> best_effort_version(\"ubuntu lts\")\n    '0.dev0+sanitized.ubuntu.lts'\n    >>> best_effort_version(\"0.23ubuntu1\")\n    '0.23.dev0+sanitized.ubuntu1'\n    >>> best_effort_version(\"0.23-\")\n    '0.23.dev0+sanitized'\n    >>> best_effort_version(\"0.-_\")\n    '0.dev0+sanitized'\n    >>> best_effort_version(\"42.+?1\")\n    '42.dev0+sanitized.1'\n    \"\"\"\n    # See pkg_resources._forgiving_version\n    try:\n        return safe_version(version)\n    except packaging.version.InvalidVersion:\n        v = version.replace(' ', '.')\n        match = _PEP440_FALLBACK.search(v)\n        if match:\n            safe = match[\"safe\"]\n            rest = v[len(safe) :]\n        else:\n            safe = \"0\"\n            rest = version\n        safe_rest = _NON_ALPHANUMERIC.sub(\".\", rest).strip(\".\")\n        local = f\"sanitized.{safe_rest}\".strip(\".\")\n        return safe_version(f\"{safe}.dev0+{local}\")\n\n\ndef safe_extra(extra: str) -> str:\n    \"\"\"Normalize extra name according to PEP 685\n    >>> safe_extra(\"_FrIeNdLy-._.-bArD\")\n    'friendly-bard'\n    >>> safe_extra(\"FrIeNdLy-._.-bArD__._-\")\n    'friendly-bard'\n    \"\"\"\n    return _NON_ALPHANUMERIC.sub(\"-\", extra).strip(\"-\").lower()\n\n\ndef filename_component(value: str) -> str:\n    \"\"\"Normalize each component of a filename (e.g. distribution/version part of wheel)\n    Note: ``value`` needs to be already normalized.\n    >>> filename_component(\"my-pkg\")\n    'my_pkg'\n    \"\"\"\n    return value.replace(\"-\", \"_\").strip(\"_\")\n\n\ndef safer_name(value: str) -> str:\n    \"\"\"Like ``safe_name`` but can be used as filename component for wheel\"\"\"\n    # See bdist_wheel.safer_name\n    return filename_component(safe_name(value))\n\n\ndef safer_best_effort_version(value: str) -> str:\n    \"\"\"Like ``best_effort_version`` but can be used as filename component for wheel\"\"\"\n    # See bdist_wheel.safer_verion\n    # TODO: Replace with only safe_version in the future (no need for best effort)\n    return filename_component(best_effort_version(value))\n", "path": "setuptools/_normalization.py"}]}