pyenv-virtualenv for Windows 1.2
A 'pyenv' plugin to manage Python virtual environments, depending on different Python versions, for various Python projects.
Loading...
Searching...
No Matches
pyenv-virtualenv-prefix.py
Go to the documentation of this file.
1##
2# @package pyenv-virtualenv-prefix
3# @file pyenv-virtualenv-prefix.py
4# @author Michael Paul Korthals
5# @date 2025-07-10
6# @version 1.0.0
7# @copyright © 2025 Michael Paul Korthals. All rights reserved.
8# See License details in the documentation.
9#
10# Utility application to output the virtual environment path prefix.
11#
12
13# --- IMPORTS ----------------------------------------------------------
14
15# Python
16import argparse
17import os
18import sys
19
20# Avoid colored output problems
21os.system('')
22
23# Community
24try:
25 import virtualenv
26except ImportError():
27 print(
28 '\x1b[101mCRITICAL %s\x1b[0m'
29 %
30 'Cannot find package "%s".'
31 %
32 'virtualenv'
33 )
34 print(
35 '\x1b[37mINFO %s\x1b[0m'
36 %
37 'Install it using "pip". Then try again.')
38 import virtualenv
39
40# My
41import lib.hlp as hlp
42import lib.log as log
43
44
45# --- RUN ---------------------------------------------------------------
46
47## Sub routine to run the application.
48#
49# @param args Given command line arguments.
50# @return RC = 0 or other values in case of error.
51def run(args: argparse.Namespace) -> int:
52 rc: int = 0
53 # noinspection PyBroadException
54 try:
55 while True:
57 'Display "real_prefix" for a Python virtual environment version.'
58 )
59 try:
60 # Use the given "version" argument
61 version: str = args.name
62 name_given = True
63 except AttributeError:
64 name_given = False
65 if name_given:
66 result = ''
67 filtered_envs = hlp.getAllEnvs(
68 args.name,
69 as_paths=True
70 )
71 if len(filtered_envs) > 0:
72 for env in filtered_envs:
73 pl = env.split(os.sep)
74 for i in range(len(pl)):
75 item = pl[i]
76 if item == 'versions':
77 if len(result) > 0:
78 result += '\r\n'
79 result += os.sep.join(pl[:i + 2])
80 print(result)
81 else:
82 log.warning(f'Cannot find virtual environments like "{args.name}".')
83 log.info('Try again with another filter by name. Wildcards are implemented.')
84 else:
85 # Check if the path to Python executable
86 # passes into a virtual environment.
87 log.debug(f'Python executable: "{sys.executable}".')
88 pl = sys.executable.split(os.sep)
89 if (
90 ('envs' in pl)
91 and
92 ('Scripts' in pl)
93 and
94 (os.path.isfile(
95 os.path.join(
96 os.path.dirname(sys.executable),
97 '..',
98 'pyvenv.cfg'
99 )
100 ))
101 ):
102 # Virtual environment detected
103 result = ''
104 for i in range(len(pl)):
105 item = pl[i]
106 if item == 'versions':
107 result = os.sep.join(pl[:i + 2])
108 break
109 if result == '':
110 log.error('Cannot determine Python version for this virtual environment.')
111 rc = 1
112 break
113 print(result)
114 else:
115 # Not in virtual environment
116 version = sys.version.split(' ')[0]
117 log.warning(f'"pyenv-virtualenv": Version`{version}` is not a virtual environment.')
118 rc = 5
119 break
120 # End if
121 # Go on
122 break
123 # End while
124 except:
125 log.error(sys.exc_info())
126 rc = 1
127 return rc
128
129
130# --- MAIN --------------------------------------------------------------
131
132## Parse CLI arguments for this application.<br>
133# <br>
134# Implement this as required, but don't touch the interface definition
135# for input and output.
136#
137# @return A tuple of:
138# * Namespace to read arguments in "dot" notation or None
139# in case of help or error.
140# * RC = 0 or another value in case of error.
141def parseCliArguments0() -> tuple[(argparse.Namespace, None), int]:
142 rc: int = 0
143 # noinspection PyBroadException
144 try:
145 parser = argparse.ArgumentParser(
146# --- BEGIN CHANGE -----------------------------------------------------
147 prog='pyenv virtualenv-prefix',
148 description='Display "real_prefix" for a Python virtual environment version.'
149 )
150# --- END CHANGE -------------------------------------------------------
151 return parser.parse_args(), rc
152 except SystemExit:
153 return None, 0
154 except:
155 log.error(sys.exc_info())
156 return None, 1
157
158## Parse CLI arguments for this application.<br>
159# <br>
160# Implement this as required, but don't touch the interface definition
161# for input and output.
162#
163# @return A tuple of:
164# * Namespace to read arguments in "dot" notation or None
165# in case of help or error.
166# * RC = 0 or another value in case of error.
167def parseCliArguments1() -> tuple[(argparse.Namespace, None), int]:
168 rc: int = 0
169 # noinspection PyBroadException
170 try:
171 parser = argparse.ArgumentParser(
172# --- BEGIN CHANGE -----------------------------------------------------
173 prog='pyenv virtualenv-prefix',
174 description='Display "real_prefix" for a Python virtual environment version.'
175 )
176 # Add positional str argument
177 parser.add_argument(
178 'name',
179 help='Short name of an installed Python virtual environment. Default: Empty string = analyze the CWD.'
180 )
181# --- END CHANGE -------------------------------------------------------
182 return parser.parse_args(), rc
183 except SystemExit:
184 return None, 0
185 except:
186 log.error(sys.exc_info())
187 return None, 1
188
189## Main routine of the application.
190#
191# @return RC = 0 or other values in case of error.
192def main() -> int:
193 # noinspection PyBroadException
194 try:
195 while True:
196 # Audit the operating system platform
197 rc = hlp.auditPlatform('Windows')
198 if rc != 0:
199 # Deviation: Reject unsupported platform
200 break
201 # Audit the global Python version number
203 if rc != 0:
204 # Deviation: Reject unsupported Python version
205 break
206 # Initialize the colored logging to console
208 # Audit the "pyenv" version number
209 rc = hlp.auditPyEnv('3')
210 if rc != 0:
211 # Deviation: Reject unsupported "pyenv" version
212 break
213 # Parse arguments
214 # NOTE: Sorry, this is a complicated workaround to
215 # bypass the lack of applicability of Python "ArgumentParser"
216 # class. This simple use case to set required = False for
217 # positional argument is not included and must be patched
218 # away here.
219 log.verbose('Parsing arguments ...')
220 args = None
221 args_list = sys.argv.copy() # Clone
222 # Strip program executable path
223 args_list.pop(0)
224 # Detect and remove all optional arguments,
225 # which are not related to the positional arguments
226 help_requested = False
227 for i in reversed(range(len(args_list))):
228 arg = args_list[i]
229 if arg in ['-h', '--help']:
230 help_requested = True
231 args_list.pop(i)
232 # Calculate the count of positional arguments
233 positional_count = len(args_list)
234 if (
235 help_requested
236 or
237 (positional_count not in [0, 1])
238 ):
239 text = ("""
240Usage: pyenv virtualenv-prefix [-h] [name]
241
242Display "real_prefix" for a Python virtual environment version.
243
244Positional arguments (can be omitted):
245 [name] Short name of an installed Python virtual environment.
246 Default: Empty string = analyze the CWD.
247Options:
248 -h, --help Show this help message and exit
249 """).strip()
250 print(text)
251 elif positional_count == 0:
252 # Case 1: single positional argument must be "Name"
253 args, rc = parseCliArguments0()
254 elif positional_count == 1:
255 # Case 2: duo positional arguments must be "Version" and "Name"
256 args, rc = parseCliArguments1()
257 if rc != 0:
258 break
259 if args is None: # -h, --help
260 break
261 # Run this application
262 log.verbose('Running application ...')
263 rc = run(args)
264 if rc != 0:
265 break
266 # Go on
267 break
268 # End while
269 except Exception as exc:
271 log.error(sys.exc_info())
272 else:
273 print(
274 '\x1b[91mERROR: Unexpected error "%s".\x1b[0m'
275 %
276 str(exc)
277 )
278 rc = 1
279 return rc
280
281
282if __name__ == "__main__":
283 sys.exit(main())
284
285# --- END OF CODE ------------------------------------------------------
286
int auditPyEnv(str min_ver)
Check if "pyenv" version is greater or equal the given minimal version.
Definition hlp.py:213
int auditGlobalPythonVersion(str min_ver)
Check if Python version is greater or equal the given minimal version.
Definition hlp.py:148
int auditPlatform(str name)
Check if the program in running on the required platform.
Definition hlp.py:85
list[str] getAllEnvs(str name=' *', bool as_paths=False)
Get list of installed virtual environments for a specific Python version in "pyenv".
Definition hlp.py:768
debug((str, tuple) msg)
Log debug message colored to console only.
Definition log.py:215
warning((str, tuple) msg)
Log warning message colored to console only.
Definition log.py:191
verbose((str, tuple) msg)
Log verbose message colored to console only.
Definition log.py:209
initLogging()
Initialize the logging.
Definition log.py:71
bool isInitialized()
Definition log.py:90
info((str, tuple) msg)
Log info message colored to console only.
Definition log.py:203
error((str, tuple) msg)
Log error message colored to console only.
Definition log.py:179
int run(argparse.Namespace args)
Sub routine to run the application.
tuple[(argparse.Namespace, None), int] parseCliArguments1()
Parse CLI arguments for this application.
int main()
Main routine of the application.
tuple[(argparse.Namespace, None), int] parseCliArguments0()
Parse CLI arguments for this application.