prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Add SSL CA certificate information to `pip debug`
  **What's the problem this feature will solve?**
  
  As described in [#6720 (comment)](https://github.com/pypa/pip/issues/6720#issuecomment-538791684), pip may be using several sources of information for the CA certificate bundle to use for HTTPS requests. This makes it hard to debug user issues.
  
  **Describe the solution you'd like**
  
  In the output of `pip debug` we should include:
  
  * the `cert` setting from the highest-priority pip configuration file (~~and the configuration file path~~) - on second thought the location doesn't matter much
  * `os.environ.get('REQUESTS_CA_BUNDLE')`
  * `os.environ.get('CURL_CA_BUNDLE')`
  * `pip._vendor.certifi.where()`
  
  This will provide insight into the CA certificate bundle in use for a given request, which can then be used in instructions to the user in conjunction with curl/openssl to submit an HTTP request independent of pip and rule out pip-specific issues.
  
  **Alternative Solutions**
  
  Do nothing.
  
  **Additional context**
  
  * #4459
  * #4919
  * #6335
  * #6720
  * #6915
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/pip/_internal/commands/debug.py`
  Content:
  ```
  1 # The following comment should be removed at some point in the future.
  2 # mypy: disallow-untyped-defs=False
  3 
  4 from __future__ import absolute_import
  5 
  6 import locale
  7 import logging
  8 import sys
  9 
  10 from pip._internal.cli import cmdoptions
  11 from pip._internal.cli.base_command import Command
  12 from pip._internal.cli.cmdoptions import make_target_python
  13 from pip._internal.cli.status_codes import SUCCESS
  14 from pip._internal.utils.logging import indent_log
  15 from pip._internal.utils.misc import get_pip_version
  16 from pip._internal.utils.typing import MYPY_CHECK_RUNNING
  17 from pip._internal.wheel import format_tag
  18 
  19 if MYPY_CHECK_RUNNING:
  20     from typing import Any, List
  21     from optparse import Values
  22 
  23 logger = logging.getLogger(__name__)
  24 
  25 
  26 def show_value(name, value):
  27     # type: (str, str) -> None
  28     logger.info('{}: {}'.format(name, value))
  29 
  30 
  31 def show_sys_implementation():
  32     # type: () -> None
  33     logger.info('sys.implementation:')
  34     if hasattr(sys, 'implementation'):
  35         implementation = sys.implementation  # type: ignore
  36         implementation_name = implementation.name
  37     else:
  38         implementation_name = ''
  39 
  40     with indent_log():
  41         show_value('name', implementation_name)
  42 
  43 
  44 def show_tags(options):
  45     # type: (Values) -> None
  46     tag_limit = 10
  47 
  48     target_python = make_target_python(options)
  49     tags = target_python.get_tags()
  50 
  51     # Display the target options that were explicitly provided.
  52     formatted_target = target_python.format_given()
  53     suffix = ''
  54     if formatted_target:
  55         suffix = ' (target: {})'.format(formatted_target)
  56 
  57     msg = 'Compatible tags: {}{}'.format(len(tags), suffix)
  58     logger.info(msg)
  59 
  60     if options.verbose < 1 and len(tags) > tag_limit:
  61         tags_limited = True
  62         tags = tags[:tag_limit]
  63     else:
  64         tags_limited = False
  65 
  66     with indent_log():
  67         for tag in tags:
  68             logger.info(format_tag(tag))
  69 
  70         if tags_limited:
  71             msg = (
  72                 '...\n'
  73                 '[First {tag_limit} tags shown. Pass --verbose to show all.]'
  74             ).format(tag_limit=tag_limit)
  75             logger.info(msg)
  76 
  77 
  78 class DebugCommand(Command):
  79     """
  80     Display debug information.
  81     """
  82 
  83     usage = """
  84       %prog <options>"""
  85     ignore_require_venv = True
  86 
  87     def __init__(self, *args, **kw):
  88         super(DebugCommand, self).__init__(*args, **kw)
  89 
  90         cmd_opts = self.cmd_opts
  91         cmdoptions.add_target_python_options(cmd_opts)
  92         self.parser.insert_option_group(0, cmd_opts)
  93 
  94     def run(self, options, args):
  95         # type: (Values, List[Any]) -> int
  96         logger.warning(
  97             "This command is only meant for debugging. "
  98             "Do not use this with automation for parsing and getting these "
  99             "details, since the output and options of this command may "
  100             "change without notice."
  101         )
  102         show_value('pip version', get_pip_version())
  103         show_value('sys.version', sys.version)
  104         show_value('sys.executable', sys.executable)
  105         show_value('sys.getdefaultencoding', sys.getdefaultencoding())
  106         show_value('sys.getfilesystemencoding', sys.getfilesystemencoding())
  107         show_value(
  108             'locale.getpreferredencoding', locale.getpreferredencoding(),
  109         )
  110         show_value('sys.platform', sys.platform)
  111         show_sys_implementation()
  112 
  113         show_tags(options)
  114 
  115         return SUCCESS
  116
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: 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
  @@ -5,8 +5,11 @@
   
   import locale
   import logging
  +import os
   import sys
   
  +from pip._vendor.certifi import where
  +
   from pip._internal.cli import cmdoptions
   from pip._internal.cli.base_command import Command
   from pip._internal.cli.cmdoptions import make_target_python
  @@ -17,14 +20,14 @@
   from pip._internal.wheel import format_tag
   
   if MYPY_CHECK_RUNNING:
  -    from typing import Any, List
  +    from typing import Any, List, Optional
       from optparse import Values
   
   logger = logging.getLogger(__name__)
   
   
   def show_value(name, value):
  -    # type: (str, str) -> None
  +    # type: (str, Optional[str]) -> None
       logger.info('{}: {}'.format(name, value))
   
   
  @@ -75,6 +78,25 @@
               logger.info(msg)
   
   
  +def ca_bundle_info(config):
  +    levels = set()
  +    for key, value in config.items():
  +        levels.add(key.split('.')[0])
  +
  +    if not levels:
  +        return "Not specified"
  +
  +    levels_that_override_global = ['install', 'wheel', 'download']
  +    global_overriding_level = [
  +        level for level in levels if level in levels_that_override_global
  +    ]
  +    if not global_overriding_level:
  +        return 'global'
  +
  +    levels.remove('global')
  +    return ", ".join(levels)
  +
  +
   class DebugCommand(Command):
       """
       Display debug information.
  @@ -90,6 +112,7 @@
           cmd_opts = self.cmd_opts
           cmdoptions.add_target_python_options(cmd_opts)
           self.parser.insert_option_group(0, cmd_opts)
  +        self.parser.config.load()
   
       def run(self, options, args):
           # type: (Values, List[Any]) -> int
  @@ -110,6 +133,11 @@
           show_value('sys.platform', sys.platform)
           show_sys_implementation()
   
  +        show_value("'cert' config value", ca_bundle_info(self.parser.config))
  +        show_value("REQUESTS_CA_BUNDLE", os.environ.get('REQUESTS_CA_BUNDLE'))
  +        show_value("CURL_CA_BUNDLE", os.environ.get('CURL_CA_BUNDLE'))
  +        show_value("pip._vendor.certifi.where()", where())
  +
           show_tags(options)
   
           return SUCCESS
  
verification_info: {"golden_diff": "diff --git a/src/pip/_internal/commands/debug.py b/src/pip/_internal/commands/debug.py\n--- a/src/pip/_internal/commands/debug.py\n+++ b/src/pip/_internal/commands/debug.py\n@@ -5,8 +5,11 @@\n \n import locale\n import logging\n+import os\n import sys\n \n+from pip._vendor.certifi import where\n+\n from pip._internal.cli import cmdoptions\n from pip._internal.cli.base_command import Command\n from pip._internal.cli.cmdoptions import make_target_python\n@@ -17,14 +20,14 @@\n from pip._internal.wheel import format_tag\n \n if MYPY_CHECK_RUNNING:\n-    from typing import Any, List\n+    from typing import Any, List, Optional\n     from optparse import Values\n \n logger = logging.getLogger(__name__)\n \n \n def show_value(name, value):\n-    # type: (str, str) -> None\n+    # type: (str, Optional[str]) -> None\n     logger.info('{}: {}'.format(name, value))\n \n \n@@ -75,6 +78,25 @@\n             logger.info(msg)\n \n \n+def ca_bundle_info(config):\n+    levels = set()\n+    for key, value in config.items():\n+        levels.add(key.split('.')[0])\n+\n+    if not levels:\n+        return \"Not specified\"\n+\n+    levels_that_override_global = ['install', 'wheel', 'download']\n+    global_overriding_level = [\n+        level for level in levels if level in levels_that_override_global\n+    ]\n+    if not global_overriding_level:\n+        return 'global'\n+\n+    levels.remove('global')\n+    return \", \".join(levels)\n+\n+\n class DebugCommand(Command):\n     \"\"\"\n     Display debug information.\n@@ -90,6 +112,7 @@\n         cmd_opts = self.cmd_opts\n         cmdoptions.add_target_python_options(cmd_opts)\n         self.parser.insert_option_group(0, cmd_opts)\n+        self.parser.config.load()\n \n     def run(self, options, args):\n         # type: (Values, List[Any]) -> int\n@@ -110,6 +133,11 @@\n         show_value('sys.platform', sys.platform)\n         show_sys_implementation()\n \n+        show_value(\"'cert' config value\", ca_bundle_info(self.parser.config))\n+        show_value(\"REQUESTS_CA_BUNDLE\", os.environ.get('REQUESTS_CA_BUNDLE'))\n+        show_value(\"CURL_CA_BUNDLE\", os.environ.get('CURL_CA_BUNDLE'))\n+        show_value(\"pip._vendor.certifi.where()\", where())\n+\n         show_tags(options)\n \n         return SUCCESS\n", "issue": "Add SSL CA certificate information to `pip debug`\n**What's the problem this feature will solve?**\r\n\r\nAs described in [#6720 (comment)](https://github.com/pypa/pip/issues/6720#issuecomment-538791684), pip may be using several sources of information for the CA certificate bundle to use for HTTPS requests. This makes it hard to debug user issues.\r\n\r\n**Describe the solution you'd like**\r\n\r\nIn the output of `pip debug` we should include:\r\n\r\n* the `cert` setting from the highest-priority pip configuration file (~~and the configuration file path~~) - on second thought the location doesn't matter much\r\n* `os.environ.get('REQUESTS_CA_BUNDLE')`\r\n* `os.environ.get('CURL_CA_BUNDLE')`\r\n* `pip._vendor.certifi.where()`\r\n\r\nThis will provide insight into the CA certificate bundle in use for a given request, which can then be used in instructions to the user in conjunction with curl/openssl to submit an HTTP request independent of pip and rule out pip-specific issues.\r\n\r\n**Alternative Solutions**\r\n\r\nDo nothing.\r\n\r\n**Additional context**\r\n\r\n* #4459\r\n* #4919\r\n* #6335\r\n* #6720\r\n* #6915\n", "before_files": [{"content": "# The following comment should be removed at some point in the future.\n# mypy: disallow-untyped-defs=False\n\nfrom __future__ import absolute_import\n\nimport locale\nimport logging\nimport sys\n\nfrom pip._internal.cli import cmdoptions\nfrom pip._internal.cli.base_command import Command\nfrom pip._internal.cli.cmdoptions import make_target_python\nfrom pip._internal.cli.status_codes import SUCCESS\nfrom pip._internal.utils.logging import indent_log\nfrom pip._internal.utils.misc import get_pip_version\nfrom pip._internal.utils.typing import MYPY_CHECK_RUNNING\nfrom pip._internal.wheel import format_tag\n\nif MYPY_CHECK_RUNNING:\n    from typing import Any, List\n    from optparse import Values\n\nlogger = logging.getLogger(__name__)\n\n\ndef show_value(name, value):\n    # type: (str, str) -> None\n    logger.info('{}: {}'.format(name, value))\n\n\ndef show_sys_implementation():\n    # type: () -> None\n    logger.info('sys.implementation:')\n    if hasattr(sys, 'implementation'):\n        implementation = sys.implementation  # type: ignore\n        implementation_name = implementation.name\n    else:\n        implementation_name = ''\n\n    with indent_log():\n        show_value('name', implementation_name)\n\n\ndef show_tags(options):\n    # type: (Values) -> None\n    tag_limit = 10\n\n    target_python = make_target_python(options)\n    tags = target_python.get_tags()\n\n    # Display the target options that were explicitly provided.\n    formatted_target = target_python.format_given()\n    suffix = ''\n    if formatted_target:\n        suffix = ' (target: {})'.format(formatted_target)\n\n    msg = 'Compatible tags: {}{}'.format(len(tags), suffix)\n    logger.info(msg)\n\n    if options.verbose < 1 and len(tags) > tag_limit:\n        tags_limited = True\n        tags = tags[:tag_limit]\n    else:\n        tags_limited = False\n\n    with indent_log():\n        for tag in tags:\n            logger.info(format_tag(tag))\n\n        if tags_limited:\n            msg = (\n                '...\\n'\n                '[First {tag_limit} tags shown. Pass --verbose to show all.]'\n            ).format(tag_limit=tag_limit)\n            logger.info(msg)\n\n\nclass DebugCommand(Command):\n    \"\"\"\n    Display debug information.\n    \"\"\"\n\n    usage = \"\"\"\n      %prog <options>\"\"\"\n    ignore_require_venv = True\n\n    def __init__(self, *args, **kw):\n        super(DebugCommand, self).__init__(*args, **kw)\n\n        cmd_opts = self.cmd_opts\n        cmdoptions.add_target_python_options(cmd_opts)\n        self.parser.insert_option_group(0, cmd_opts)\n\n    def run(self, options, args):\n        # type: (Values, List[Any]) -> int\n        logger.warning(\n            \"This command is only meant for debugging. \"\n            \"Do not use this with automation for parsing and getting these \"\n            \"details, since the output and options of this command may \"\n            \"change without notice.\"\n        )\n        show_value('pip version', get_pip_version())\n        show_value('sys.version', sys.version)\n        show_value('sys.executable', sys.executable)\n        show_value('sys.getdefaultencoding', sys.getdefaultencoding())\n        show_value('sys.getfilesystemencoding', sys.getfilesystemencoding())\n        show_value(\n            'locale.getpreferredencoding', locale.getpreferredencoding(),\n        )\n        show_value('sys.platform', sys.platform)\n        show_sys_implementation()\n\n        show_tags(options)\n\n        return SUCCESS\n", "path": "src/pip/_internal/commands/debug.py"}], "after_files": [{"content": "# The following comment should be removed at some point in the future.\n# mypy: disallow-untyped-defs=False\n\nfrom __future__ import absolute_import\n\nimport locale\nimport logging\nimport os\nimport sys\n\nfrom pip._vendor.certifi import where\n\nfrom pip._internal.cli import cmdoptions\nfrom pip._internal.cli.base_command import Command\nfrom pip._internal.cli.cmdoptions import make_target_python\nfrom pip._internal.cli.status_codes import SUCCESS\nfrom pip._internal.utils.logging import indent_log\nfrom pip._internal.utils.misc import get_pip_version\nfrom pip._internal.utils.typing import MYPY_CHECK_RUNNING\nfrom pip._internal.wheel import format_tag\n\nif MYPY_CHECK_RUNNING:\n    from typing import Any, List, Optional\n    from optparse import Values\n\nlogger = logging.getLogger(__name__)\n\n\ndef show_value(name, value):\n    # type: (str, Optional[str]) -> None\n    logger.info('{}: {}'.format(name, value))\n\n\ndef show_sys_implementation():\n    # type: () -> None\n    logger.info('sys.implementation:')\n    if hasattr(sys, 'implementation'):\n        implementation = sys.implementation  # type: ignore\n        implementation_name = implementation.name\n    else:\n        implementation_name = ''\n\n    with indent_log():\n        show_value('name', implementation_name)\n\n\ndef show_tags(options):\n    # type: (Values) -> None\n    tag_limit = 10\n\n    target_python = make_target_python(options)\n    tags = target_python.get_tags()\n\n    # Display the target options that were explicitly provided.\n    formatted_target = target_python.format_given()\n    suffix = ''\n    if formatted_target:\n        suffix = ' (target: {})'.format(formatted_target)\n\n    msg = 'Compatible tags: {}{}'.format(len(tags), suffix)\n    logger.info(msg)\n\n    if options.verbose < 1 and len(tags) > tag_limit:\n        tags_limited = True\n        tags = tags[:tag_limit]\n    else:\n        tags_limited = False\n\n    with indent_log():\n        for tag in tags:\n            logger.info(format_tag(tag))\n\n        if tags_limited:\n            msg = (\n                '...\\n'\n                '[First {tag_limit} tags shown. Pass --verbose to show all.]'\n            ).format(tag_limit=tag_limit)\n            logger.info(msg)\n\n\ndef ca_bundle_info(config):\n    levels = set()\n    for key, value in config.items():\n        levels.add(key.split('.')[0])\n\n    if not levels:\n        return \"Not specified\"\n\n    levels_that_override_global = ['install', 'wheel', 'download']\n    global_overriding_level = [\n        level for level in levels if level in levels_that_override_global\n    ]\n    if not global_overriding_level:\n        return 'global'\n\n    levels.remove('global')\n    return \", \".join(levels)\n\n\nclass DebugCommand(Command):\n    \"\"\"\n    Display debug information.\n    \"\"\"\n\n    usage = \"\"\"\n      %prog <options>\"\"\"\n    ignore_require_venv = True\n\n    def __init__(self, *args, **kw):\n        super(DebugCommand, self).__init__(*args, **kw)\n\n        cmd_opts = self.cmd_opts\n        cmdoptions.add_target_python_options(cmd_opts)\n        self.parser.insert_option_group(0, cmd_opts)\n        self.parser.config.load()\n\n    def run(self, options, args):\n        # type: (Values, List[Any]) -> int\n        logger.warning(\n            \"This command is only meant for debugging. \"\n            \"Do not use this with automation for parsing and getting these \"\n            \"details, since the output and options of this command may \"\n            \"change without notice.\"\n        )\n        show_value('pip version', get_pip_version())\n        show_value('sys.version', sys.version)\n        show_value('sys.executable', sys.executable)\n        show_value('sys.getdefaultencoding', sys.getdefaultencoding())\n        show_value('sys.getfilesystemencoding', sys.getfilesystemencoding())\n        show_value(\n            'locale.getpreferredencoding', locale.getpreferredencoding(),\n        )\n        show_value('sys.platform', sys.platform)\n        show_sys_implementation()\n\n        show_value(\"'cert' config value\", ca_bundle_info(self.parser.config))\n        show_value(\"REQUESTS_CA_BUNDLE\", os.environ.get('REQUESTS_CA_BUNDLE'))\n        show_value(\"CURL_CA_BUNDLE\", os.environ.get('CURL_CA_BUNDLE'))\n        show_value(\"pip._vendor.certifi.where()\", where())\n\n        show_tags(options)\n\n        return SUCCESS\n", "path": "src/pip/_internal/commands/debug.py"}]}