)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":2475,"name":"Antoine Musso","email":"hashar@free.fr","username":"hashar"},"change_message_id":"f6fed603d95b1d2c738bdc26d60740f5fc53cde4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"22ac5486_de7b9d03","updated":"2023-03-16 20:09:27.000000000","message":"From my comment on https://review.opendev.org/c/jjb/python-jenkins/+/865776\n\n\u003e Locally I can reproduce the failure it comes from v66.0.0 https://setuptools.pypa.io/en/latest/history.html#v66-0-0\n\u003e \n\u003e 15 Jan 2023\n\u003e    Breaking Changes\n\u003e \n\u003e #2497: Support for PEP 440 non-conforming versions has been removed. Environments containing packages with non-conforming versions may fail or the packages may not be recognized.\n\n","commit_id":"28b2499e4fb7f24aaa5969172d2a1afb55dbb721"},{"author":{"_account_id":35972,"name":"Christoph Erhardt","email":"ce+ubuntuone@sicherha.de","username":"sicherha"},"change_message_id":"fb206e6a9103a4eb0073d9da286c0c2a14b65c3a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"8c0a88d5_4d20e3bc","updated":"2023-04-30 09:23:18.000000000","message":"Follow-up: https://review.opendev.org/c/jjb/python-jenkins/+/881904","commit_id":"68bc075c934f94925900743a7fb8befae3ccffd2"},{"author":{"_account_id":2475,"name":"Antoine Musso","email":"hashar@free.fr","username":"hashar"},"change_message_id":"85781eab5c69b996b566a5b2dd911e94f4ec9a15","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"3457e73c_0e975d3f","updated":"2023-03-17 10:41:02.000000000","message":"We should go with https://pypi.org/project/semantic-version/ , see my rationale in the diff comment ;)","commit_id":"68bc075c934f94925900743a7fb8befae3ccffd2"},{"author":{"_account_id":2475,"name":"Antoine Musso","email":"hashar@free.fr","username":"hashar"},"change_message_id":"0387c2f936df25591e84b04824a7f0cf9f315487","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"fb4fb3bc_16b40902","updated":"2023-03-21 10:38:57.000000000","message":"recheck after CI fix https://review.opendev.org/c/jjb/python-jenkins/+/865776","commit_id":"68bc075c934f94925900743a7fb8befae3ccffd2"}],"jenkins/plugins.py":[{"author":{"_account_id":2475,"name":"Antoine Musso","email":"hashar@free.fr","username":"hashar"},"change_message_id":"2ce911fc8cd53557df603747cdb19919fe7e7025","unresolved":true,"context_lines":[{"line_number":42,"context_line":"import operator"},{"line_number":43,"context_line":"import re"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"import packaging"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"class Plugin(dict):"}],"source_content_type":"text/x-python","patch_set":1,"id":"03a4256c_ca3a81f9","line":45,"range":{"start_line":45,"start_character":0,"end_line":45,"end_character":16},"updated":"2023-03-16 15:47:30.000000000","message":"That should be:\n\n import packaging.version","commit_id":"28b2499e4fb7f24aaa5969172d2a1afb55dbb721"},{"author":{"_account_id":2475,"name":"Antoine Musso","email":"hashar@free.fr","username":"hashar"},"change_message_id":"2ce911fc8cd53557df603747cdb19919fe7e7025","unresolved":true,"context_lines":[{"line_number":76,"context_line":"        \u0027\u0027\u0027Parse plugin version and store it for comparison.\u0027\u0027\u0027"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        self._version \u003d version"},{"line_number":79,"context_line":"        self.parsed_version \u003d packaging.version.parse("},{"line_number":80,"context_line":"            self.__convert_version(version))"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def __convert_version(self, version):"},{"line_number":83,"context_line":"        return self._VERSION_RE.sub(r\u0027\\g\u003c1\u003e.preview\u0027, str(version))"}],"source_content_type":"text/x-python","patch_set":1,"id":"63abd45c_8882f036","line":80,"range":{"start_line":79,"start_character":0,"end_line":80,"end_character":44},"updated":"2023-03-16 15:47:30.000000000","message":"I have hit the issue previously when parsing a list of Jenkins plugins. Their version do not match whatever PEP defines a version and thus some versions might end up being invalid.\n\n import pkg_resources\n import packaging.version\n \n versions \u003d [\u00271.4.4\u0027, \u00271.5\u0027, \u00274.5.13-138.v4e7d9a_7b_a_e61\u0027]\n \n for v in versions:\n     print(\u0027Version\u0027, v, end\u003d\u0027 \u0027)\n     try:\n         pkg_resources.parse_version(v)\n         print(\u0027OK\u0027)\n         packaging.version.parse(v)\n         print(\u0027OK\u0027)\n     except Exception as e:\n         print(\u0027Exception\u0027, e)\n\nWhich gives:\n\n Version 1.4.4                                                                                                                                                                                 \n OK                                                                                                                                                                                            \n OK                                                                                                                                                                                            \n Version 1.5                                                                                                                                                                                   \n OK                                                                                                                                                                                            \n OK                                                                                                                                                                                            \n Version 4.5.13-138.v4e7d9a_7b_a_e61                                                                                                                                                           \n OK                                                                                                                                                                                            \n Exception Invalid version: \u00274.5.13-138.v4e7d9a_7b_a_e61\u0027","commit_id":"28b2499e4fb7f24aaa5969172d2a1afb55dbb721"},{"author":{"_account_id":9369,"name":"Steve Kowalik","email":"steven@wedontsleep.org","username":"stevenk"},"change_message_id":"62a19a36ee2c8cf79fc187afa59e99e76ddb9cc5","unresolved":true,"context_lines":[{"line_number":76,"context_line":"        \u0027\u0027\u0027Parse plugin version and store it for comparison.\u0027\u0027\u0027"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        self._version \u003d version"},{"line_number":79,"context_line":"        self.parsed_version \u003d packaging.version.parse("},{"line_number":80,"context_line":"            self.__convert_version(version))"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def __convert_version(self, version):"},{"line_number":83,"context_line":"        return self._VERSION_RE.sub(r\u0027\\g\u003c1\u003e.preview\u0027, str(version))"}],"source_content_type":"text/x-python","patch_set":1,"id":"66e67122_e5d0fc8e","line":80,"range":{"start_line":79,"start_character":0,"end_line":80,"end_character":44},"in_reply_to":"2509d39c_6ee2dd71","updated":"2023-04-17 04:49:30.000000000","message":"semantic_version isn\u0027t nearly lax enough to make the existing test suite pass. Pasting some of the underlying code from LegacyVersion from packaging before it was removed makes the existing tests pass.","commit_id":"28b2499e4fb7f24aaa5969172d2a1afb55dbb721"},{"author":{"_account_id":2475,"name":"Antoine Musso","email":"hashar@free.fr","username":"hashar"},"change_message_id":"85781eab5c69b996b566a5b2dd911e94f4ec9a15","unresolved":true,"context_lines":[{"line_number":76,"context_line":"        \u0027\u0027\u0027Parse plugin version and store it for comparison.\u0027\u0027\u0027"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        self._version \u003d version"},{"line_number":79,"context_line":"        self.parsed_version \u003d packaging.version.parse("},{"line_number":80,"context_line":"            self.__convert_version(version))"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def __convert_version(self, version):"},{"line_number":83,"context_line":"        return self._VERSION_RE.sub(r\u0027\\g\u003c1\u003e.preview\u0027, str(version))"}],"source_content_type":"text/x-python","patch_set":1,"id":"2509d39c_6ee2dd71","line":80,"range":{"start_line":79,"start_character":0,"end_line":80,"end_character":44},"in_reply_to":"63abd45c_8882f036","updated":"2023-03-17 10:41:02.000000000","message":"After some digging `openstack/requirements` lists https://pypi.org/project/semantic-version/ which provides semantic versioning and supports invalid versions (via Version.coerce()). A demo:\n\n import semantic_version\n \n versions \u003d [\u00271.4.4\u0027, \u00271.5\u0027, \u00274.5.13-138.v4e7d9a_7b_a_e61\u0027]\n \n for v in versions:\n     print(\u0027Version\u0027, v, end\u003d\u0027 \u0027)\n     semver \u003d semantic_version.Version.coerce(v)\n     print(\u0027OK\u0027)\n     print(\", \".join([\n         \"%s: %s\" % (attr, getattr(semver, attr))\n         for attr in [\u0027major\u0027, \u0027minor\u0027, \u0027patch\u0027, \u0027prerelease\u0027]\n         ]))\n  \nYields:\n\n Version 1.4.4 OK\n major: 1, minor: 4, patch: 4, prerelease: ()\n Version 1.5 OK\n major: 1, minor: 5, patch: 0, prerelease: ()\n Version 4.5.13-138.v4e7d9a_7b_a_e61 OK \n major: 4, minor: 5, patch: 13, prerelease: (\u0027138\u0027, \u0027v4e7d9a-7b-a-e61\u0027)\n \nIt thus support an invalid \u00271.5\u0027 and convert to \u00271.5.0\u0027, same for the invalid long one.  Both styles are used by Jenkins plugins.\n\n\nBy using `semantic_version` as a module dependency, we relieve ourselves from the way stricter Python package versioning which is slightly different and have no interest in supporting \"invalid\" version (as shown by Setuptools 66 dropping it entirely).","commit_id":"28b2499e4fb7f24aaa5969172d2a1afb55dbb721"}]}
