Sun Position: Fix crash when Blender was started in background
[blender-addons.git] / mesh_tissue / utils_pip.py
blob1ef72d098f4a3c64d45fd1f542a5a9c37af845eb
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # ----------------------------------------------------------
4 # Author: Stephen Leger (s-leger)
6 # ----------------------------------------------------------
7 import bpy
8 import subprocess
9 import sys
12 PYPATH = sys.executable #bpy.app.binary_path_python
15 class Pip:
17 def __init__(self):
18 self._ensurepip()
20 @staticmethod
21 def _ensure_user_site_package():
22 import os
23 import site
24 import sys
25 site_package = site.getusersitepackages()
26 if not os.path.exists(site_package):
27 site_package = bpy.utils.user_resource('SCRIPTS', "site_package", create=True)
28 site.addsitedir(site_package)
29 if site_package not in sys.path:
30 sys.path.append(site_package)
31 '''
32 @staticmethod
33 def _ensure_user_site_package():
34 import os
35 import site
36 import sys
37 site_package = site.getusersitepackages()
38 if os.path.exists(site_package):
39 if site_package not in sys.path:
40 sys.path.append(site_package)
41 else:
42 site_package = bpy.utils.user_resource('SCRIPTS', "site_package", create=True)
43 site.addsitedir(site_package)
44 '''
45 def _cmd(self, action, options, module):
46 if options is not None and "--user" in options:
47 self._ensure_user_site_package()
49 cmd = [PYPATH, "-m", "pip", action]
51 if options is not None:
52 cmd.extend(options.split(" "))
54 cmd.append(module)
55 return self._run(cmd)
57 def _popen(self, cmd):
58 popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
59 for stdout_line in iter(popen.stdout.readline, ""):
60 yield stdout_line
61 popen.stdout.close()
62 popen.wait()
64 def _run(self, cmd):
65 res = False
66 status = ""
67 for line in self._popen(cmd):
68 if "ERROR:" in line:
69 status = line.strip()
70 if "Error:" in line:
71 status = line.strip()
72 print(line)
73 if "Successfully" in line:
74 status = line.strip()
75 res = True
76 return res, status
78 def _ensurepip(self):
79 pip_not_found = False
80 try:
81 import pip
82 except ImportError:
83 pip_not_found = True
84 pass
85 if pip_not_found:
86 self._run([PYPATH, "-m", "ensurepip", "--default-pip"])
88 @staticmethod
89 def upgrade_pip():
90 return Pip()._cmd("install", "--upgrade", "pip")
92 @staticmethod
93 def uninstall(module, options=None):
94 """
95 :param module: string module name with requirements see:[1]
96 :param options: string command line options see:[2]
97 :return: True on uninstall, False if already removed, raise on Error
98 [1] https://pip.pypa.io/en/stable/reference/pip_install/#id29
99 [2] https://pip.pypa.io/en/stable/reference/pip_install/#id47
101 if options is None or options.strip() == "":
102 # force confirm
103 options = "-y"
104 return Pip()._cmd("uninstall", options, module)
106 @staticmethod
107 def install(module, options=None):
109 :param module: string module name with requirements see:[1]
110 :param options: string command line options see:[2]
111 :return: True on install, False if already there, raise on Error
112 [1] https://pip.pypa.io/en/stable/reference/pip_install/#id29
113 [2] https://pip.pypa.io/en/stable/reference/pip_install/#id47
115 if options is None or options.strip() == "":
116 # store in user writable directory, use wheel, without deps
117 options = "--user --only-binary all --no-deps"
118 return Pip()._cmd("install", options, module)
120 @staticmethod
121 def blender_version():
123 :return: blender version tuple
125 return bpy.app.version
127 @staticmethod
128 def python_version():
130 :return: python version object
132 import sys
133 # version.major, version.minor, version.micro
134 return sys.version_info