Python/C and PYTHONPATH

Tero Pihlajakoski tepihlaj at paju.oulu.fi
Tue Jan 6 02:04:31 CET 2004


Samuel Walters <swalters_usenet at yahoo.com> wrote:
> |Thus Spake Tero Pihlajakoski On the now historical date of Mon, 05 Jan
> 2004 22:39:19 +0000|
>> I'll see if it's actually the C-part that's causing problems, but I worked
>> it around by adding:
>> 
>> PyRun_SimpleString("import sys\nsys.path.insert(0,'')");
>> 
>> right after the Py_Initialize().
>> 
>> Works ok. Guess I'm "allowed" to do that(?)
> IMLK (In My Limited Knowledge) that seems okay, but it also feels a bit
> ham-handed.  try this snippet:

Ok, there are comments here, somewhere: 

> ---untested code---
> #include <string.h>
> #include <stdlib.h>
> /* prototyping may not be neccessary... dunno...*/
> extern char *getenv(const char *name);
> extern char *setenv(const char *name, const char *value, int overwrite);
> /* comment them out if gcc complains about redeclarations. */

> /* append something to pythonpath */
> /* returns 0 on failure, 1 on creation of the env variable and 2 on an append
>   oh, and -1 in cases of catastrophic miscompilation */
> int myPyPathAppend(char *extrapath)
> {
>    char *buffer = NULL;
>    /* size to taste... You should do this dynamically to avoid future buffer overrun attacks*/
>    char eventual_path[1024] = { 0 };
>    /* take note: after getenv, buffer points to an external constant character buffer.
>       do NOT try to modify it directly.  use strcpy(char *dest, char *src)
>       (he says knowingly... is she into photography mate?)
>       */
>    if( (buffer = getenv("PYTHONPATH")) == NULL )
>    {
>        /* we're here because PYTHONPATH is not already part of the environment. */
>        
>        setenv("PYTHONPATH", extrapath, 1); /* the last argument makes sure that we create the env var*/
>        /* did it go happen ..  you should check this more rigorously*/
>        if( (buffer = getenv("PYTHONPATH")) == NULL)
>        {
>            /* we failed... abend. */
>            return 0;
>        }
>        else
>        {
>            /* success! cheers! */
>            return 1;
>        }
>        return -1; /* dead code... should never reach here */
>    }
>    else
>    {
>        /* PYTHONPATH already exists.  append ';', then our new path and update it. */

Here. I might not want to add ';' or ':', depending on the OS (probably
not)? I can solve this with #ifdefs for WIN32 and Linux, but everytime I
want to run it on a new system, I'd have to find out the delimiter... It
also needs a buffer underrun check on that [1024]. I'll stick with the
PyRun_... for now, but I'll definitely save this code, so thanks. Again.

Also, found this piece from sys.path docs (now that my net is up and
running):
  ... "A program is free to modify this (sys.path) list for its own
purposes." ...
  

>                
>        /* find the "=" in the buffer...
>           from  string.h
>           extern char *strstr (__const char *__haystack, __const char *__needle)
>           there's a better way to do this, but I can't recall the function off the top of my head
>        */
>        buffer = strstr(buffer, "=") + 1; /* +1 because buffer points to the equals.  we want the string starting after it. */
>        
>        /* copy the old PYTHONPATH string */
>        strcpy(eventual_path, buffer);
>        strcat(eventual_path, ";");
>        strcat(eventual_path, extrapath);

>        setenv("PYTHONPATH", extrapath, 1); /* the last argument makes sure that we create the env var*/
>        /* did it go happen ..  you should check this more rigorously*/
>        if( (buffer = getenv("PYTHONPATH")) == NULL)
>        {
>            /* we failed... abend. */
>            return 0;
>        }
>        else
>        {
>            /* success! cheers! */
>            return 2;
>        }
>        return -1; /* dead code... should never reach here */
>    }

One if and two elses, have you started "getting ready" for the party
already? ;) Or maybe it's fuzzy logic ;)

>    else
>    {
>        /* PYTHONPATH already exists.  append ';', then our new path and update it. */
>        /* find the "=" in the buffer...

... snip ...

>    }
>    return -1; /* deader code... should *really* never reach here */
> }
> ---untested code---
> I haven't tested, compiled or even read through this code.
> I'm late for a party and still added comments
> That means you get punctuation patrol :-P
> Check the semicolons, check the braces
> Hey, I hear that in some companies they call this teamwork methodology
> "extreme-programming"  We're buzzword compliant!

- Tero

-- 




More information about the Python-list mailing list