[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