I'm running multiple installs of Python on Windows Server 2012. I can probably find a way to work around this, but I'm curious as to what is going on. I'm wary about radically changing the installs in case I break other people's Python scheduled tasks that I may not be aware of.
(All the code boxes below are PowerShell).
PS C:\> C:\Python34\Scripts\pip.exe list
jdcal (1.0)
pip (7.1.2)
setuptools (12.0.5)
virtualenv (13.1.2)
Although this Python 3.4 install doesn't have Django installed, it appears to pick up the version from the Python 33x86 install. Is that normal?
PS C:\> C:\Python34\python.exe -c "import django; print(django.get_version())"
1.6.5
PS C:\> C:\Python33x86\python.exe -c "import django; print(django.get_version())"
1.6.5
I've created a Python virtualenv based on Python 3.4 and installed Django 1.8.4 in it. Doing a "pip list" confirms that it is installed correctly:-
PS C:\> D:\PyVirtualEnvs\example_py34\Scripts\activate.bat
PS C:\> D:\PyVirtualEnvs\example_py34\Scripts\pip.exe list | Select-String "Django "
Django (1.8.4)
However, when I import within that virtualenv, I get Django version 1.6.5:-
PS C:\> D:\PyVirtualEnvs\example_py34\Scripts\python.exe -c "import django; print(django.get_version())"
1.6.5
Is this a bug in virtualenv or am I missing something?
EDIT: Could it be related to this question?
EDIT2: The same thing happens when using pyvenv, as suggested by ham-sandwich.
I've discovered the reason for this behaviour. The PYTHONPATH environment variable was set to a Python installation at an unusual location on the machine.
According to the documentation, PYTHONPATH is used as the import location when the module is not found in the current directory.
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
- the directory containing the input script (or the current directory).
- PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
- the installation-dependent default.
For some reason PYTHONPATH is not set/unset by the activate/deactivate scripts. It does set PYTHONHOME, but this doesn't seem to affect imports. This feels like a bug in virtualenv and pyvenv (I tried both).
The original activate.bat scripts change a "set" variable, which doesn't affect the $env:PYTHONPATH. Activate.ps1 attempts to save the original PYTHONPATH in a variable, set it to the virtual environment directory, then on deactivate, restore the original PYTHONPATH. Neither of these work anymore, possibly due to a Powershell or Python update.
The solution for us is to modify the activate and deactivate scripts (PoSh or bat) to switch the PYTHONPATH between two hard-coded values.