prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  [BUG] + in version string breaks fingerprint system
  **Describe your context**
  -  replace the result of `pip list | grep dash` below
  ```
  dash                                  1.5.1                           
  dash-core-components                  1.4.0                           
  dash-daq                              0.2.2                           
  dash-html-components                  1.0.1                           
  dash-renderer                         1.2.0                           
  dash-table                            4.5.0  
  ```
  
  **Describe the bug**
  
  When going from `dash==1.4` to `dash==1.5`, we experienced a breaking change in the custom Dash components we use.
  
  It took some hours to debug, but the reason was found to be related to the new "fingerprint" system in Dash. In our project, we use the [setuptools_scm](https://github.com/pypa/setuptools_scm) package (by the Python Packaging Authority) in order to have a versioning system that automatically is linked to the git repo tags. This makes continuous deployment to e.g. Pypi easy and robust wrt. keeping versions consistent.
  
  I.e. instead of
  ```python
  __version__ = package['version']
  ```
  in the component package, we use something like
  ```
  __version__ = get_distribution(__name__).version
  ```
  This worked until `dash==1.5`, then it broke on non-release-versions due to automatic tags of the type
  `1.0.0.dev5+af4304c.d20191103`, where the tag includes a `+`. See [the default tag formats](https://github.com/pypa/setuptools_scm#default-versioning-scheme).
  
  Changing the line above to
  ```
  __version__ = get_distribution(__name__).version.replace("+", ".")
  ```
  is one workaround that gets the third party components to also work on `dash==1.5`
  
  **Expected behavior**
  
  `setuptools_scm` provided versions to work also in `dash>=1.5`.
  
  **Suggested solution**
  
  Change [this line](https://github.com/plotly/dash/blob/40b5357f262ac207f94ac980e6cb928d94df65b7/dash/fingerprint.py#L12) in Dash's `build_fingerprint` to also replace `+` with `_`?
  
  </issue>
  <code>
  [start of dash/fingerprint.py]
  1 import re
  2 
  3 cache_regex = re.compile(r"^v[\w-]+m[0-9a-fA-F]+$")
  4 
  5 
  6 def build_fingerprint(path, version, hash_value):
  7     path_parts = path.split("/")
  8     filename, extension = path_parts[-1].split(".", 1)
  9 
  10     return "{}.v{}m{}.{}".format(
  11         "/".join(path_parts[:-1] + [filename]),
  12         str(version).replace(".", "_"),
  13         hash_value,
  14         extension,
  15     )
  16 
  17 
  18 def check_fingerprint(path):
  19     path_parts = path.split("/")
  20     name_parts = path_parts[-1].split(".")
  21 
  22     # Check if the resource has a fingerprint
  23     if len(name_parts) > 2 and cache_regex.match(name_parts[1]):
  24         original_name = ".".join([name_parts[0]] + name_parts[2:])
  25         return "/".join(path_parts[:-1] + [original_name]), True
  26 
  27     return path, False
  28
  [end of dash/fingerprint.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/dash/fingerprint.py b/dash/fingerprint.py
  --- a/dash/fingerprint.py
  +++ b/dash/fingerprint.py
  @@ -1,7 +1,7 @@
   import re
   
   cache_regex = re.compile(r"^v[\w-]+m[0-9a-fA-F]+$")
  -
  +version_clean = re.compile(r"[^\w-]")
   
   def build_fingerprint(path, version, hash_value):
       path_parts = path.split("/")
  @@ -9,7 +9,7 @@
   
       return "{}.v{}m{}.{}".format(
           "/".join(path_parts[:-1] + [filename]),
  -        str(version).replace(".", "_"),
  +        re.sub(version_clean, "_", str(version)),
           hash_value,
           extension,
       )
  
verification_info: {"golden_diff": "diff --git a/dash/fingerprint.py b/dash/fingerprint.py\n--- a/dash/fingerprint.py\n+++ b/dash/fingerprint.py\n@@ -1,7 +1,7 @@\n import re\n \n cache_regex = re.compile(r\"^v[\\w-]+m[0-9a-fA-F]+$\")\n-\n+version_clean = re.compile(r\"[^\\w-]\")\n \n def build_fingerprint(path, version, hash_value):\n     path_parts = path.split(\"/\")\n@@ -9,7 +9,7 @@\n \n     return \"{}.v{}m{}.{}\".format(\n         \"/\".join(path_parts[:-1] + [filename]),\n-        str(version).replace(\".\", \"_\"),\n+        re.sub(version_clean, \"_\", str(version)),\n         hash_value,\n         extension,\n     )\n", "issue": "[BUG] + in version string breaks fingerprint system\n**Describe your context**\r\n-  replace the result of `pip list | grep dash` below\r\n```\r\ndash                                  1.5.1                           \r\ndash-core-components                  1.4.0                           \r\ndash-daq                              0.2.2                           \r\ndash-html-components                  1.0.1                           \r\ndash-renderer                         1.2.0                           \r\ndash-table                            4.5.0  \r\n```\r\n\r\n**Describe the bug**\r\n\r\nWhen going from `dash==1.4` to `dash==1.5`, we experienced a breaking change in the custom Dash components we use.\r\n\r\nIt took some hours to debug, but the reason was found to be related to the new \"fingerprint\" system in Dash. In our project, we use the [setuptools_scm](https://github.com/pypa/setuptools_scm) package (by the Python Packaging Authority) in order to have a versioning system that automatically is linked to the git repo tags. This makes continuous deployment to e.g. Pypi easy and robust wrt. keeping versions consistent.\r\n\r\nI.e. instead of\r\n```python\r\n__version__ = package['version']\r\n```\r\nin the component package, we use something like\r\n```\r\n__version__ = get_distribution(__name__).version\r\n```\r\nThis worked until `dash==1.5`, then it broke on non-release-versions due to automatic tags of the type\r\n`1.0.0.dev5+af4304c.d20191103`, where the tag includes a `+`. See [the default tag formats](https://github.com/pypa/setuptools_scm#default-versioning-scheme).\r\n\r\nChanging the line above to\r\n```\r\n__version__ = get_distribution(__name__).version.replace(\"+\", \".\")\r\n```\r\nis one workaround that gets the third party components to also work on `dash==1.5`\r\n\r\n**Expected behavior**\r\n\r\n`setuptools_scm` provided versions to work also in `dash>=1.5`.\r\n\r\n**Suggested solution**\r\n\r\nChange [this line](https://github.com/plotly/dash/blob/40b5357f262ac207f94ac980e6cb928d94df65b7/dash/fingerprint.py#L12) in Dash's `build_fingerprint` to also replace `+` with `_`?\n", "before_files": [{"content": "import re\n\ncache_regex = re.compile(r\"^v[\\w-]+m[0-9a-fA-F]+$\")\n\n\ndef build_fingerprint(path, version, hash_value):\n    path_parts = path.split(\"/\")\n    filename, extension = path_parts[-1].split(\".\", 1)\n\n    return \"{}.v{}m{}.{}\".format(\n        \"/\".join(path_parts[:-1] + [filename]),\n        str(version).replace(\".\", \"_\"),\n        hash_value,\n        extension,\n    )\n\n\ndef check_fingerprint(path):\n    path_parts = path.split(\"/\")\n    name_parts = path_parts[-1].split(\".\")\n\n    # Check if the resource has a fingerprint\n    if len(name_parts) > 2 and cache_regex.match(name_parts[1]):\n        original_name = \".\".join([name_parts[0]] + name_parts[2:])\n        return \"/\".join(path_parts[:-1] + [original_name]), True\n\n    return path, False\n", "path": "dash/fingerprint.py"}]}