Import and absolute file names, sys.path including ''... or not

  • Thread starter Jean-Michel Pichavant
  • Start date
J

Jean-Michel Pichavant

Hi fellows,

I spent quite a time on a malicious issue. I found out that there is a
slight difference on the sys.path content when either executing code
from a shell or from within a script.
This difference is the '' item, which is present in the shell form of
sys.path.

For instance, let's write this code in test.py:
import sys
print sys.path

shell form:
python
Python 2.4.4 (#2, Oct 22 2008, 19:52:44)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.['', other misc stuff] <- sys.path


script form:
python test.py
[other misc stuff] <- sys.path

The '' item is not here.

Problem is, '' is required for absolute path to be properly resolved. In
my code I sometimes have to import file in that way :
__import__('/some/absolute/path')

So the immediate solution is to write this:
if '' not in sys.path:
sys.path.append('') # make sure absolute path are properly resolved
in any case

I'm not a big fan of manipulating sys.path at the begining of my files.
Is there something I'm doing wrong ? Is there a standard/nice way to
support absolute path ? I guess '' is in fact aimed at resolving
relative path from the execution directory...

best regards,

Jean-Michel
 
A

Aahz

I spent quite a time on a malicious issue. I found out that there is a
slight difference on the sys.path content when either executing code
from a shell or from within a script. This difference is the '' item,
which is present in the shell form of sys.path.

Why are you calling this a malicious issue?

When I do this test, I find that the current working directory's full
path is prepended to sys.path, so if you're having problems, I bet that
you're changing your working directory during program execution.
 
J

Jean-Michel Pichavant

You are right, but my concern is not the relative path resolution. Let
me clarify:

/home/jeanmichel/test.py:
"import sys
print sys.path"
>python.exe test.py
sys.path = ['/home/jeanmichel']
> from within a python shell:
sys.path = ['']

The unpredictable effect of '' (at least something I did not predict) is
that it allows absolute path resolution, while '/home/jeanmichel' cannot.
Example :
write a anotherTest.py file:
"
__import__('/home/jeanmichel/test')
"

anotherTest.py will be successfully imported in a python shell ('' +
'/home/jeanmichel/test.py' is a valid path), but the "python.exe
anotherTest2.py" form will fail as it will try for '/home/jeanmichel'
+'/home/jeanmichel/test.py' which is not a valid path.

So my question is: "why the shell is adding '' when the interpreter is
adding the full path ?"

Hope I'm not too foggy.

JM
 
M

Mike Kazantsev

You are right, but my concern is not the relative path resolution. Let
me clarify:

/home/jeanmichel/test.py:
"import sys
print sys.path"
python.exe test.py
sys.path = ['/home/jeanmichel']
from within a python shell:
sys.path = ['']

The unpredictable effect of '' (at least something I did not predict) is
that it allows absolute path resolution, while '/home/jeanmichel' cannot.
Example :
write a anotherTest.py file:
"
__import__('/home/jeanmichel/test')
"

It works for me with py2.6, what version do you have?
anotherTest.py will be successfully imported in a python shell ('' +
'/home/jeanmichel/test.py' is a valid path), but the "python.exe
anotherTest2.py" form will fail as it will try for '/home/jeanmichel'
+'/home/jeanmichel/test.py' which is not a valid path.

I believe python uses os.path.join algorithm to combine paths which
discards anything (absolute or not) if absolute path gets appended to
it:
os.path.join('/some/path', '/home/jeanmichel') == '/home/jeanmichel'
So my question is: "why the shell is adding '' when the interpreter is
adding the full path ?"

Looks like a solid way to construct relative imports to me.

--
Mike Kazantsev // fraggod.net

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.11 (GNU/Linux)

iEYEARECAAYFAkoUm2kACgkQASbOZpzyXnEODQCeKOyjtGBNCp7vICFuzVp6y9V9
VHwAnAsF3yOkO+QEfT5ao7qsS95Yzbnm
=xU/K
-----END PGP SIGNATURE-----
 
G

greg

Jean-Michel Pichavant said:
__import__('/home/jeanmichel/test')

The __import__ function takes *module* names, not
filesystem pathnames.

Giving it a pathname might happen to work some of
the time in some versions of Python, but it's not
an intended feature, and you shouldn't rely on it.

If you want to execute the contents of an arbitrary
file, rather than a module existing somewhere in the
Python module namespace, use execfile().
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top