9

I need to set association for .py files to be executed with specific python version. But I need to make this association only for single cmd.exe session (parallel sessions should not be affected). Does Windows allow this?

I suspect the answer is no, but I'd like to see some proof before throwing out the idea to get such feature into virtualenv.

anatoly techtonik
  • 19,847
  • 9
  • 124
  • 140
  • The trivial solution is to name the python that you want in the command line rather than relying on file associations which simply are not cut out for this. – David Heffernan Apr 07 '11 at 19:55
  • I already have several Python interpreters named python32, python27 etc. What I want is to avoid specifying interpreter in command line for this virtualenv session. – anatoly techtonik Apr 08 '11 at 01:49

4 Answers4

8

Sure you can. You were very close to answer in your comment to Jakob's answer -

If it is possible to change file association with environment variables - it will help, but it doesn't seem possible.

It is possible. All you have to do is to use REG_EXPAND_SZ type of registry key and environment variable in the key's value. For example putting
%python_home%\python %1 %*
as the (Default) value of
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Python.File\shell\open\command
key and setting its value to REG_EXPAND_SZ makes it possible to define what Python your Python files will be opened with. You decide by setting python_home environment variable and you can do this per command line session of course. Take a look at my answer to the question where in the registry does Windows store, with which program to open certain file types?

Having said that there is now special tool for solving exactly this problem which I highly recommend. It's called pylauncher. From the docs:

PEP 397 compatible launcher for Python under Windows. See http://www.python.org/dev/peps/pep-0397/ for PEP, http://www.red-dove.com/screencasts/launcher/launcher.html for screencast

You can even skip the .py extension if you add it to the PATHEXT environment variable. See the question What environment variables will be used when calling an EXE from command line?

Community
  • 1
  • 1
Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366
  • 2
    This works great. And I believe that it is important to set up your environment this way, because otherwise you may jump to wrong conclusions by calling the wrong interpreter python instance without being noticing. This is how I did it * setup an empty virtaulenv ENV * have VIRTUAL_ENV system env var pointing to it * change the association to be relative, based on VIRTUAL_ENV `reg add HKEY_CLASSES_ROOT\Python.File\shell\open\command /ve /t REG_EXPAND_SZ /d "\"%VIRTUAL_ENV%\Scripts\python.exe\" \"%1\" %*" ` * activating an environment, changes the value of VIRTUAL_ENV – xverges Sep 16 '11 at 20:46
  • 1
    Nice! +1 This *answers* my question [Why doesn't virtualenv on Windows associate .py/.pyw/.pyo/.pyc files with virtualenv's version of Python executables?](http://stackoverflow.com/questions/4879624/) – Piotr Dobrogost Sep 17 '11 at 21:50
  • However it would be nice not to have to create this virtual :) virtualenv. There must be some way... – Piotr Dobrogost Sep 18 '11 at 17:26
  • Unfortunately, my Windows box is broken and I couldn't check this works, but it seems feasible. – anatoly techtonik Sep 19 '11 at 14:47
3

In Windows you can change file associations from the command line using the assoc and ftype commands (You can currently download a Windows Command Reference PDF file from here).

You can see what file type is currently associated with .py files using the assoc command:

> assoc .py
.py=Python.File

With that information you can then check to see what program is currently associated with the Python.File file type using the ftype command:

> ftype Python.File
Python.File="C:\Python2.6\python.exe" "%1" %*

You can also use ftype to change the associated program:

> ftype Python.File="C:\Python2.7\python.exe" "%1" %*
Python.File="C:\Python2.7\python.exe" "%1" %*

Associations set this way are persistent because they're stored in the Windows Registry. That means you will need to set or restore it to what you want before terminating the cmd.exe session. I'd suggest using one or more batch files for this purpose.

cmd.exe itself accepts a /k parameter, which you could use to have it execute a batch file at start up that sets up the file association you want initially. You could then also provide a custom quit.bat that would restore it before exiting the cmd session.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • I need the scope of file association to be limited to cmd.exe session, i.e. parallel cmd sessions (with different python virtualenv) should not be affected. – anatoly techtonik Apr 08 '11 at 01:47
  • @techtonik: On Windows associations are a function of the global OS Registry, so it seems that you'll need to explicitly specify which version of the Python interpreter you want used to execute the script. It's unclear why you want to avoid doing that so badly as it doesn't seem any worse than setting-up an association for/in a `cmd.exe` session would be. – martineau Apr 08 '11 at 21:15
  • The problem is that when users execute 'django-admin.py' for example, it is executed with default python, not the one installed in virtualenv, and the script fails. While it is possible to rewrite all instructions and add 'python' prefix, I'd like to avoid this if possible. – anatoly techtonik Apr 08 '11 at 21:53
  • 1
    Just a remark: both *assoc* and *ftype* act upon keys in *HKEY_LOCAL_MACHINE\Software\Classes* which are overridden by entries in *HKEY_CURRENT_USER\Software\Classes* if present. – Piotr Dobrogost Sep 04 '11 at 08:22
  • @techtonik: Why do you think you would have to add a 'python' prefix? – martineau Sep 18 '12 at 18:56
  • @martineau: Because assoc/ftype value can be changed in parallel session I can not rely on its full path, so I need to modify the scripts to include `python` prefix before command and make sure that PATH is set correctly for the given 'virtualenv'. – anatoly techtonik Oct 15 '12 at 08:44
  • @techtonik: If you include the script's extension (`.py` or `.pyw`) when you invoke it, you don't need to have the PATH env var set correctly, nor add the `python` prefix to execute it with the currently associated Python interpreter. – martineau Oct 15 '12 at 16:39
  • @martineau: This point is clear. The point is that without REG_EXPAND_SZ the association doesn't help, so the question is if `ftype Python.File="%PYTHON_HOME%\python.exe" "%1" %*` will work? – anatoly techtonik Oct 19 '12 at 14:08
  • 1
    @techtonik: It will work if you do it in two steps. `set TMP_HOME=PYTHON_HOME` followed by `ftype Python.File="%%TMP_HOME%%\python.exe" "%1" %*`. – martineau Oct 19 '12 at 15:18
  • Another problem is that if I close the .bat file the original association won't be restored. – anatoly techtonik Oct 22 '12 at 08:36
  • @techtonik: It will if you set `PYTHON_HOME` to the proper value. – martineau Oct 22 '12 at 08:48
  • It could be the solution if I could access global PYTHON_HOME somehow from batch file. Otherwise I risk to break system Python when overriding it. – anatoly techtonik Oct 22 '12 at 09:21
  • I mean I need to set global PYTHON_HOME to the previous version if it's not set before `ftype Python.File="%PYTHON_HOME%\python.exe" "%1" %*` – anatoly techtonik Oct 22 '12 at 09:25
  • You can change the global `PYTHON_HOME` environment variable whose value is stored in the registry, either by using the `reg` command or `setx.exe` as described in this [article](http://best-windows.vlaurie.com/environment-variables.html). – martineau Oct 22 '12 at 11:18
1

Your best bet is probably going to be to set the PATH variable in the script and invoke python by writing python script.py. File associations are global and shared between processes. Environment variables are local to a process and that's why I suggest this solution.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

You can use the windows set command to set temp associations, set will last as long as the shell does unless attached to the system enviromental variables.

Jakob Bowyer
  • 33,878
  • 8
  • 76
  • 91