Repository: pypa/setuptools_scm

Issue:
weird version_tuple when hardcoding version_scheme
I would like to use setuptools_scm to append a git sha if applicable, and in any case use a hard-coded version number as base (instead of a Git tag). To this end, I use the `"version_scheme"`:
```python
      use_scm_version={
          "version_scheme": lambda _: "4.1.0",
          "write_to": "foobar/version.py"
      }
```
The command
```
python3 setup.py --version
```
correctly produces
```
4.1.0+g4ac9d2c
```
but the `version_tuple` in `version.py` is weird:
```python
version = '4.1.0+g4ac9d2c'
version_tuple = (4, 1, '0+g4ac9d2c')
```
I would have expected
```python
version_tuple = (4, 1, 0, 'g4ac9d2c')
# or perhaps
version_tuple = (4, 1, 0, '+g4ac9d2c')
```
What's going wrong here?

Discussion:

Patch:
diff --git a/src/setuptools_scm/__init__.py b/src/setuptools_scm/__init__.py
index bc5797d..97061f2 100644
--- a/src/setuptools_scm/__init__.py
+++ b/src/setuptools_scm/__init__.py
@@ -5,6 +5,11 @@
 import os
 import warnings
 
+try:
+    from packaging.version import parse
+except ImportError:
+    from pkg_resources import parse_version as parse
+
 from .config import (
     Configuration,
     DEFAULT_VERSION_SCHEME,
@@ -83,15 +88,12 @@ def dump_version(root, version, write_to, template=None):
             )
         )
 
-    # version_tuple: each field is converted to an int if possible or kept as string
-    fields = tuple(version.split("."))
-    version_fields = []
-    for field in fields:
-        try:
-            v = int(field)
-        except ValueError:
-            v = field
-        version_fields.append(v)
+    parsed_version = parse(version)
+    version_fields = parsed_version.release
+    if parsed_version.dev is not None:
+        version_fields += (f"dev{parsed_version.dev}",)
+    if parsed_version.local is not None:
+        version_fields += (parsed_version.local,)
 
     with open(target, "w") as fp:
         fp.write(template.format(version=version, version_tuple=tuple(version_fields)))


Test patch:
diff --git a/testing/test_basic_api.py b/testing/test_basic_api.py
index 5e35a9e..5aaf8fa 100644
--- a/testing/test_basic_api.py
+++ b/testing/test_basic_api.py
@@ -112,6 +112,18 @@ def test_dump_version(tmpdir):
     assert "version = '1.0.dev42'" in lines
     assert "version_tuple = (1, 0, 'dev42')" in lines
 
+    dump_version(sp, "1.0.1+g4ac9d2c", "second.py")
+    content = tmpdir.join("second.py").read()
+    lines = content.splitlines()
+    assert "version = '1.0.1+g4ac9d2c'" in lines
+    assert "version_tuple = (1, 0, 1, 'g4ac9d2c')" in lines
+
+    dump_version(sp, "1.2.3.dev18+gb366d8b.d20210415", "third.py")
+    content = tmpdir.join("third.py").read()
+    lines = content.splitlines()
+    assert "version = '1.2.3.dev18+gb366d8b.d20210415'" in lines
+    assert "version_tuple = (1, 2, 3, 'dev18', 'gb366d8b.d20210415')" in lines
+
     import ast
 
     ast.parse(content)