Repository: pypa/pip

Issue:
Disable upgrade prompt on `EXTERNALLY-MANAGED` environments
### Description

It's slightly odd that pip recommends running a pip install --upgrade pip that cannot succeed under EXTERNALLY-MANAGED environments

### Expected behavior

_No response_

### pip version

23.0.1

### Python version

3.11

### OS

Debian

### How to Reproduce

N/A

### Output

_No response_

### Code of Conduct

- [x] I agree to follow the [PSF Code of Conduct](https://www.python.org/psf/conduct/).

Discussion:

Patch:
diff --git a/news/11820.bugfix.rst b/news/11820.bugfix.rst
new file mode 100644
index 000000000..68b23ef11
--- /dev/null
+++ b/news/11820.bugfix.rst
@@ -0,0 +1,1 @@
+The pip version self check is disabled on ``EXTERNALLY-MANAGED`` environments.
diff --git a/src/pip/_internal/self_outdated_check.py b/src/pip/_internal/self_outdated_check.py
index f9a91af9d..2e0e3df35 100644
--- a/src/pip/_internal/self_outdated_check.py
+++ b/src/pip/_internal/self_outdated_check.py
@@ -26,7 +26,11 @@ from pip._internal.utils.entrypoints import (
     get_best_invocation_for_this_python,
 )
 from pip._internal.utils.filesystem import adjacent_tmp_file, check_path_owner, replace
-from pip._internal.utils.misc import ensure_dir
+from pip._internal.utils.misc import (
+    ExternallyManagedEnvironment,
+    check_externally_managed,
+    ensure_dir,
+)
 
 _WEEK = datetime.timedelta(days=7)
 
@@ -231,6 +235,10 @@ def pip_self_version_check(session: PipSession, options: optparse.Values) -> Non
     installed_dist = get_default_environment().get_distribution("pip")
     if not installed_dist:
         return
+    try:
+        check_externally_managed()
+    except ExternallyManagedEnvironment:
+        return
 
     upgrade_prompt = _self_version_check_logic(
         state=SelfCheckState(cache_dir=options.cache_dir),


Test patch:
diff --git a/tests/unit/test_self_check_outdated.py b/tests/unit/test_self_check_outdated.py
index 38ce648a0..a5310ca7b 100644
--- a/tests/unit/test_self_check_outdated.py
+++ b/tests/unit/test_self_check_outdated.py
@@ -14,6 +14,8 @@ from freezegun import freeze_time
 from pip._vendor.packaging.version import Version
 
 from pip._internal import self_outdated_check
+from pip._internal.self_outdated_check import UpgradePrompt, pip_self_version_check
+from pip._internal.utils.misc import ExternallyManagedEnvironment
 
 
 @pytest.mark.parametrize(
@@ -185,3 +187,15 @@ class TestSelfCheckState:
             "last_check": "2000-01-01T00:00:00+00:00",
             "pypi_version": "1.0.0",
         }
+
+
+@patch("pip._internal.self_outdated_check._self_version_check_logic")
+def test_suppressed_by_externally_managed(mocked_function: Mock, tmpdir: Path) -> None:
+    mocked_function.return_value = UpgradePrompt(old="1.0", new="2.0")
+    fake_options = Values({"cache_dir": str(tmpdir)})
+    with patch(
+        "pip._internal.self_outdated_check.check_externally_managed",
+        side_effect=ExternallyManagedEnvironment("nope"),
+    ):
+        pip_self_version_check(session=Mock(), options=fake_options)
+    mocked_function.assert_not_called()