[Python-Dev] Preventing 1.5 extensions crashing under 1.6/2.0 Python

Gordon McMillan gmcm@hypernet.com
Sun, 16 Jul 2000 09:07:55 -0400


There seems to be some confusion about this subject. 
Clarification:

An extension compiled for 1.5 will, when loaded by 1.6 / 2.0 
either:
 - fail to load (python15.dll not found)
 - crash (python15.dll found)

This is because the typical way of building an extension on 
Windows has you link against the import lib for the current 
version of Python. An import lib is nothing like a static lib - it's 
a bit of stub code (which gets statically linked in) which 
automatically does the dynamic load of the associated dll. In 
other words, python15.lib (the import lib) automatically loads 
python15.dll at runtime.

1) One proposed solution was to remove the version number 
from the python dll, and rely on binary compatibility. As Mark 
said, this would "probably" work. The problem being that 
moving from "probably" to "certainly" is very difficult. And a 
failure would be every bit as messy as the current situation 
(crash - except you've removed any easy way of diagnosing 
the situation).

2) Another was to stop putting pythonxx.dll in the system 
directory - that breaks COM support.

3) Another is to have the 1.6 / 2.0 installer remove any other 
versions of the python dll from the system directory. But that 
breaks having multiple versions of python installed (which 
*does* work).

4) Another would be to build extensions with the version 
number in the name (eg, kjbuckets15.dll), with some added 
magic to the c-extension import code (so "import kjbuckets" 
evaluates to loading "kjbuckets" + sys.winver-with-the-dot-
removed + ['.dll' | '.pyd']). I don't think this would break 
anything (but it would tax the capabilities of your typical 
Windows developer <wink>).

5) The last "solution" I can think of is the Tcl stubs 
mechanism. In this scenario, the extension would not link 
against any import lib for python at all. It would rely on getting 
a pointer to a (large) table of pointers to python-exported 
functions and symbols in the initmodule call. There's a lot of 
drudge work involved in setting this up. It does mean that 
binary compatibility can always be maintained, or if it's 
decided to break binary compatibility, failure can be made 
"graceful" <wink/snort>. (It also means that embedders could 
statically link in python, and still dynamically load 
extensions). Unfortunately, this solution still doesn't help with 
the transition from 1.5 to 1.6 / 2.0.

6) Of course, we can also do nothing. This is not as bad as it 
has been painted. Extensions on Windows are supposed to 
live in the DLLs subdirectory (although certain package writers 
don't follow this convention); and since this is a new install, it's 
a new directory. So we tell users not to move extensions from 
their old install into the new one. Extension writers who don't 
follow this convention (you know who you are) can figure out 
their own responses.

In an ideal world, I rather like #5 (stubs), but I vote for #4 
(version number in the extension module name) or #6 (get a 
life).



- Gordon