Jeremy Friesner
Jeremy Friesner

Reputation: 73219

How to make Python use a path that contains colons in it?

I have a program that includes an embedded Python 2.6 interpreter. When I invoke the interpreter, I call PySys_SetPath() to set the interpreter's import-path to the subdirectories installed next to my executable that contain my Python script files... like this:

PySys_SetPath("/path/to/my/program/scripts/type1:/path/to/my/program/scripts/type2");

(except that the path strings are dynamically generated based on the current location of my program's executable, not hard-coded as in the example above)

This works fine... except when the clever user decides to install my program underneath a folder that has a colon in its name. In that case, my PySys_SetPath() command ends up looking like this (note the presence of a folder named "path:to"):

PySys_SetPath("/path:to/my/program/scripts/type1:/path:to/my/program/scripts/type2");

... and this breaks all my Python scripts, because now Python looks for script files in "/path", and "to/my/program/scripts/type1" instead of in "/path:to/myprogram/scripts/type1", and so none of the import statements work.

My question is, is there any fix for this issue, other than telling the user to avoid colons in his folder names?

I looked at the makepathobject() function in Python/sysmodule.c, and it doesn't appear to support any kind of quoting or escaping to handle literal colons.... but maybe I am missing some nuance.

Upvotes: 1

Views: 4872

Answers (2)

samplebias
samplebias

Reputation: 37919

The problem you're running into is the PySys_SetPath function parses the string you pass using a colon as the delimiter. That parser sees each : character as delimiting a path, and there isn't a way around this (can't be escaped).

However, you can bypass this by creating a list of the individual paths (each of which may contain colons) and use PySys_SetObject to set the sys.path:

PyListObject *path; 

path = (PyListObject *)PyList_New(0); 
PyList_Append((PyObject *) path, PyString_FromString("foo:bar")); 
PySys_SetObject("path", (PyObject *)path); 

Now the interpreter will see "foo:bar" as a distinct component of the sys.path.

Upvotes: 6

fluffy
fluffy

Reputation: 5314

Supporting colons in a file path opens up a huge can of worms on multiple operating systems; it is not a valid path character on Windows or Mac OS X, for example, and it doesn't seem like a particularly reasonable thing to support in the context of a scripting environment either for exactly this reason. I'm actually a bit surprised that Linux allows colon filenames too, especially since : is a very common path separator character.

You might try escaping the colon out, i.e. converting /path:to/ to /path\:to/ and see if that works. Other than that, just tell the user to avoid using colons in their file names. They will run into all sorts of problems in quite a few different environments and it's a just plain bad idea.

Upvotes: 2

Related Questions