Filename case-insensitivity on OS X

T

Tom Anderson

Afternoon all,

MacOS X seems to have some heretical ideas about the value of case in
paths - it seems to believe that it doesn't exist, more or less, so "touch
foo FOO" touches just one file, you can't have both 'makefile' and
'Makefile' in the same directory,
"os.path.exists(some_valid_path.upper())" returns True even when
"os.path.split(some_valid_path.upper())[1] in
os.listdir(os.path.split(some_valid_path)[0])" returns False, etc
(although, of course, "ls *.txt" doesn't mention any of those .TXT files
lying around).

Just to prove it, here's what unix (specifically, linux) does:

twic@urchin:~$ uname
Linux
twic@urchin:~$ python
Python 2.3.5 (#2, Sep 4 2005, 22:01:42)
[GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import os
filenames = os.listdir(".")
first = filenames[0]
first in filenames True
first.upper() in filenames False
os.path.exists(os.path.join(".", first)) True
os.path.exists(os.path.join(".", first.upper())) False

And here's what OS X does:

Hooke:~ tom$ uname
Darwin
Hooke:~ tom$ python
Python 2.4.1 (#2, Mar 31 2005, 00:05:10)
[GCC 3.3 20030304 (Apple Computer, Inc. build 1666)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
import os
filenames = os.listdir(".")
first = filenames[0]
first in filenames True
first.upper() in filenames False
os.path.exists(os.path.join(".", first)) True
os.path.exists(os.path.join(".", first.upper())) True

Sigh. Anyone got any bright ideas for working around this, specifically
for os.path.exists? I was hoping there was some os.path.actualpath, so i
could say:

def exists_dontignorecase(path):
return os.path.exists(path) and (path == os.path.actualpath(path))

Java has a java.io.File.getCanonicalPath method that does this, but i
can't find an equivalent in python - is there one?

I can emulate it like this:

def _canonicalise(s, l):
s = s.lower()
for t in l:
if s == t.lower():
return t
raise ValueError, ("could not canonicalise string", s)

def canonicalpath(path):
if (path in ("/", "")):
return path
parent, child = os.path.split(path)
cparent = canonicalpath(parent)
cchild = _canonicalise(child, os.listdir(cparent))
return os.path.join(cparent, cchild)

Or, more crudely, do something like this:

def exists_dontignorecase(path):
dir, f = os.path.split(path)
return f in os.listdir(dir)

But better solutions are welcome.

Thanks,
tom
 
S

Scott David Daniels

Tom said:
Java has a java.io.File.getCanonicalPath method that does this, but i
can't find an equivalent in python - is there one?

What's wrong with: os.path.normcase(path) ?

--Scott David Daniels
(e-mail address removed)
 
D

Doug Schwarz

Tom Anderson said:
Afternoon all,

MacOS X seems to have some heretical ideas about the value of case in
paths - it seems to believe that it doesn't exist, more or less, so "touch
foo FOO" touches just one file, you can't have both 'makefile' and
'Makefile' in the same directory,
"os.path.exists(some_valid_path.upper())" returns True even when
"os.path.split(some_valid_path.upper())[1] in
os.listdir(os.path.split(some_valid_path)[0])" returns False, etc
(although, of course, "ls *.txt" doesn't mention any of those .TXT files
lying around).


Strictly speaking, it's not OS X, but the HFS file system that is case
insensitive. You can use other file systems, such as "UNIX File
System". Use Disk Utility to create a disk image and then erase it
(again, using Disk Utility) and put UFS on it. You'll find that "touch
foo FOO" will create two files.
 
D

Dan Sommers

Strictly speaking, it's not OS X, but the HFS file system that is case
insensitive. You can use other file systems, such as "UNIX File
System". Use Disk Utility to create a disk image and then erase it
(again, using Disk Utility) and put UFS on it. You'll find that
"touch foo FOO" will create two files.

You may also find some native Mac OS X applications failing in strange
ways.

Regards,
Dan
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

Tom said:
Java has a java.io.File.getCanonicalPath method that does this, but i
can't find an equivalent in python - is there one?

I can emulate it like this:

I think it could be implemented more efficiently with getattrlist(2),
looking for ATTR_CMN_NAME. Unfortunately, there appears to be no wrapper
for this function.

Alternatively, you might also find macos.GetFullPathname useful,
although I'm uncertain as to how precisely it is used.

Regards,
Martin
 
T

Tom Anderson

What's wrong with: os.path.normcase(path) ?

It doesn't work.

Hooke:~ tom$ uname
Darwin
Hooke:~ tom$ python
Python 2.4.1 (#2, Mar 31 2005, 00:05:10)
[GCC 3.3 20030304 (Apple Computer, Inc. build 1666)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
import os
path=os.path.join(".", os.listdir(".")[0])
path './.appletviewer'
os.path.normcase(path) './.appletviewer'
os.path.normcase(path.upper()) './.APPLETVIEWER'

I'm not entirely sure what normcase is supposed to do - the documentation
says "Normalize case of pathname. Has no effect under Posix", which is
less than completely illuminating.

tom
 
T

Tom Anderson

Aaah, of course. Why on earth didn't Apple move to UFS/FFS/whatever with
the switch to OS X?
You may also find some native Mac OS X applications failing in strange
ways.

Oh, that's why. :(

tom
 
D

Dan Lowe

Aaah, of course. Why on earth didn't Apple move to UFS/FFS/whatever
with
the switch to OS X?


Oh, that's why. :(

That's one reason, but here are two more:

1. It would have broken the expected behavior from the previous 15
years of Mac OS releases. Given Mac users' obsessive attention to
detail regarding the consistency of their environment, this would
*not* have gone over well at all.

2. Mac OS is designed primarily for non-technical users. A case-
sensitive filesystem would just be confusing for the main audience.
If I tried to explain to my mother that Dan.doc is not the same as
DAN.DOC, she would probably tell me I was out of my mind.

Think about it - how many things used by average people are case
sensitive? Passwords? That's about it. (And judging by most user
passwords I have seen, they're almost all lowercase anyway.) Email
addresses, URLs, the search box in Google, your AOL or Jabber buddy
list: all case-insensitive.

Aside from that, what is "right" is a matter of opinion. I prefer
case-insensitive filesystems, and I'm a system administrator who
works on Solaris systems all day. Others I work with refuse to
consider case-insensitive filesystems as anything but a "bug". Who's
right? I don't think there's one true answer...

I'm not trying to get into one of these case sensitivity religious
wars here, just offering an opinion.

-dan
 
M

Michael Anthony Maibaum

You can choose if HFS+ behaves in a case-preserving, case-insensitive
or case-sensitive manner. See man newfs_hfs. Case sensitive is not
supported on the 'System' volume, but I have several external disks
using it without a problem for do general unix-like development
projects.

hth

Michael
 
P

Piet van Oostrum

Doug Schwarz said:
DS> In article <[email protected]>,
Afternoon all,

MacOS X seems to have some heretical ideas about the value of case in
paths - it seems to believe that it doesn't exist, more or less, so "touch
foo FOO" touches just one file, you can't have both 'makefile' and
'Makefile' in the same directory,
"os.path.exists(some_valid_path.upper())" returns True even when
"os.path.split(some_valid_path.upper())[1] in
os.listdir(os.path.split(some_valid_path)[0])" returns False, etc
(although, of course, "ls *.txt" doesn't mention any of those .TXT files
lying around).

DS> Strictly speaking, it's not OS X, but the HFS file system that is case
DS> insensitive. You can use other file systems, such as "UNIX File
DS> System". Use Disk Utility to create a disk image and then erase it
DS> (again, using Disk Utility) and put UFS on it. You'll find that "touch
DS> foo FOO" will create two files.

It seems that with Tiger, HFS+ can be made case-sensitive. I haven't seen
it, only read about it.
 
M

Maarten

Piet said:
It seems that with Tiger, HFS+ can be made case-sensitive. I haven't seen
it, only read about it.

Yes, indeed, that is possible. I tried it, once. Right now I'm using
the case insensitive version again, which should tell you how well it
works - the canon utilities of my camera refused to work for me, as did
Audacity. I didn't encounter any other problems, but that was enough
for me.

As to UFS: it is apparently way slower than HFS+, and only recommended
in special cases, most of which are now advised to use Case-sensitive
HFS+, I believe.

Maarten
 
D

Dan Lowe

You can choose if HFS+ behaves in a case-preserving, case-insensitive
or case-sensitive manner. See man newfs_hfs. Case sensitive is not
supported on the 'System' volume, but I have several external disks
using it without a problem for do general unix-like development
projects.

For people without an external disk sitting around, note that you can
also do this via a mountable disk image. Here's an example to create
a case-sensitive HFS+ image:

hdiutil create -size 10m -fs "Case-sensitive HFS+" -volname MyVolume
MyVolume.dmg

For more information, try "hdiutil create" or "man hdiutil".

-dan
 
D

Dan Lowe


You are correct, of course. I was thinking of cases like this:

http://www.python.org
HTTP://WWW.PYTHON.ORG
hTtP://www.PyThOn.ORG

So I should have said "hostnames" instead of "URLs". In my
experience, most URLs that are actually typed in are like this...

http://yahoo.com
http://google.com
http://ebay.com
http://apple.com
http://amazon.com

And in that form, they are not case sensitive. They only become that
way when you start putting more on the end. But I'd guess that 90%+
of the time, URLs of that form are clicked on, not typed into the
browser.

-dan
 

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,995
Messages
2,570,231
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top