[pywin32-checkins] pywin32/win32/Lib pywintypes.py,1.11,1.12
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: Mark H. <mha...@us...> - 2005-10-21 02:25:57
|
Update of /cvsroot/pywin32/pywin32/win32/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2524/win32/lib Modified Files: pywintypes.py Log Message: Give up on trying to safely import pywintypesXX.dll without help from an extension - so we have a new _win32sysloader.cpp which only claim to fame is that it does not link to pywintypes.dll. This prevents errors seen in Zope, when an (existing) pywintypesXX.dll lives in system32, and Zope installs its own next to its python.exe. In this case, importing (eg) win32api before pywintypes would cause bizarre type errors as the module was loaded twice. Index: pywintypes.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Lib/pywintypes.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** pywintypes.py 2 Jul 2004 02:38:45 -0000 1.11 --- pywintypes.py 21 Oct 2005 02:25:49 -0000 1.12 *************** *** 2,14 **** def __import_pywin32_system_module__(modname, globs): ! # *sigh* - non-admin installs will not have pywintypesxx.dll in the ! # system directory, so 'import win32api' will fail looking ! # for pywintypes - the exact DLL we are trying to load! ! # So if it exists in sys.prefix, then we try and load it from ! # there, as that way we can avoid the win32api import import imp, sys, os if not sys.platform.startswith("win32"): # These extensions can be built on Linux via the 'mainwin' toolkit. # Look for a native 'lib{modname}.so' for ext, mode, ext_type in imp.get_suffixes(): if ext_type==imp.C_EXTENSION: --- 2,27 ---- def __import_pywin32_system_module__(modname, globs): ! # This has been through a number of iterations. The problem: how to ! # locate pywintypesXX.dll when it may be in a number of places, and how ! # to avoid ever loading it twice. This problem is compounded by the ! # fact that the "right" way to do this requires win32api, but this ! # itself requires pywintypesXX. ! # And the killer problem is that someone may have done 'import win32api' ! # before this code is called. In that case Windows will have already ! # loaded pywintypesXX as part of loading win32api - but by the time ! # we get here, we may locate a different one. This appears to work, but ! # then starts raising bizarre TypeErrors complaining that something ! # is not a pywintypes type when it clearly is! ! ! # So in what we hope is the last major iteration of this, we now ! # rely on a _win32sysloader module, implemented in C but not relying ! # on pywintypesXX.dll. It then can check if the DLL we are looking for ! # lib is already loaded. import imp, sys, os if not sys.platform.startswith("win32"): # These extensions can be built on Linux via the 'mainwin' toolkit. # Look for a native 'lib{modname}.so' + # NOTE: The _win32sysloader module will probably build in this + # environment, so it may be better to use that here too. for ext, mode, ext_type in imp.get_suffixes(): if ext_type==imp.C_EXTENSION: *************** *** 34,37 **** --- 47,52 ---- # If we are running from a frozen program (py2exe, McMillan, freeze) # then we try and load the DLL from our sys.path + # XXX - This path may also benefit from _win32sysloader? However, + # MarkH has never seen the DLL load problem with py2exe programs... for look in sys.path: # If the sys.path entry is a (presumably) .zip file, use the *************** *** 46,73 **** "Module '%s' isn't in frozen sys.path %s" % (modname, sys.path) else: ! # If there is a version in our Python directory, use that ! # (it may not be on the PATH, so may fail to be loaded by win32api) ! # Non-admin installs will have the system files there. ! found = None ! if os.path.isfile(os.path.join(sys.prefix, filename)): ! found = os.path.join(sys.prefix, filename) ! # Allow Windows to find it. We have tried various other tricks, ! # but in some cases, we ended up with *2* versions of the libraries ! # loaded - the one found by Windows when doing a later "import win32*", ! # and the one we found here. ! # A remaining trick would be to simulate LoadLibrary(), using the ! # registry to determine the system32 directory. However, Python ! # 2.2 doesn't have sys.getwindowsversion(), which is kinda needed ! # to determine the correct places to look. ! # The downside of this is that we need to use win32api, and this ! # depends on pywintypesxx.dll, which may be what we are trying to ! # find! If this fails, we get a dialog box, followed by the import ! # error. The dialog box is undesirable, but should only happen ! # when something is badly broken, and is a less harmful side-effect ! # than loading the DLL twice! if found is None: ! import win32api # failure here means Windows can't find it either! ! found = win32api.GetModuleFileName(win32api.LoadLibrary(filename)) # Python can load the module --- 61,96 ---- "Module '%s' isn't in frozen sys.path %s" % (modname, sys.path) else: ! # First see if it already in our process - if so, we must use that. ! import _win32sysloader ! found = _win32sysloader.GetModuleFilename(filename) ! if found is None: ! # We ask Windows to load it next. This is in an attempt to ! # get the exact same module loaded should pywintypes be imported ! # first (which is how we are here) or if, eg, win32api was imported ! # first thereby implicitly loading the DLL. ! # Sadly though, it doesn't quite work - if pywintypesxx.dll ! # is in system32 *and* the executable's directory, on XP SP2, an ! # import of win32api will cause Windows to load pywintypes ! # from system32, where LoadLibrary for that name will ! # load the one in the exe's dir. ! # That shouldn't really matter though, so long as we only ever ! # get one loaded. ! found = _win32sysloader.LoadModule(filename) if found is None: ! # Windows can't find it - which although isn't relevent here, ! # means that we *must* be the first win32 import, as an attempt ! # to import win32api etc would fail when Windows attempts to ! # locate the DLL. ! # This is most likely to happen for "non-admin" installs, where ! # we can't put the files anywhere else on the global path. ! ! # If there is a version in our Python directory, use that ! if os.path.isfile(os.path.join(sys.prefix, filename)): ! found = os.path.join(sys.prefix, filename) ! if found is None: ! # give up in disgust. ! raise ImportError, \ ! "No system module '%s' (%s)" % (modname, filename) # Python can load the module |