Repository: pypa/pip

Issue:
Location warning messages for MSYS2
cc @rupanshu1710 @stephan-cr @mitchellmebane

Opening a new one for this so the discussion doesn’t get drowned by reports for other platforms. I’ve set up MSYS2 but am confused a bit how I should proceed (having only limited experience with the platform). MSYS2 seems to be multiple Python packages. Do you know how those (e.g. `python` and `mingw-w64-python`) are different? Which one are you using?

https://github.com/pypa/pip/issues/10151#issuecomment-886185018
https://github.com/pypa/pip/issues/10151#issuecomment-888288679
https://github.com/pypa/pip/issues/10151#issuecomment-888647104


Discussion:
Hi @uranusjr!

> Do you know how those (e.g. python and mingw-w64-python) are different?

Most packages come in different flavors, see https://www.msys2.org/docs/environments/. They differ regarding CPU architecture, compiler/toolchain, C and C++ library being used.

> Which one are you using?

In my case I have `mingw64/mingw-w64-x86_64-python`.
Thanks for the information! I tried `pacman -S mingw-w64-x86_64-python`; it did not give a working `python` command, but I was able to locate the [package detail on MSYS2’s index](https://packages.msys2.org/package/mingw-w64-x86_64-python). Things work after I added `/mingw64/bin` to `PATH`.

So this seems like a distributor bug. MSYS2 patches `distutils` and `sysconfig` to provide a POSIX-like scheme (the default scheme would be something like `{prefix}/Lib/site-packages` on Windows). But their patch on `sysconfig` is incorrectly omitting the `site-packages` part. So the warning is correct, and we need MSYS2 to fix this.

I browsed around the site and it seems like MINGW package bugs should be reported to https://github.com/msys2/MINGW-packages. I’ll submit an entry there and see how things go. If any of ya’ll happen to know a better place to raise this issue, please tell me as well.
Now the issue is identified as a bug in MSYS2, there’s nothing more we can do. We should suppress the warning in 21.2.4.
I'm just curious - are we keeping a log anywhere (other than these issues), of where these distributor bugs have been reported? I imagine a time in the future when we finally switch to sysconfig at which point these warnings will become errors. At that point it would be useful to have somewhere a note that says "this issue was reported to the MSYS2 project in August 2021 as issue XXX" so that our users know where to go for a fix.
I'm keeping everything in the source code; each issue I've reported (but yet to be fixed) have a comment in `pip/_internal/locations/__init__.py` linking to an issue somewhere.

Resolving patch:
diff --git a/src/pip/_internal/locations/__init__.py b/src/pip/_internal/locations/__init__.py
--- a/src/pip/_internal/locations/__init__.py
+++ b/src/pip/_internal/locations/__init__.py
@@ -95,6 +95,24 @@ def _looks_like_red_hat_scheme() -> bool:
     )
 
 
+@functools.lru_cache(maxsize=None)
+def _looks_like_msys2_mingw_scheme() -> bool:
+    """MSYS2 patches distutils and sysconfig to use a UNIX-like scheme.
+
+    However, MSYS2 incorrectly patches sysconfig ``nt`` scheme. The fix is
+    likely going to be included in their 3.10 release, so we ignore the warning.
+    See msys2/MINGW-packages#9319.
+
+    MSYS2 MINGW's patch uses lowercase ``"lib"`` instead of the usual uppercase,
+    and is missing the final ``"site-packages"``.
+    """
+    paths = sysconfig.get_paths("nt", expand=False)
+    return all(
+        "Lib" not in p and "lib" in p and not p.endswith("site-packages")
+        for p in (paths[key] for key in ("platlib", "purelib"))
+    )
+
+
 def _fix_abiflags(parts: Tuple[str]) -> Iterator[str]:
     ldversion = sysconfig.get_config_var("LDVERSION")
     abiflags: str = getattr(sys, "abiflags", None)
@@ -239,6 +257,14 @@ def get_scheme(
         if skip_sysconfig_abiflag_bug:
             continue
 
+        # MSYS2 MINGW's sysconfig patch does not include the "site-packages"
+        # part of the path. This is incorrect and will be fixed in MSYS.
+        skip_msys2_mingw_bug = (
+            WINDOWS and k in ("platlib", "purelib") and _looks_like_msys2_mingw_scheme()
+        )
+        if skip_msys2_mingw_bug:
+            continue
+
         warning_contexts.append((old_v, new_v, f"scheme.{k}"))
 
     if not warning_contexts:


Test patch: