Patch sys with all site scrubbed.
(self)
| 467 | # Thar be dragons -- when this function exits, the interpreter is potentially in a wonky state |
| 468 | # since the patches here (minimum_sys_modules for example) actually mutate global state. |
| 469 | def patch_sys(self): |
| 470 | # type: () -> None |
| 471 | """Patch sys with all site scrubbed.""" |
| 472 | inherit_path = self._vars.PEX_INHERIT_PATH |
| 473 | if inherit_path == InheritPath.FALSE: |
| 474 | inherit_path = self._pex_info.inherit_path |
| 475 | |
| 476 | def patch_dict(old_value, new_value): |
| 477 | # type: (Dict[_K, _V], Mapping[_K, _V]) -> None |
| 478 | old_value.clear() |
| 479 | old_value.update(new_value) |
| 480 | |
| 481 | def patch_all(path, path_importer_cache, modules): |
| 482 | # type: (List[str], Mapping[str, Any], Mapping[str, ModuleType]) -> None |
| 483 | sys.path[:] = path |
| 484 | patch_dict(sys.path_importer_cache, path_importer_cache) |
| 485 | patch_dict(sys.modules, modules) |
| 486 | |
| 487 | # N.B.: These hooks may contain custom code set via site.py or `.pth` files that we've |
| 488 | # just scrubbed. Reset them to factory defaults to avoid scrubbed code. |
| 489 | sys.displayhook = sys.__displayhook__ |
| 490 | sys.excepthook = sys.__excepthook__ # type: ignore[assignment] # Builtin typeshed bug. |
| 491 | |
| 492 | new_sys_path, new_sys_path_importer_cache, new_sys_modules = self.minimum_sys(inherit_path) |
| 493 | |
| 494 | if self._vars.PEX_EXTRA_SYS_PATH: |
| 495 | TRACER.log( |
| 496 | "Adding {} to sys.path".format(os.pathsep.join(self._vars.PEX_EXTRA_SYS_PATH)) |
| 497 | ) |
| 498 | extra_sys_path = self._vars.PEX_EXTRA_SYS_PATH |
| 499 | new_sys_path.extend(extra_sys_path) |
| 500 | |
| 501 | # Let Python subprocesses see the same sys.path additions we see. If those Python |
| 502 | # subprocesses are PEX subprocesses, they'll do their own (re-)scrubbing as needed. |
| 503 | if inherit_path is InheritPath.FALSE: |
| 504 | pythonpath_entries = extra_sys_path |
| 505 | else: |
| 506 | raw_pythonpath = os.environ.get(self._PYTHONPATH) |
| 507 | pythonpath = tuple(raw_pythonpath.split(os.pathsep)) if raw_pythonpath else () |
| 508 | pythonpath_entries = pythonpath + extra_sys_path |
| 509 | os.environ[self._PYTHONPATH] = os.pathsep.join(pythonpath_entries) |
| 510 | |
| 511 | TRACER.log("New sys.path: {}".format(new_sys_path)) |
| 512 | |
| 513 | patch_all(new_sys_path, new_sys_path_importer_cache, new_sys_modules) |
| 514 | |
| 515 | def _wrap_coverage(self, runner, *args): |
| 516 | if not self._vars.PEX_COVERAGE and self._vars.PEX_COVERAGE_FILENAME is None: |