MCPcopy Create free account
hub / github.com/aaPanel/BaoTa / VirtualEnvDetector

Class VirtualEnvDetector

mod/project/python/pyenv_tool.py:763–905  ·  view source on GitHub ↗

虚拟环境检测器(支持venv/virtualenv)

Source from the content-addressed store, hash-verified

761
762
763class VirtualEnvDetector(_EnvironmentDetector):
764 """虚拟环境检测器(支持venv/virtualenv)"""
765 ENV_MARKERS = ["pyvenv.cfg", "bin/activate"]
766 NAME_REGEXPS = [
767 re.compile(r'''!=\s*x\s*]\s*;\s*then\s*VIRTUAL_ENV_PROMPT=['"]?(?P<name>[^'"\s]+)['"]?\n'''),
768 re.compile(r'''_OLD_VIRTUAL_PS1="\$\{PS1:-}"\s+PS1=['"\s]*\(['"\s]*(?P<name>.*)['"\s]*\)['"\s]*\$\{PS1:-}"''&#x27;),
769 re.compile(r'''VIRTUAL_ENV=["']?(/.*)/(?P<name>\S*)["']?\n'''),
770 ]
771
772 def __init__(self, search_dirs: List[str]):
773 self.search_dirs = search_dirs
774
775 def detect(self) -> List[PythonEnvironment]:
776 envs = []
777 max_depth = 2
778 find_bin_path = set()
779 for base_dir in self.search_dirs:
780 expanded_dir = os.path.expanduser(base_dir)
781 if not os.path.exists(expanded_dir):
782 continue
783
784 for root, dirs, _ in os.walk(expanded_dir, topdown=True):
785 # 避免过多搜索子目录
786 if root.replace(expanded_dir, "").count(os.sep) >= max_depth:
787 dirs.clear()
788 continue
789
790 for tmp_dir in dirs:
791 if all(Path(root) / tmp_dir / marker for marker in self.ENV_MARKERS):
792 bin_path = "{}/bin/python".format(root)
793 if not os.path.exists(bin_path) or not os.access(bin_path, os.X_OK):
794 bin_path = "{}/bin/python3".format(root)
795 if not os.path.exists(bin_path) or not os.access(bin_path, os.X_OK):
796 continue
797 if bin_path in find_bin_path:
798 continue
799 data = self.get_env_info(root)
800 if not data:
801 continue
802 site_packages = self.get_site_packages(bin_path)
803 if not site_packages:
804 continue
805 find_bin_path.add(bin_path)
806 pe = PythonEnvironment(bin_path, data[1], "venv")
807 pe.activate_sh = "source {}/bin/activate".format(root)
808 pe.system_path = data[0]
809 pe.venv_name = data[2]
810 pe.site_packages = site_packages
811 envs.append(pe)
812 return envs
813
814 @classmethod
815 def get_env_info(cls, path: str) -> Optional[Tuple[str, str, str]]:
816 cfg_file = Path(path) / "pyvenv.cfg"
817 atv_file = Path(path) / "bin" / "activate"
818 if not cfg_file.exists():
819 return None
820

Callers 1

__init__Method · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected