Repository: pypa/pip

Issue:
Test test_debug__library_versions fails when versions have leading zeros, but vendor.txt omits them
**Environment**

* pip version: 201.0 (pre-release from master)
* Python version: 3.8
* OS: Windows

**Description**
The `certifi` package includes a leading zero in its published version, `2020.12.05`. When vendoring that version *without* including the leading zero (which is the output `pip freeze` gives for that version), the test `test_debug__library_versions` fails with a version conflict.

**Expected behavior**
The test should pass, as versions `2020.12.05` and `2020.12.5` are equivalent, according to PEP 440.

**How to Reproduce**
Modify the `vendor.txt` file on master to have a version of `2020.12.5` for `certifi`. Run the test `test_debug__library_versions`. It fails.

**Output**

```
====================================================== FAILURES =======================================================
____________________________________________ test_debug__library_versions _____________________________________________

script = <tests.lib.PipTestEnvironment object at 0x0000016ACDCBDCD0>

    def test_debug__library_versions(script):
        """
        Check the library versions normal output.
        """
        args = ['debug']
        result = script.pip(*args, allow_stderr_warning=True)
        print(result.stdout)

        vendored_versions = create_vendor_txt_map()
        for name, value in vendored_versions.items():
>           assert f'{name}=={value}' in result.stdout
E           AssertionError: assert 'certifi==2020.12.5' in 'pip version: pip 21.0.dev0 from c:\\users\\gustav\\appdata\\local\\temp\\pytest-of-gustav\\pytest-4\\pip0\\pip\\src\\...win_amd64\n  cp32-abi3-win_amd64\n  py38-none-win_amd64\n  ...\n  [First 10 tags shown. Pass --verbose to show all.]\n'
E            +  where 'pip version: pip 21.0.dev0 from c:\\users\\gustav\\appdata\\local\\temp\\pytest-of-gustav\\pytest-4\\pip0\\pip\\src\\...win_amd64\n  cp32-abi3-win_amd64\n  py38-none-win_amd64\n  ...\n  [First 10 tags shown. Pass --verbose to show all.]\n' = <tests.lib.TestPipResult object at 0x0000016ACDDB6E20>.stdout

tests\functional\test_debug.py:43: AssertionError
------------------------------------------------ Captured stderr setup ------------------------------------------------
warning: no files found matching 'docs\docutils.conf'
warning: no previously-included files found matching '.coveragerc'
warning: no previously-included files found matching '.mailmap'
warning: no previously-included files found matching '.appveyor.yml'
warning: no previously-included files found matching '.travis.yml'
warning: no previously-included files found matching '.readthedocs.yml'
warning: no previously-included files found matching '.pre-commit-config.yaml'
warning: no previously-included files found matching '.pre-commit-config-slow.yaml'
warning: no previously-included files found matching 'tox.ini'
warning: no previously-included files found matching 'noxfile.py'
warning: no files found matching '*.css' under directory 'docs'
warning: no files found matching '*.rst' under directory 'docs'
warning: no files found matching '*.py' under directory 'docs'
warning: no previously-included files found matching 'src\pip\_vendor\six'
warning: no previously-included files found matching 'src\pip\_vendor\six\moves'
warning: no previously-included files matching '*.pyi' found under directory 'src\pip\_vendor'
no previously-included directories found matching '.github'
no previously-included directories found matching '.azure-pipelines'
no previously-included directories found matching 'docs\build'
no previously-included directories found matching 'news'
no previously-included directories found matching 'tasks'
no previously-included directories found matching 'tests'
no previously-included directories found matching 'tools'
------------------------------------------------ Captured stdout call -------------------------------------------------
pip version: pip 21.0.dev0 from c:\users\gustav\appdata\local\temp\pytest-of-gustav\pytest-4\pip0\pip\src\pip (python 3.8)
sys.version: 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)]
sys.executable: C:\Users\Gustav\AppData\Local\Temp\pytest-of-Gustav\pytest-4\test_debug__library_versions0\workspace\venv\Scripts\python.exe
sys.getdefaultencoding: utf-8
sys.getfilesystemencoding: utf-8
locale.getpreferredencoding: cp1252
sys.platform: win32
sys.implementation:
  name: cpython
'cert' config value: global
REQUESTS_CA_BUNDLE: None
CURL_CA_BUNDLE: None
pip._vendor.certifi.where(): c:\users\gustav\appdata\local\temp\pytest-of-gustav\pytest-4\pip0\pip\src\pip\_vendor\certifi\cacert.pem
pip._vendor.DEBUNDLED: False
vendored library versions:
  appdirs==1.4.4
  CacheControl==0.12.6
  colorama==0.4.4
  contextlib2==0.6.0.post1 (Unable to locate actual module version, using vendor.txt specified version)
  distlib==0.3.1
  distro==1.5.0 (Unable to locate actual module version, using vendor.txt specified version)
  html5lib==1.1
  msgpack==1.0.2 (Unable to locate actual module version, using vendor.txt specified version)
  packaging==20.8
  pep517==0.9.1
  progress==1.5
  pyparsing==2.4.7
  requests==2.25.1
  certifi==2020.12.05 (CONFLICT: vendor.txt suggests version should be 2020.12.5)
  chardet==4.0.0
  idna==2.10
  urllib3==1.26.2
  resolvelib==0.5.4
  retrying==1.3.3 (Unable to locate actual module version, using vendor.txt specified version)
  setuptools==44.0.0 (Unable to locate actual module version, using vendor.txt specified version)
  six==1.15.0
  toml==0.10.2
  webencodings==0.5.1 (Unable to locate actual module version, using vendor.txt specified version)
Compatible tags: 30
  cp38-cp38-win_amd64
  cp38-abi3-win_amd64
  cp38-none-win_amd64
  cp37-abi3-win_amd64
  cp36-abi3-win_amd64
  cp35-abi3-win_amd64
  cp34-abi3-win_amd64
  cp33-abi3-win_amd64
  cp32-abi3-win_amd64
  py38-none-win_amd64
  ...
  [First 10 tags shown. Pass --verbose to show all.]
```

Note the line "certifi==2020.12.05 (CONFLICT: vendor.txt suggests version should be 2020.12.5)". This can also be seen in the `pip debug` output.

**Analysis**

The test was introduced in #7887 by @NoahGorny, and matches versions using string comparison. I believe it should use proper PEP 440 version comparison to confirm that the versions are the same.


Discussion:

Resolving patch:
diff --git a/src/pip/_internal/commands/debug.py b/src/pip/_internal/commands/debug.py
--- a/src/pip/_internal/commands/debug.py
+++ b/src/pip/_internal/commands/debug.py
@@ -6,6 +6,7 @@
 import pip._vendor
 from pip._vendor import pkg_resources
 from pip._vendor.certifi import where
+from pip._vendor.packaging.version import parse as parse_version
 
 from pip import __file__ as pip_location
 from pip._internal.cli import cmdoptions
@@ -100,7 +101,7 @@ def show_actual_vendor_versions(vendor_txt_versions):
             extra_message = ' (Unable to locate actual module version, using'\
                             ' vendor.txt specified version)'
             actual_version = expected_version
-        elif actual_version != expected_version:
+        elif parse_version(actual_version) != parse_version(expected_version):
             extra_message = ' (CONFLICT: vendor.txt suggests version should'\
                             ' be {})'.format(expected_version)
         logger.info('%s==%s%s', module_name, actual_version, extra_message)


Test patch: