Skip to content

Commit 5fd620c

Browse files
jurko-gospodneticgaborbernat
authored andcommitted
update detecting Windows Python installations
- now correctly detects current user installation and not just those installed at the system level - for Python versions 3.5+ (which track 32-bit & 64-bit installations separately), recognize version tags X.Y, X.Y-32 & X.Y-64 where X.Y represents the 64-bit installation if available or 32-bit otherwise
1 parent af5711c commit 5fd620c

File tree

1 file changed

+38
-20
lines changed

1 file changed

+38
-20
lines changed

src/virtualenv.py

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -85,33 +85,51 @@ def get_installed_pythons():
8585
import _winreg as winreg
8686

8787
def get_installed_pythons():
88-
try:
89-
python_core = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE,
90-
"Software\\Python\\PythonCore")
91-
except WindowsError:
92-
# No registered Python installations
93-
return {}
94-
i = 0
95-
versions = []
96-
while True:
97-
try:
98-
versions.append(winreg.EnumKey(python_core, i))
99-
i = i + 1
100-
except WindowsError:
101-
break
10288
exes = dict()
103-
for ver in versions:
89+
# If both system and current user installations are found for a
90+
# particular Python version, the current user one is used
91+
for key in (winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER):
10492
try:
105-
path = winreg.QueryValue(python_core, "%s\\InstallPath" % ver)
93+
python_core = winreg.CreateKey(key,
94+
"Software\\Python\\PythonCore")
10695
except WindowsError:
96+
# No registered Python installations
10797
continue
108-
exes[ver] = join(path, "python.exe")
109-
110-
winreg.CloseKey(python_core)
98+
i = 0
99+
while True:
100+
try:
101+
version = winreg.EnumKey(python_core, i)
102+
i += 1
103+
try:
104+
path = winreg.QueryValue(python_core,
105+
"%s\\InstallPath" % version)
106+
except WindowsError:
107+
continue
108+
exes[version] = join(path, "python.exe")
109+
except WindowsError:
110+
break
111+
winreg.CloseKey(python_core)
112+
113+
# For versions that track separate 32-bit (`X.Y-32`) & 64-bit (`X-Y`)
114+
# installation registrations, add a `X.Y-64` version tag and make the
115+
# extensionless `X.Y` version tag represent the 64-bit installation if
116+
# available or 32-bit if it is not
117+
updated = {}
118+
for ver in exes:
119+
if ver < '3.5':
120+
continue
121+
if ver.endswith('-32'):
122+
base_ver = ver[:-3]
123+
if base_ver not in exes:
124+
updated[base_ver] = exes[ver]
125+
else:
126+
updated[ver + '-64'] = exes[ver]
127+
exes.update(updated)
111128

112129
# Add the major versions
113130
# Sort the keys, then repeatedly update the major version entry
114-
# Last executable (i.e., highest version) wins with this approach
131+
# Last executable (i.e., highest version) wins with this approach,
132+
# 64-bit over 32-bit if both are found
115133
for ver in sorted(exes):
116134
exes[ver[0]] = exes[ver]
117135

0 commit comments

Comments
 (0)