| 814 | |
| 815 | |
| 816 | class PythonInterpreter(object): |
| 817 | _REGEX = re.compile( |
| 818 | r""" |
| 819 | ^ |
| 820 | (?: |
| 821 | python | |
| 822 | pypy |
| 823 | ) |
| 824 | (?: |
| 825 | # Major version |
| 826 | [2-9] |
| 827 | (?:. |
| 828 | # Minor version |
| 829 | [0-9]+ |
| 830 | # Some distributions include a suffix on the interpreter name, similar to |
| 831 | # PEP-3149. For example, Gentoo has /usr/bin/python3.6m to indicate it was |
| 832 | # built with pymalloc |
| 833 | [a-z]? |
| 834 | )? |
| 835 | )? |
| 836 | {extension} |
| 837 | $ |
| 838 | """.format( |
| 839 | extension=re.escape(EXE_EXTENSION) |
| 840 | ), |
| 841 | # NB: OSX ships python binaries named Python with a capital-P; so we allow for this as well |
| 842 | # as accommodating Windows which has DOS case insensitivity. |
| 843 | flags=re.IGNORECASE | re.VERBOSE, |
| 844 | ) |
| 845 | |
| 846 | _PYTHON_INTERPRETER_BY_NORMALIZED_PATH = {} # type: Dict |
| 847 | |
| 848 | @classmethod |
| 849 | @contextmanager |
| 850 | def _cleared_memory_cache(cls): |
| 851 | # type: () -> Iterator[None] |
| 852 | # Intended for test use. |
| 853 | |
| 854 | _cache = cls._PYTHON_INTERPRETER_BY_NORMALIZED_PATH.copy() |
| 855 | cls._PYTHON_INTERPRETER_BY_NORMALIZED_PATH = {} |
| 856 | try: |
| 857 | yield |
| 858 | finally: |
| 859 | cls._PYTHON_INTERPRETER_BY_NORMALIZED_PATH = _cache |
| 860 | |
| 861 | @classmethod |
| 862 | def _resolve_pyvenv_canonical_python_binary( |
| 863 | cls, |
| 864 | maybe_venv_python_binary, # type: str |
| 865 | ): |
| 866 | # type: (...) -> Optional[str] |
| 867 | maybe_venv_python_binary = os.path.abspath(maybe_venv_python_binary) |
| 868 | if not os.path.islink(maybe_venv_python_binary): |
| 869 | return None |
| 870 | |
| 871 | pyvenv_cfg = PyVenvCfg.find(maybe_venv_python_binary) |
| 872 | if pyvenv_cfg is None: |
| 873 | return None |