normalize_version ----------------- The exact output can differ lots for various setuptools versions. setuptools 7 and lower: None -> ('*final',) '1.1' -> ('00000001', '00000001', '*final') setuptools 8 and higher: None -> '1.1' -> Workaround is to turn the result into a tuple. But that makes pkg_resources complain when using setuptools 8 or higher: RuntimeWarning: You have iterated over the result of pkg_resources.parse_version. This is a legacy behavior which is inconsistent with the new version class introduced in setuptools 8.0. In most cases, conversion to a tuple is unnecessary. For comparison of versions, sort the Version instances directly. If you have another use case requiring the tuple, please file a bug with the setuptools project describing that need. In our case the only important part is that sorting works reliably, which is what we check here. >>> from Products.GenericSetup.upgrade import normalize_version >>> normalize_version(None) < normalize_version('1.1') True >>> normalize_version('1.1') > normalize_version(None) True >>> normalize_version('unknown') < normalize_version('1.1') True >>> normalize_version('1.0') < normalize_version('1.1') True >>> normalize_version(('1', '1')) == normalize_version('1.1') True _version_matches_all ------------------- >>> from Products.GenericSetup.upgrade import _version_matches_all >>> _version_matches_all(None) True >>> _version_matches_all('all') True >>> _version_matches_all('unknown') True >>> _version_matches_all('') False >>> _version_matches_all('1.0') False >>> _version_matches_all(('all', )) True >>> _version_matches_all(('1', '0')) False _version_matches --------------- >>> from Products.GenericSetup.upgrade import _version_matches >>> _version_matches(None, '1.0', '2.0') True >>> _version_matches('0.5', '1.0', '2.0') True >>> _version_matches('0.5', '1.0', '2.0', strict=True) False >>> _version_matches('1.0', '1.0', '2.0', strict=True) True >>> _version_matches('1.5', '1.0', '2.0') False >>> _version_matches('1.0', '1.0', '0.5') False >>> _version_matches('1.0', '1.0', 'unknown') True UpgradeEntity ------------- >>> from Products.GenericSetup.upgrade import _extractStepInfo >>> from Products.GenericSetup.upgrade import UpgradeEntity >>> tool = object() >>> def true_checker(tool): return True >>> def false_checker(tool): return False with no restrictions: all -> all, no checker -------------------------------------------- >>> e = UpgradeEntity('TITLE', 'PROFILE', '*', '*', 'DESC') >>> e.source is None True >>> e.dest is None True all <> unknown <> all >>> e.versionMatch(None) True >>> e.isProposed(tool, None) True >>> bool(_extractStepInfo(tool, 'ID', e, None)) True >>> e.versionMatch('unknown') True >>> e.isProposed(tool, 'unknown') True >>> bool(_extractStepInfo(tool, 'ID', e, 'unknown')) True all <> 1.0 <> all >>> e.versionMatch('1.0') True >>> e.isProposed(tool, '1.0') True >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True all <> 2.0 <> all >>> e.versionMatch('2.0') True >>> e.isProposed(tool, '2.0') True >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) True with version restriction: all -> 2.0, no checker ------------------------------------------------ >>> e = UpgradeEntity('TITLE', 'PROFILE', '*', '2.0', 'DESC') >>> e.source is None True >>> e.dest ('2', '0') all <> unknown <> 2.0 >>> e.versionMatch(None) True >>> e.isProposed(tool, None) True >>> bool(_extractStepInfo(tool, 'ID', e, None)) True >>> e.versionMatch('unknown') True >>> e.isProposed(tool, 'unknown') True >>> bool(_extractStepInfo(tool, 'ID', e, 'unknown')) True all <> 1.0 < 2.0 >>> e.versionMatch('1.0') True >>> e.isProposed(tool, '1.0') True >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True all <> 2.0 == 2.0 >>> e.versionMatch('2.0') False >>> e.isProposed(tool, '2.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) False with version restriction: 1.0 -> 2.0, no checker ------------------------------------------------ >>> e = UpgradeEntity('TITLE', 'PROFILE', '1.0', '2.0', 'DESC') >>> e.source ('1', '0') >>> e.dest ('2', '0') 1.0 <> unknown <> 2.0 >>> e.versionMatch(None) True >>> e.isProposed(tool, None) True >>> bool(_extractStepInfo(tool, 'ID', e, None)) True >>> e.versionMatch('unknown') True >>> e.isProposed(tool, 'unknown') True >>> bool(_extractStepInfo(tool, 'ID', e, 'unknown')) True 1.0 == 1.0 < 2.0 >>> e.versionMatch('1.0') True >>> e.isProposed(tool, '1.0') True >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True 1.0 < 2.0 == 2.0 >>> e.versionMatch('2.0') False >>> e.isProposed(tool, '2.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) False with version restriction: 1.1 -> 2.0, no checker ------------------------------------------------ >>> e = UpgradeEntity('TITLE', 'PROFILE', '1.1', '2.0', 'DESC') >>> e.source ('1', '1') >>> e.dest ('2', '0') 1.1 <> unknown <> 2.0 >>> e.versionMatch(None) True >>> e.isProposed(tool, None) True >>> bool(_extractStepInfo(tool, 'ID', e, None)) True >>> e.versionMatch('unknown') True >>> e.isProposed(tool, 'unknown') True >>> bool(_extractStepInfo(tool, 'ID', e, 'unknown')) True 1.1 > 1.0 < 2.0 >>> e.versionMatch('1.0') False >>> e.isProposed(tool, '1.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True 1.1 < 2.0 == 2.0 >>> e.versionMatch('2.0') False >>> e.isProposed(tool, '2.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) False with version restriction: 2.0 -> 3.0, no checker ------------------------------------------------ >>> e = UpgradeEntity('TITLE', 'PROFILE', '2.0', '3.0', 'DESC') >>> e.source ('2', '0') >>> e.dest ('3', '0') 2.0 <> unknown <> 3.0 >>> e.versionMatch(None) True >>> e.isProposed(tool, None) True >>> bool(_extractStepInfo(tool, 'ID', e, None)) True >>> e.versionMatch('unknown') True >>> e.isProposed(tool, 'unknown') True >>> bool(_extractStepInfo(tool, 'ID', e, 'unknown')) True 2.0 > 1.0 < 3.0 >>> e.versionMatch('1.0') False >>> e.isProposed(tool, '1.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True 2.0 == 2.0 < 3.0 >>> e.versionMatch('2.0') True >>> e.isProposed(tool, '2.0') True >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) True with checker restriction: all -> all, true checker -------------------------------------------------- >>> e = UpgradeEntity('TITLE', 'PROFILE', '*', '*', 'DESC', true_checker) all <> unknown <> all >>> e.versionMatch(None) True >>> e.isProposed(tool, None) True >>> bool(_extractStepInfo(tool, 'ID', e, None)) True all <> 1.0 <> all >>> e.versionMatch('1.0') True >>> e.isProposed(tool, '1.0') True >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True all <> 2.0 <> all >>> e.versionMatch('2.0') True >>> e.isProposed(tool, '2.0') True >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) True with checker restriction: all -> all, false checker --------------------------------------------------- >>> e = UpgradeEntity('TITLE', 'PROFILE', '*', '*', 'DESC', false_checker) all <> unknown <> all >>> e.versionMatch(None) True >>> e.isProposed(tool, None) False >>> bool(_extractStepInfo(tool, 'ID', e, None)) True all <> 1.0 <> all >>> e.versionMatch('1.0') True >>> e.isProposed(tool, '1.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True all <> 2.0 <> all >>> e.versionMatch('2.0') True >>> e.isProposed(tool, '2.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) True with combined restrictions: 1.0 -> 2.0, true checker ---------------------------------------------------- >>> e = UpgradeEntity('TITLE', 'PROFILE', '1.0', '2.0', 'DESC', true_checker) 1.0 <> unknown <> 2.0 >>> e.versionMatch(None) True >>> e.isProposed(tool, None) True >>> bool(_extractStepInfo(tool, 'ID', e, None)) True 1.0 == 1.0 < 2.0 >>> e.versionMatch('1.0') True >>> e.isProposed(tool, '1.0') True >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True 1.0 < 2.0 == 2.0 >>> e.versionMatch('2.0') False >>> e.isProposed(tool, '2.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) False with combined restrictions: 1.1 -> 2.0, true checker ---------------------------------------------------- >>> e = UpgradeEntity('TITLE', 'PROFILE', '1.1', '2.0', 'DESC', true_checker) 1.1 <> unknown <> 2.0 >>> e.versionMatch(None) True >>> e.isProposed(tool, None) True >>> bool(_extractStepInfo(tool, 'ID', e, None)) True 1.1 > 1.0 < 2.0 >>> e.versionMatch('1.0') False >>> e.isProposed(tool, '1.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True 1.1 < 2.0 == 2.0 >>> e.versionMatch('2.0') False >>> e.isProposed(tool, '2.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) False with combined restrictions: 2.0 -> 3.0, true checker ---------------------------------------------------- >>> e = UpgradeEntity('TITLE', 'PROFILE', '2.0', '3.0', 'DESC', true_checker) 2.0 <> unknown <> 3.0 >>> e.versionMatch(None) True >>> e.isProposed(tool, None) True >>> bool(_extractStepInfo(tool, 'ID', e, None)) True 2.0 > 1.0 < 3.0 >>> e.versionMatch('1.0') False >>> e.isProposed(tool, '1.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True 2.0 == 2.0 < 3.0 >>> e.versionMatch('2.0') True >>> e.isProposed(tool, '2.0') True >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) True with combined restrictions: 1.0 -> 2.0, false checker ----------------------------------------------------- >>> e = UpgradeEntity('TITLE', 'PROFILE', '1.0', '2.0', 'DESC', false_checker) 1.0 <> unknown <> 2.0 >>> e.versionMatch(None) True >>> e.isProposed(tool, None) False >>> bool(_extractStepInfo(tool, 'ID', e, None)) True 1.0 == 1.0 < 2.0 >>> e.versionMatch('1.0') True >>> e.isProposed(tool, '1.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True 1.0 < 2.0 == 2.0 >>> e.versionMatch('2.0') False >>> e.isProposed(tool, '2.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) False with combined restrictions: 1.1 -> 2.0, false checker ----------------------------------------------------- >>> e = UpgradeEntity('TITLE', 'PROFILE', '1.1', '2.0', 'DESC', false_checker) 1.1 <> unknown <> 2.0 >>> e.versionMatch(None) True >>> e.isProposed(tool, None) False >>> bool(_extractStepInfo(tool, 'ID', e, None)) True 1.1 > 1.0 < 2.0 >>> e.versionMatch('1.0') False >>> e.isProposed(tool, '1.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True 1.1 < 2.0 == 2.0 >>> e.versionMatch('2.0') False >>> e.isProposed(tool, '2.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) False with combined restrictions: 2.0 -> 3.0, false checker ----------------------------------------------------- >>> e = UpgradeEntity('TITLE', 'PROFILE', '2.0', '3.0', 'DESC', false_checker) 2.0 <> unknown <> 3.0 >>> e.versionMatch(None) True >>> e.isProposed(tool, None) False >>> bool(_extractStepInfo(tool, 'ID', e, None)) True 2.0 > 1.0 < 3.0 >>> e.versionMatch('1.0') False >>> e.isProposed(tool, '1.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '1.0')) True 2.0 == 2.0 < 3.0 >>> e.versionMatch('2.0') True >>> e.isProposed(tool, '2.0') False >>> bool(_extractStepInfo(tool, 'ID', e, '2.0')) True