Repository: twisted/incremental

Issue:
Have PEP440 normalized release candidate
This change was introduced here https://github.com/twisted/incremental/pull/62/files#diff-37e20d1852a6db96a5d77c800f2007c0265b65a30a62649dbb7c0fd1228eef72R207

From PEP440 https://peps.python.org/pep-0440/#pre-release-separators

Pre-releases should allow a ., -, or _ separator between the release segment and the pre-release segment. The normal form for this is without a separator. This allows versions such as 1.1.a1 or 1.1-a1 which would be normalized to 1.1a1. It should also allow a separator to be used between the pre-release signifier and the numeral. This allows versions such as 1.0a.1 which would be normalized to 1.0a1.

--------

I am reporting this issue as in Towncrier there is a test that checks that towncrier version is the same as the importlib version ... but for a release candidate, the test fails.

----

I am not sure if this is a valid bug report, as in theory the current format is still valid PEP440, is just that it is not normalized. 

Discussion:

Patch:
diff --git a/src/incremental/__init__.py b/src/incremental/__init__.py
index 9e89b8a..d804924 100644
--- a/src/incremental/__init__.py
+++ b/src/incremental/__init__.py
@@ -178,7 +178,7 @@ class Version(object):
         if self.release_candidate is None:
             rc = ""
         else:
-            rc = ".rc%s" % (self.release_candidate,)
+            rc = "rc%s" % (self.release_candidate,)
 
         if self.post is None:
             post = ""
diff --git a/src/incremental/newsfragments/81.bugfix b/src/incremental/newsfragments/81.bugfix
new file mode 100644
index 0000000..3b32880
--- /dev/null
+++ b/src/incremental/newsfragments/81.bugfix
@@ -0,0 +1,1 @@
+Incremental no longer inserts a dot before the rc version component (i.e., ``1.2.3rc1`` instead of ``1.2.3.rc1``), resulting in version numbers in the `canonical format <https://packaging.python.org/en/latest/specifications/version-specifiers/#public-version-identifiers>`__.


Test patch:
diff --git a/src/incremental/tests/test_update.py b/src/incremental/tests/test_update.py
index c6c874f..679e294 100644
--- a/src/incremental/tests/test_update.py
+++ b/src/incremental/tests/test_update.py
@@ -20,7 +20,6 @@ from incremental.update import _run, run
 
 class NonCreatedUpdateTests(TestCase):
     def setUp(self):
-
         self.srcdir = FilePath(self.mktemp())
         self.srcdir.makedirs()
 
@@ -84,7 +83,6 @@ __all__ = ["__version__"]
 
 class MissingTests(TestCase):
     def setUp(self):
-
         self.srcdir = FilePath(self.mktemp())
         self.srcdir.makedirs()
 
@@ -124,7 +122,7 @@ __all__ = ["__version__"]
         out = []
         with self.assertRaises(ValueError):
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion=None,
                 patch=False,
@@ -140,7 +138,6 @@ __all__ = ["__version__"]
 
 class CreatedUpdateInSrcTests(TestCase):
     def setUp(self):
-
         self.srcdir = FilePath(self.mktemp())
         self.srcdir.makedirs()
 
@@ -179,7 +176,7 @@ __all__ = ["__version__"]
         """
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=False,
@@ -210,7 +207,7 @@ __all__ = ["__version__"]
         )
 
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=False,
@@ -242,11 +239,9 @@ __all__ = ["__version__"]
 
 
 class CreatedUpdateTests(TestCase):
-
     maxDiff = None
 
     def setUp(self):
-
         self.srcdir = FilePath(self.mktemp())
         self.srcdir.makedirs()
 
@@ -283,7 +278,7 @@ __all__ = ["__version__"]
         """
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=self.packagedir.path,
             newversion=None,
             patch=False,
@@ -318,7 +313,7 @@ __all__ = ["__version__"]
         """
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=False,
@@ -354,7 +349,7 @@ __all__ = ["__version__"]
         """
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=True,
@@ -406,7 +401,7 @@ __all__ = ["__version__"]
 
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=True,
@@ -442,7 +437,7 @@ __all__ = ["__version__"]
         """
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=True,
@@ -475,7 +470,7 @@ __all__ = ["__version__"]
             b"""
 from incremental import Version
 introduced_in = Version("inctestpkg", 1, 2, 4, release_candidate=1).short()
