
[me]
But the intention here is for the customization to be application specific (hence the Spam in the name). sitecustomize doesn't know whethere I need the Mailman or the Knowbot root added to my path.
[JimA]
Ah, you have multiple scripts in one directory and multiple Foo_path, Bar_path etc. I was thinking with my Windows head. A commercial Windows app generally has its own exclusive install directory, so I was thinking single directory so a single sitecustomize.py.
Or do you mean to imply that we can do this with zero text added to the script, by simply dropping an appropriate sitecustomize.py in the script dir?
Yes, that is exactly what I was thinking.
Unfortunately this does currently *not* work, because sys.path[0] is added after Py_Initialize() is run.
Yikes! That kills using sitecustomize.py. Your Spam_path still works because it is imported later, but requires an import in each Python main script just as you said.
Not too bad (who cares about one more line of boilerplate...).
Even worse, it means that exceptions.py and site.py can not be found at all except using the normal PYTHONPATH, and putting their path in Spam_path will *not* work.
Why would you want your own exceptions.py and site.py?
Because the script's directory is first on the default path, the Spam scripts will pick up Spam_path without any help from $PYTHONPATH.
Hmmm. Is this really true? Nothing else, for example the registry, can change sys.path[0]? Ever? Please say yes.
Yes. (The registry can add module-specific paths, which will be searched before sys.path is even looked at, but this is only for specific modules. It cannot insert a general directory that is searched.) The only way this can fail is if an embedding app fails to call PySys_SetArgv().
Oh dear, I think I heard no instead of yes. Are you saying that if someone else installs a Python app on my customer's machine after I do, and sets a registry entry which sayes to use c:/other/path/to/site.py for site.py (as he may very well want to do), then if my Python program depends on getting my copy of site.py from my directory, it will then use the other copy instead and may very well fail?
Again - why would anyone register their own site.py?
In any case, that's a separate issue -- I agree that if sys.path[0] is '' (as it often is) it's better for site.py or sitecustomize.py or Spam_path.py (or whoever) to absolutize it (and everything else on the path) so that it will still work if the app does a chdir().
Point on the curve: Windows apps generally start from an icon which contains their path and current working directory, and these are generally different. So a Windows app in general will *never* have had a getcwd() equal to the path of either the binary interpreter or the Python main script.
You're lucky. It turns out that on Windows, under those circumstances at least, sys.path[0] is the absolute pathname of the directory. You only see '' if sys.argv[0] doesn't have any pathname information; that's only possible if the script *does* live in the current directory.
The files exceptions.py and site.py must be in all the bin directories as well as sitecustomize.py because they are automatically imported in Py_Initialize().
Yes.
Well, *no* right? This fails unless the bin directories are in fact on PYTHONPATH. The only way to get exceptions.py is by using sys.path as it exists within Py_Initialize(). So there is no hacked sys.path[0] equal to the script dir. And since the path hacks in site.py haven't happened yet either, we have an incomplete sys.path at that point.
Sorry, I've lost track of what we were after here. Indeed the scripts' directory (which I presume you meant by the bin directory) indeed doesn't occur in sys.path until after Py_Initialize() has run.
added to sys). How about prepending the single directory sys.executable to sys.path during Py_Initialize()? And demanding that modules like the new Greg_importer.py[c], exceptions.py[c] and site.py[c] be placed there.
On Unix, this is a bin directory and it is strongly discouraged to put non-program files there.
Ok, point taken.
Is the full DLL path available at any point? This would certainly be a good starting point -- especially when the DLL is loaded implicitly as the result of some COM operation.
I don't know about loading by COM, but if it is a file, its absolute path is reliably known in sys, the code is identical to that currently used for sys.executable (on Windows), and I have a patch if you want.
I presume using GetModuleFileName()? Please send me the patch!
JimA's conjecture: It is currently impossible to ship a Python app which can not be damaged by the installation of a second Python app without using a hacked custom binary.
Sounds right. All tricks to make the app unique require using a different registry key, which requires a change to the DLL. However, you can do this without recompiling! The version string is used is embedded in a resource, so you can patch it using some kind of resource editor. Mark Hammond planned it this way! --Guido van Rossum (home page: http://www.python.org/~guido/)