2001-02-20 22:40:36 -05:00
|
|
|
|
PEP: 235
|
|
|
|
|
Title: Import on Case-Insensitive Platforms
|
|
|
|
|
Version: $Revision$
|
|
|
|
|
Author: Tim Peters <tim@digicool.com>
|
|
|
|
|
Status: Draft
|
|
|
|
|
Type: Standards Track
|
2001-02-20 22:41:08 -05:00
|
|
|
|
Python-Version: 2.1
|
2001-02-20 22:40:36 -05:00
|
|
|
|
Post-History: 16 February 2001
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note
|
|
|
|
|
|
|
|
|
|
This is essentially a retroactive PEP: the issue came up too late
|
|
|
|
|
in the 2.1 release process to solicit wide opinion before deciding
|
|
|
|
|
what to do, and can't be put off until 2.2 without also delaying
|
|
|
|
|
the Cygwin and MacOS X ports.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Motivation
|
|
|
|
|
|
|
|
|
|
File systems vary across platforms in whether or not they preserve
|
|
|
|
|
the case of filenames, and in whether or not the platform C
|
|
|
|
|
library file-opening functions do or don't insist on
|
|
|
|
|
case-sensitive matches:
|
|
|
|
|
|
|
|
|
|
case-preserving case-destroying
|
|
|
|
|
+-------------------+------------------+
|
|
|
|
|
case-sensitive | most Unix flavors | brrrrrrrrrr |
|
|
|
|
|
+-------------------+------------------+
|
|
|
|
|
case-insensitive | Windows | some unfortunate |
|
|
|
|
|
| MacOSX HFS+ | network schemes |
|
|
|
|
|
| Cygwin | |
|
|
|
|
|
| | OpenVMS |
|
|
|
|
|
+-------------------+------------------+
|
|
|
|
|
|
|
|
|
|
In the upper left box, if you create "fiLe" it's stored as "fiLe",
|
|
|
|
|
and only open("fiLe") will open it (open("file") will not, nor
|
|
|
|
|
will the 14 other variations on that theme).
|
|
|
|
|
|
|
|
|
|
In the lower right box, if you create "fiLe", there's no telling
|
|
|
|
|
what it's stored as -- but most likely as "FILE" -- and any of the
|
|
|
|
|
16 obvious variations on open("FilE") will open it.
|
|
|
|
|
|
|
|
|
|
The lower left box is a mix: creating "fiLe" stores "fiLe" in the
|
|
|
|
|
platform directory, but you don't have to match case when opening
|
|
|
|
|
it; any of the 16 obvious variations on open("FILe") work.
|
|
|
|
|
|
|
|
|
|
NONE OF THAT IS CHANGING! Python will continue to follow platform
|
|
|
|
|
conventions w.r.t. whether case is preserved when creating a file,
|
|
|
|
|
and w.r.t. whether open() requires a case-sensitive match. In
|
|
|
|
|
practice, you should always code as if matches were
|
|
|
|
|
case-sensitive, else your program won't be portable.
|
|
|
|
|
|
|
|
|
|
What's proposed is to change the semantics of Python "import"
|
|
|
|
|
statements, and there *only* in the lower left box.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Current Lower-Left Semantics
|
|
|
|
|
|
|
|
|
|
Support for MacOSX HFS+, and for Cygwin, is new in 2.1, so nothing
|
|
|
|
|
is changing there. What's changing is Windows behavior. Here are
|
|
|
|
|
the current rules for import on Windows:
|
|
|
|
|
|
|
|
|
|
1. Despite that the filesystem is case-insensitive, Python insists
|
|
|
|
|
on a case-sensitive match. But not in the way the upper left
|
|
|
|
|
box works: if you have two files, FiLe.py and file.py on
|
|
|
|
|
sys.path, and do
|
|
|
|
|
|
|
|
|
|
import file
|
|
|
|
|
|
|
|
|
|
then if Python finds FiLe.py first, it raises a NameError. It
|
|
|
|
|
does *not* go on to find file.py; indeed, it's impossible to
|
|
|
|
|
import any but the first case-insensitive match on sys.path,
|
|
|
|
|
and then only if case matches exactly in the first
|
|
|
|
|
case-insensitive match.
|
|
|
|
|
|
|
|
|
|
2. An ugly exception: if the first case-insensitive match on
|
|
|
|
|
sys.path is for a file whose name is entirely in upper case
|
|
|
|
|
(FILE.PY or FILE.PYC or FILE.PYO), then the import silently
|
|
|
|
|
grabs that, no matter what mixture of case was used in the
|
|
|
|
|
import statement. This is apparently to cater to miserable old
|
|
|
|
|
filesystems that really fit in the lower right box. But this
|
|
|
|
|
exception is unique to Windows, for reasons that may or may not
|
|
|
|
|
exist.
|
|
|
|
|
|
|
|
|
|
3. And another exception: if the environment variable PYTHONCASEOK
|
|
|
|
|
exists, Python silently grabs the first case-insensitive match
|
|
|
|
|
of any kind.
|
|
|
|
|
|
|
|
|
|
So these Windows rules are pretty complicated, and neither match
|
|
|
|
|
the Unix rules nor provide semantics natural for the native
|
|
|
|
|
filesystem. That makes them hard to explain to Unix *or* Windows
|
|
|
|
|
users. Nevertheless, they've worked fine for years, and in
|
|
|
|
|
isolation there's no compelling reason to change them.
|
|
|
|
|
|
|
|
|
|
However, that was before the MacOSX HFS+ and Cygwin ports arrived.
|
|
|
|
|
They also have case-preserving case-insensitive filesystems, but
|
|
|
|
|
the people doing the ports despised the Windows rules. Indeed, a
|
|
|
|
|
patch to make HFS+ act like Unix for imports got past a reviewer
|
|
|
|
|
and into the code base, which incidentally made Cygwin also act
|
|
|
|
|
like Unix (but this met the unbounded approval of the Cygwin
|
|
|
|
|
folks, so they sure didn't complain -- they had patches of their
|
|
|
|
|
own pending to do this, but the reviewer for those balked).
|
|
|
|
|
|
|
|
|
|
At a higher level, we want to keep Python consistent, by following
|
|
|
|
|
the same rules on *all* platforms with case-preserving
|
|
|
|
|
case-insensitive filesystems.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Proposed Semantics
|
|
|
|
|
|
|
|
|
|
The proposed new semantics for the lower left box:
|
|
|
|
|
|
|
|
|
|
A. If the PYTHONCASEOK environment variable exists, same as
|
|
|
|
|
before: silently accept the first case-insensitive match of any
|
|
|
|
|
kind; raise ImportError if none found.
|
|
|
|
|
|
|
|
|
|
B. Else search sys.path for the first case-sensitive match; raise
|
|
|
|
|
ImportError if none found.
|
|
|
|
|
|
|
|
|
|
#B is the same rule as is used on Unix, so this will improve cross-
|
|
|
|
|
platform portability. That's good. #B is also the rule the Mac
|
|
|
|
|
and Cygwin folks want (and wanted enough to implement themselves,
|
|
|
|
|
multiple times, which is a powerful argument in PythonLand). It
|
|
|
|
|
can't cause any existing non-exceptional Windows import to fail,
|
|
|
|
|
because any existing non-exceptional Windows import finds a
|
|
|
|
|
case-sensitive match first in the path -- and it still will. An
|
|
|
|
|
exceptional Windows import currently blows up with a NameError or
|
|
|
|
|
ImportError, in which latter case it still will, or in which
|
|
|
|
|
former case will continue searching, and either succeed or blow up
|
|
|
|
|
with an ImportError.
|
|
|
|
|
|
|
|
|
|
#A is needed to cater to case-destroying filesystems mounted on Windows,
|
|
|
|
|
and *may* also be used by people so enamored of "natural" Windows
|
|
|
|
|
behavior that they're willing to set an environment variable to
|
|
|
|
|
get it. I don't intend to implement #A for Unix too, but that's
|
|
|
|
|
just because I'm not clear on how I *could* do so efficiently (I'm
|
|
|
|
|
not going to slow imports under Unix just for theoretical purity).
|
|
|
|
|
|
|
|
|
|
The potential damage is here: #2 (matching on ALLCAPS.PY) is
|
|
|
|
|
proposed to be dropped. Case-destroying filesystems are a
|
|
|
|
|
vanishing breed, and support for them is ugly. We're already
|
|
|
|
|
supporting (and will continue to support) PYTHONCASEOK for their
|
|
|
|
|
benefit, but they don't deserve multiple hacks in 2001.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Local Variables:
|
|
|
|
|
mode: indented-text
|
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
|
End:
|