-next_released_version = "inctestpkg 1.2.4.rc1"
+next_released_version = "inctestpkg 1.2.4rc1"
 """,
         )
 
@@ -494,7 +489,7 @@ __all__ = ["__version__"]
 
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=False,
@@ -527,7 +522,7 @@ __all__ = ["__version__"]
             b"""
 from incremental import Version
 introduced_in = Version("inctestpkg", 1, 2, 3, release_candidate=2).short()
-next_released_version = "inctestpkg 1.2.3.rc2"
+next_released_version = "inctestpkg 1.2.3rc2"
 """,
         )
 
@@ -547,7 +542,7 @@ __all__ = ["__version__"]
 
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=False,
@@ -580,7 +575,7 @@ __all__ = ["__version__"]
             b"""
 from incremental import Version
 introduced_in = Version("inctestpkg", 16, 8, 0, release_candidate=1).short()
-next_released_version = "inctestpkg 16.8.0.rc1"
+next_released_version = "inctestpkg 16.8.0rc1"
 """,
         )
 
@@ -591,7 +586,7 @@ next_released_version = "inctestpkg 16.8.0.rc1"
         """
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=False,
@@ -624,12 +619,12 @@ __all__ = ["__version__"]
             b"""
 from incremental import Version
 introduced_in = Version("inctestpkg", 16, 8, 0, release_candidate=1).short()
-next_released_version = "inctestpkg 16.8.0.rc1"
+next_released_version = "inctestpkg 16.8.0rc1"
 """,
         )
 
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=False,
@@ -674,7 +669,7 @@ next_released_version = "inctestpkg 16.8.0"
         out = []
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion=None,
                 patch=False,
@@ -698,7 +693,7 @@ next_released_version = "inctestpkg 16.8.0"
         """
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=False,
@@ -743,7 +738,7 @@ __all__ = ["__version__"]
 
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=False,
@@ -787,7 +782,7 @@ __all__ = ["__version__"]
 
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion=None,
             patch=False,
@@ -832,7 +827,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
         out = []
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion="1",
                 patch=True,
@@ -848,7 +843,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
 
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion="1",
                 patch=False,
@@ -864,7 +859,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
 
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion="1",
                 patch=False,
@@ -880,7 +875,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
 
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion="1",
                 patch=False,
@@ -901,7 +896,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
         out = []
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion=None,
                 patch=True,
@@ -917,7 +912,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
 
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion=None,
                 patch=False,
@@ -933,7 +928,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
 
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion=None,
                 patch=False,
@@ -955,7 +950,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
         out = []
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion=None,
                 patch=True,
@@ -971,7 +966,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
 
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion="1",
                 patch=False,
@@ -987,7 +982,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
 
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion=None,
                 patch=False,
@@ -1003,7 +998,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
 
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion=None,
                 patch=False,
@@ -1019,7 +1014,7 @@ next_released_version = "inctestpkg 1.2.3.post2"
 
         with self.assertRaises(ValueError) as e:
             _run(
-                u"inctestpkg",
+                "inctestpkg",
                 path=None,
                 newversion=None,
                 patch=False,
@@ -1035,14 +1030,14 @@ next_released_version = "inctestpkg 1.2.3.post2"
 
     def test_newversion(self):
         """
-        `incremental.update package --newversion=1.2.3.rc1.post2.dev3`, will
+        `incremental.update package --newversion=1.2.3rc1.post2.dev3`, will
         set that version in the package.
         """
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
-            newversion="1.2.3.rc1.post2.dev3",
+            newversion="1.2.3rc1.post2.dev3",
             patch=False,
             rc=False,
             post=False,
@@ -1076,7 +1071,7 @@ __all__ = ["__version__"]
 from incremental import Version
 introduced_in = Version("inctestpkg", 1, 2, 3, """
                 b"""release_candidate=1, post=2, dev=3).short()
-next_released_version = "inctestpkg 1.2.3.rc1.post2.dev3"
+next_released_version = "inctestpkg 1.2.3rc1.post2.dev3"
 """
             ),
         )
@@ -1088,7 +1083,7 @@ next_released_version = "inctestpkg 1.2.3.rc1.post2.dev3"
         """
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion="1",
             patch=False,
@@ -1132,7 +1127,7 @@ next_released_version = "inctestpkg 1.0.0"
         """
         out = []
         _run(
-            u"inctestpkg",
+            "inctestpkg",
             path=None,
             newversion="1.1",
             patch=False,
@@ -1172,7 +1167,6 @@ next_released_version = "inctestpkg 1.1.0"
 
 class ScriptTests(TestCase):
     def setUp(self):
-
         self.srcdir = FilePath(self.mktemp())
         self.srcdir.makedirs()
 
@@ -1256,6 +1250,6 @@ __all__ = ["__version__"]
             b"""
 from incremental import Version
 introduced_in = Version("inctestpkg", 16, 8, 0, release_candidate=1).short()
-next_released_version = "inctestpkg 16.8.0.rc1"
+next_released_version = "inctestpkg 16.8.0rc1"
 """,
         )
diff --git a/src/incremental/tests/test_version.py b/src/incremental/tests/test_version.py
index 17296d0..da66503 100644
--- a/src/incremental/tests/test_version.py
+++ b/src/incremental/tests/test_version.py
@@ -378,7 +378,7 @@ class VersionsTests(TestCase):
         as a release candidate.
         """
         self.assertEqual(
-            str(Version("dummy", 1, 0, 0, prerelease=1)), "[dummy, version 1.0.0.rc1]"
+            str(Version("dummy", 1, 0, 0, prerelease=1)), "[dummy, version 1.0.0rc1]"
         )
 
     def test_strWithReleaseCandidate(self):
@@ -388,7 +388,7 @@ class VersionsTests(TestCase):
         """
         self.assertEqual(
             str(Version("dummy", 1, 0, 0, release_candidate=1)),
-            "[dummy, version 1.0.0.rc1]",
+            "[dummy, version 1.0.0rc1]",
         )
 
     def test_strWithPost(self):
@@ -407,7 +407,7 @@ class VersionsTests(TestCase):
         """
         self.assertEqual(
             str(Version("dummy", 1, 0, 0, release_candidate=1, dev=2)),
-            "[dummy, version 1.0.0.rc1.dev2]",
+            "[dummy, version 1.0.0rc1.dev2]",
         )
 
     def test_strWithDev(self):
@@ -446,7 +446,7 @@ class VersionsTests(TestCase):
         """
         self.assertEqual(
             getVersionString(Version("whatever", 8, 0, 0, prerelease=1)),
-            "whatever 8.0.0.rc1",
+            "whatever 8.0.0rc1",
         )
 
     def test_getVersionStringWithReleaseCandidate(self):
@@ -455,7 +455,7 @@ class VersionsTests(TestCase):
         """
         self.assertEqual(
             getVersionString(Version("whatever", 8, 0, 0, release_candidate=1)),
-            "whatever 8.0.0.rc1",
+            "whatever 8.0.0rc1",
         )
 
     def test_getVersionStringWithPost(self):
@@ -482,7 +482,7 @@ class VersionsTests(TestCase):
         """
         self.assertEqual(
             getVersionString(Version("whatever", 8, 0, 0, release_candidate=2, dev=1)),
-            "whatever 8.0.0.rc2.dev1",
+            "whatever 8.0.0rc2.dev1",
         )
 
     def test_getVersionStringWithDevAndPost(self):
@@ -511,7 +511,7 @@ class VersionsTests(TestCase):
         """
         The base version includes 'rcX' for versions with prereleases.
         """
-        self.assertEqual(Version("foo", 1, 0, 0, prerelease=8).base(), "1.0.0.rc8")
+        self.assertEqual(Version("foo", 1, 0, 0, prerelease=8).base(), "1.0.0rc8")
 
     def test_baseWithPost(self):
         """
@@ -530,7 +530,7 @@ class VersionsTests(TestCase):
         The base version includes 'rcX' for versions with prereleases.
         """
         self.assertEqual(
-            Version("foo", 1, 0, 0, release_candidate=8).base(), "1.0.0.rc8"
+            Version("foo", 1, 0, 0, release_candidate=8).base(), "1.0.0rc8"
         )
 
     def test_baseWithDevAndRC(self):
@@ -539,7 +539,7 @@ class VersionsTests(TestCase):
         a release candidate.
         """
         self.assertEqual(
-            Version("foo", 1, 0, 0, release_candidate=2, dev=8).base(), "1.0.0.rc2.dev8"
+            Version("foo", 1, 0, 0, release_candidate=2, dev=8).base(), "1.0.0rc2.dev8"
         )
 
     def test_baseWithDevAndPost(self):