Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I forced to os.path.expanduser in python?

Tags:

python

I'm sure it's intentional, so can someone explain the rationale for this behavior:

Python 2.7.2 (default, Oct 13 2011, 15:27:47) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from os.path import isdir,expanduser
>>> isdir("~amosa/pdb")
False
>>> isdir(expanduser("~amosa/pdb"))
True
>>>
>>> from os import chdir
>>> chdir("~amosa/pdb")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: '~amosa/pdb'
>>> chdir(expanduser("~amosa/pdb"))
>>>

It's really annoying since, after all, the path with a username in it can be resolved unambiguously... I want to write code that can handle any sort of input that a user might give me, but this behavior requires me to call expanduser on every path my code has to deal with. It also means that anywhere I print that path out for the user to see, it will be slightly less legible than what they gave me.

This seems inconsistent with the concept of "duck typing" in which I generalize to mean that I expect python not to whine to me unless there's actually a problem...

like image 528
amos Avatar asked May 07 '12 19:05

amos


People also ask

What is OS path Expanduser in Python?

path. expanduser() method in Python is used to expand an initial path component ~( tilde symbol) or ~user in the given path to user's home directory. On Unix platforms, an initial ~ is replaced by the value of HOME environment variable, if it is set.

What does OS path Isfile do in Python?

path. isfile() method in Python is used to check whether the specified path is an existing regular file or not.

What does OS path join do?

os. path. join combines path names into one complete path. This means that you can merge multiple parts of a path into one, instead of hard-coding every path name manually.

What is OS path Getmtime ()?

path. getmtime() method in Python is used to get the time of last modification of the specified path. This method returns a floating point value which represents the number of seconds since the epoch. This method raise OSError if the file does not exist or is somehow inaccessible.


2 Answers

Because the underlying system calls don't recognize user paths, and the file access APIs are a fairly thin wrapper over them.

Additionally, it would be fairly surprising for non-Unix users,
if (for example) fopen("~foo") returns a "foo: no such user" error (as "~foo" is a valid file name on, for example, Windows)…
Or, similarly, if fopen("~administrator") returns an error like "Is a directory: C:\Documents and Settings\Administrator\".

Finally, as commenters have noted: you're confusing "duck typing" with "helpful shortcuts", which are two entirely different things:
- Duck typing allows me to substitute for a duck anything which quacks like a duck.
- Helpful shortcuts allow me to substitute for a duck anything which could be made to quack like a duck.(Python does not "try to make it quack" like some other languages do).

like image 154
David Wolever Avatar answered Oct 29 '22 22:10

David Wolever


In normal Unix utilities, the ~amosa syntax is handled by the shell, which is the program that invokes utilities. The utilities themselves do not know about the special ~ syntax (generally).

So if your python program is invoked by a shell on Unix, it will Just Work:

$ python -c 'import sys; print sys.argv[1]' ~drj
/home/drj

Notice how the python program above prints the expanded path, even though it clearly has no code to do the expansion itself. The shell expanded it.

like image 41
David Jones Avatar answered Oct 29 '22 21:10

David Jones