|
41 | 41 | _MISMATCH_LEVEL = logging.WARNING
|
42 | 42 |
|
43 | 43 |
|
| 44 | +@functools.lru_cache(maxsize=None) |
| 45 | +def _looks_like_red_hat_patched() -> bool: |
| 46 | + """Red Hat patches platlib in unix_prefix and unix_home, but not purelib. |
| 47 | +
|
| 48 | + This is the only way I can see to tell a Red Hat-patched Python. |
| 49 | + """ |
| 50 | + from distutils.command.install import INSTALL_SCHEMES as SCHEMES |
| 51 | + |
| 52 | + return ( |
| 53 | + k in SCHEMES |
| 54 | + and "lib64" in SCHEMES[k]["platlib"] |
| 55 | + and SCHEMES[k]["platlib"].replace("lib64", "lib") == SCHEMES[k]["purelib"] |
| 56 | + for k in ("unix_prefix", "unix_home") |
| 57 | + ) |
| 58 | + |
| 59 | + |
| 60 | +@functools.lru_cache(maxsize=None) |
| 61 | +def _looks_like_debian_patched() -> bool: |
| 62 | + """Debian adds two additional schemes.""" |
| 63 | + from distutils.command.install import INSTALL_SCHEMES |
| 64 | + |
| 65 | + return "deb_system" in INSTALL_SCHEMES and "unix_local" in INSTALL_SCHEMES |
| 66 | + |
| 67 | + |
44 | 68 | def _default_base(*, user: bool) -> str:
|
45 | 69 | if user:
|
46 | 70 | base = sysconfig.get_config_var("userbase")
|
@@ -143,6 +167,24 @@ def get_scheme(
|
143 | 167 | if skip_osx_framework_user_special_case:
|
144 | 168 | continue
|
145 | 169 |
|
| 170 | + # On Red Hat and derived Linux distributions, distutils is patched to |
| 171 | + # use "lib64" instead of "lib" for platlib. |
| 172 | + if k == "platlib" and _looks_like_red_hat_patched(): |
| 173 | + continue |
| 174 | + |
| 175 | + # Both Debian and Red Hat patch Python to place the system site under |
| 176 | + # /usr/local instead of /usr. Debian also places lib in dist-packages |
| 177 | + # instead of site-packages, but the /usr/local check should cover it. |
| 178 | + skip_linux_system_special_case = ( |
| 179 | + not (user or home or prefix) |
| 180 | + and old_v.parts[1:3] == ("user", "local") |
| 181 | + and new_v.parts[1] == "usr" |
| 182 | + and new_v.parts[2] != "local" |
| 183 | + and (_looks_like_red_hat_patched() or _looks_like_debian_patched()) |
| 184 | + ) |
| 185 | + if skip_linux_system_special_case: |
| 186 | + continue |
| 187 | + |
146 | 188 | warned.append(_warn_if_mismatch(old_v, new_v, key=f"scheme.{k}"))
|
147 | 189 |
|
148 | 190 | if any(warned):
|
|
0 commit comments