Repository: pypa/pip

Issue:
Location warning from incorrect Python patch from Slackware
Context: https://github.com/pypa/pip/issues/10151#issuecomment-965054308

```
WARNING: Value for scheme.purelib does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
distutils: /home/ali/.local/lib/python3.9/site-packages
sysconfig: /home/ali/.local/lib64/python3.9/site-packages
WARNING: Additional context:
user = True
home = None
root = None
prefix = None
```

> it is 'Slackware 15.0 x86_64' 
> I know that there is some docker image online but never used any. The source for the python3 package > could be downloaded from https://mirrors.slackware.com/slackware/slackware64-current/source/d/python3/
will it help if I give you access to a VM running slackware 15?
> PS: I gave python3-10 a try some weeks ago and pip is not usable without some manual setup.  

-----

Diagnosis:

Thanks a ton @alijkl!

I just verified—this is (arguably) a bug in Slackware’s CPython patch. It patches sysconfig like this:

```python
    'posix_user': {
        'stdlib': '{userbase}/{platlibdir}/python{py_version_short}',
        'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}',
        'purelib': '{userbase}/lib64/python{py_version_short}/site-packages',
        'platlib': '{userbase}/{platlibdir}/python{py_version_short}/site-packages',
        'include': '{userbase}/include/python{py_version_short}',
        'scripts': '{userbase}/bin',
        'data': '{userbase}',
        },
```

These are the corresponding lines in upstream CPython for comparison:

https://github.com/python/cpython/blob/v3.9.7/Lib/sysconfig.py#L69-L77

The difference is Slackware’s Python patches `purelib` to use `lib64` instead of `lib`. This is OK on its own, but Slackware needs to but did not also patch `site` to match this:

```
chung@darkstar:~$ python3 -m site
sys.path = [
    '/home/chung',
    '/usr/lib64/python39.zip',
    '/usr/lib64/python3.9',
    '/usr/lib64/python3.9/lib-dynload',
    '/home/chung/.local/lib/python3.9/site-packages',
    '/usr/lib64/python3.9/site-packages',
]
USER_BASE: '/home/chung/.local' (exists)
USER_SITE: '/home/chung/.local/lib/python3.9/site-packages' (exists)
ENABLE_USER_SITE: True
```

which causes the warning because pip correctly detects that packages installed to the incorrectly patches `sysconfig` locations will work (because the incorrect path is not in `USER_SITE` or `sys.path`). So Slackware should either patch `site`, or remove the `posix_user` patch in `sysconfig`. Fedora had a similar issue and chose to do the latter, see [bpo-44860](https://bugs.python.org/issue44860).

So the bottom line is Slackware should fix this bug. In the meantime though, I’ll submit a patch in pip to detect and slience the warning since there’s nothing pip can do in this situation.


Discussion:
p.s. Do you happen to know where Slackware hosts the development repository, in particular those distribution-specific patches?
Not sure. I've posted your reply on one of the Slackware forum:

https://www.linuxquestions.org/questions/slackware-14/warnings-in-pip-may-be-a-bug-in-cpython-package-build-patch-4175703858/

On 11/19/21 6:02 PM, Tzu-ping Chung wrote:
>
> p.s. Do you happen to know where Slackware hosts the development 
> repository, in particular those distribution-specific patches?
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub 
> <https://github.com/pypa/pip/issues/10668#issuecomment-974289115>, or 
> unsubscribe 
> <https://github.com/notifications/unsubscribe-auth/ALK52DILQAGKI33LVR3KVELUM2GKBANCNFSM5IMWJ4XA>.
> Triage notifications on the go with GitHub Mobile for iOS 
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675> 
> or Android 
> <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>. 
>
>
-- 
ALI



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
@@ -130,6 +130,22 @@ def _looks_like_red_hat_scheme() -> bool:
     )
 
 
+@functools.lru_cache(maxsize=None)
+def _looks_like_slackware_scheme() -> bool:
+    """Slackware patches sysconfig but fails to patch distutils and site.
+
+    Slackware changes sysconfig's user scheme to use ``"lib64"`` for the lib
+    path, but does not do the same to the site module.
+    """
+    if user_site is None:  # User-site not available.
+        return False
+    try:
+        paths = sysconfig.get_paths(scheme="posix_user", expand=False)
+    except KeyError:  # User-site not available.
+        return False
+    return "/lib64/" in paths["purelib"] and "/lib64/" not in user_site
+
+
 @functools.lru_cache(maxsize=None)
 def _looks_like_msys2_mingw_scheme() -> bool:
     """MSYS2 patches distutils and sysconfig to use a UNIX-like scheme.
@@ -285,6 +301,17 @@ def get_scheme(
         if skip_bpo_44860:
             continue
 
+        # Slackware incorrectly patches posix_user to use lib64 instead of lib,
+        # but not usersite to match the location.
+        skip_slackware_user_scheme = (
+            user
+            and k in ("platlib", "purelib")
+            and not WINDOWS
+            and _looks_like_slackware_scheme()
+        )
+        if skip_slackware_user_scheme:
+            continue
+
         # Both Debian and Red Hat patch Python to place the system site under
         # /usr/local instead of /usr. Debian also places lib in dist-packages
         # instead of site-packages, but the /usr/local check should cover it.


Test patch: