[Python-Dev] __file__ is not always an absolute path

Guido van Rossum guido at python.org
Sun Feb 7 00:53:00 CET 2010


On Sat, Feb 6, 2010 at 3:22 PM,  <exarkun at twistedmatrix.com> wrote:
> On 10:29 pm, guido at python.org wrote:
>>
>> On Sat, Feb 6, 2010 at 12:49 PM, Ezio Melotti <ezio.melotti at gmail.com>
>> wrote:
>>>
>>> In #7712 I was trying to change regrtest to always run the tests in a
>>> temporary CWD (e.g. /tmp/@test_1234_cwd/).
>>> The patches attached to the issue add a context manager that changes the
>>> CWD, and it works fine when I run ./python -m test.regrtest from trunk/.
>>> However, when I try from trunk/Lib/ it fails with ImportErrors (note that
>>> the latest patch by Florent Xicluna already tries to workaround the
>>> problem). The traceback points to "the_package = __import__(abstest,
>>> globals(), locals(), [])" in runtest_inner (in regrtest.py), and a "print
>>> __import__('test').__file__" there returns 'test/__init__.pyc'.
>>> This can be reproduced quite easily:
>>
>> [snip]
>>
>> I haven't tried to repro this particular example, but the reason is
>> that we don't want to have to call getpwd() on every import nor do we
>> want to have some kind of in-process variable to cache the current
>> directory. (getpwd() is relatively slow and can sometimes fail
>> outright, and trying to cache it has a certain risk of being wrong.)
>
> Assuming you mean os.getcwd():

Yes.

> exarkun at boson:~$ python -m timeit -s 'def f(): pass' 'f()'
> 10000000 loops, best of 3: 0.132 usec per loop
> exarkun at boson:~$ python -m timeit -s 'from os import getcwd' 'getcwd()'
> 1000000 loops, best of 3: 1.02 usec per loop
> exarkun at boson:~$
> So it's about 7x more expensive than a no-op function call.  I'd call this
> pretty quick.  Compared to everything else that happens during an import,
> I'm not convinced this wouldn't be lost in the noise.  I think it's at least
> worth implementing and measuring.

But it's a system call, and its speed depends on a lot more than the
speed of a simple function call. It depends on the OS kernel, possibly
on the filesystem, and so on. Also "os.getcwd()" abstracts away
various platform details that the C import code would have to
replicate. Really, the approach of preprocessing sys.path makes much
more sense. If an app wants sys.path[0] to be an absolute path too
they can modify it themselves.

-- 
--Guido van Rossum (python.org/~guido)


More information about the Python-Dev mailing list