(cls, binary=None)
| 244 | |
| 245 | @classmethod |
| 246 | def get(cls, binary=None): |
| 247 | # type: (Optional[str]) -> PythonIdentity |
| 248 | |
| 249 | # N.B.: We should not need to look past `sys.executable` to learn the current interpreter's |
| 250 | # executable path, but on OSX there has been a bug where the `sys.executable` reported is |
| 251 | # _not_ the path of the current interpreter executable: |
| 252 | # https://bugs.python.org/issue22490#msg283859 |
| 253 | # That case is distinguished by the presence of a `__PYVENV_LAUNCHER__` environment |
| 254 | # variable as detailed in the Python bug linked above. |
| 255 | if binary and binary != sys.executable and "__PYVENV_LAUNCHER__" not in os.environ: |
| 256 | # Here we assume sys.executable is accurate and binary is something like a pyenv shim. |
| 257 | binary = sys.executable |
| 258 | |
| 259 | supported_tags = tuple(tags.sys_tags()) |
| 260 | preferred_tag = supported_tags[0] |
| 261 | |
| 262 | sys_config_vars = sysconfig.get_config_vars() |
| 263 | |
| 264 | configured_macosx_deployment_target = cls._normalize_macosx_deployment_target( |
| 265 | sys_config_vars.get("MACOSX_DEPLOYMENT_TARGET") |
| 266 | ) |
| 267 | |
| 268 | pypy_version = cast( |
| 269 | "Optional[Tuple[int, int, int]]", |
| 270 | tuple(getattr(sys, "pypy_version_info", ())[:3]) or None, |
| 271 | ) |
| 272 | if pypy_version is None: |
| 273 | free_threaded = ( |
| 274 | sys.version_info[:2] >= (3, 13) and sys_config_vars.get("Py_GIL_DISABLED", 0) == 1 |
| 275 | ) # type: Optional[bool] |
| 276 | else: |
| 277 | free_threaded = None |
| 278 | |
| 279 | # Pex identifies interpreters using a bit of Pex code injected via an extraction of that |
| 280 | # code under the `PEX_ROOT` adjoined to `sys.path` via `PYTHONPATH`. Pex also exposes the |
| 281 | # vendored attrs distribution so that its `cache_hash=True` feature can work (see the |
| 282 | # bottom of pex/third_party/__init__.py where the vendor importer is installed). We ignore |
| 283 | # such adjoined `sys.path` entries to discover the true base interpreter `sys.path`. |
| 284 | pythonpath = os.environ.get("PYTHONPATH") |
| 285 | internal_entries = frozenset( |
| 286 | (pythonpath.split(os.pathsep) if pythonpath else []) + list(third_party.exposed()) |
| 287 | ) |
| 288 | sys_path = OrderedSet( |
| 289 | entry for entry in sys.path if entry and entry not in internal_entries |
| 290 | ) |
| 291 | |
| 292 | site_packages = OrderedSet( |
| 293 | site_packages_dir |
| 294 | for site_packages_dir in cls._site_packages_dirs() |
| 295 | # On Windows getsitepackages() includes sys.prefix as a historical vestige. In PEP-250 |
| 296 | # Windows got a proper dedicated directory for this which is what is used in the Pythons |
| 297 | # we support. See: https://peps.python.org/pep-0250/ |
| 298 | if site_packages_dir.path != sys.prefix |
| 299 | ) |
| 300 | |
| 301 | extras_paths = OrderedSet(cls._iter_extras_paths(site_packages=site_packages)) |
| 302 | |
| 303 | return cls( |
no test coverage detected