Python 3 minor irritation

Alf P. Steinbach alfps at start.no
Thu Feb 4 06:20:47 CET 2010


* Benjamin Kaplan:
> On Wed, Feb 3, 2010 at 11:18 PM, Alf P. Steinbach <alfps at start.no> wrote:
>> * Benjamin Kaplan:
>>> On Wed, Feb 3, 2010 at 9:56 PM, Alf P. Steinbach <alfps at start.no> wrote:
>>>> * David Monaghan:
>>>>> I have a small program which reads files from the directory in which it
>>>>> resides. It's written in Python 3 and when run through IDLE or PythonWin
>>>>> works fine. If I double-click the file, it works fine in Python 2.6, but
>>>>> in
>>>>> 3 it fails because it looks for the files to load in the Python31
>>>>> folder,
>>>>> not the one the script is in.
>>>>>
>>>>> It's not a big deal, but browsing around I haven't found why the
>>>>> behaviour
>>>>> has been changed or any comment about it (That might be my poor search
>>>>> technique, I suppose).
>>>>>
>>>>> The program fails at:
>>>>>
>>>>>   try:
>>>>>       tutdoc = minidom.parse(".//Myfile.xml")
>>>>>   except IOError:
>>>>>       <snip>
>>>> The "//" is wrong, but should not cause the behavior that you describe.
>>>>
>>>> Try to post a complete smallest possible program that exhibits the
>>>> problem.
>>>>
>>>> Possibly, in creating that example you'll also find what's cause the
>>>> problem. :-)
>>>>
>>>>
>>>> Cheers & hth.,
>>>>
>>>> - Alf
>>> That is the smallest example the exhibits the problem.
>> No, it doesn't seem to exhibit the problem at all. :-)
>>
>>
>>> It's not an
>>> issue with the Python code, it's an issue with how Windows is running
>>> it. I don't know enough about the way Windows Explorer runs files, but
>>> it seems to be doing the equivalent of
>>> cd C:\Python31
>>> python31.exe C:\full\path\to\script\foo.py
>>>
>>> instead of
>>> cd C:\full\path\path\to\script
>>> C:\Python31\python.exe foo.py
>>> which is David expected. This throws off the relative filepath.
>> No, this is not what happens.
>>
>> What happens is that when you double-click the script, then __file__ is set
>> to the absolute path instead of just the filename, at least on my machine
>> (XP); whether the full path or just the filename is passed on the OS level
>> depends, however, on the Windows version.
>>
>> The current directory is always (initially) correct, as the script's
>> directory.
>>
> 
> Read my first paragraph again- it has absolutely nothing to do with
> Python. It has to do with how the Windows is running Python 3 on the
> OP's computer.

I'm not sure what you're arguing here.

But anyway, first, I haven't stated that "it" is (only) an issue with Python: on 
the contrary, I explained how the program is run by Windows Explorer, where in 
Windows XP the full path is passed by Windows Explorer, and how that results in 
(can result in) a full path in __file__ when a script is run by double-clicking.

Second, as stated your hypothesis about current directory is Wrong(TM).

So the explanation of an incorrect result involves not only Windows Explorer, 
the Windows version, and Python, but also the OP's code is involved.

Hence the request for a minimal, complete example  --  which is nearly always a 
good idea.



> The OP's description said that it was looking for the
> file .\\myfile.xml in C:\Python31 which means it translated '.', the
> current working directory, to be C:\Python31 and not the directory the
> script is in.

I fail to reproduce that behavior.

By the way, are you the OP (just with another name)?

If not, have you reproduced the described behavior? Then kindly post the code.


>>> The easiest way to solve this permanently, by the way, is to not use
>>> relative paths. All it takes is one script to call os.chdir and the
>>> script breaks. You can use __file__ and the os.path module to figure
>>> out exactly where you are in an OS-agnostic way.
>>>
>>> import os.path
>>> #get the absolute path to the current script
>>> abs_path = os.path.abspath(__file__)
>> According to the docs: "On most platforms, this is equivalent to
>> normpath(join(os.getcwd(), path))."
>>
> 
> os.path.abspath will always work in this case (unless something
> changes the current working directory before that statement runs)

Which change is what you surmised as a cause of the original problem.

Hello.


> because __file__ is given either as an absolute path or as relative to
> the current working directory.

No, that's incorrect.


<code py="3.1">
import os

print( "Current directory: [" + os.getcwd() + "]" )
print( "__file__ = " + __file__ )
os.chdir( "blah" )
print( "Current directory: [" + os.getcwd() + "]" )
print( "__file__ = " + __file__ )
</code>


<example>
C:\Documents and Settings\Alf\test> python curdir.py
Current directory: [C:\Documents and Settings\Alf\test]
__file__ = curdir.py
Current directory: [C:\Documents and Settings\Alf\test\blah]
__file__ = curdir.py                    <-- *Not* relative to cwd.

C:\Documents and Settings\Alf\test> _
</example>


[snip]
> Except that if the cwd is not the directory the script is running in,
> __file__ should still point to it either through an absolute path
> (highly likely since it's run through Windows Explorer) or some
> (however convoluted) relative path.

Don't know about "should", but if you're talking reality, no, that's incorrect; 
see above.

[snip]


Cheers & hth.,

- Alf



More information about the Python-list mailing list