Case sensitivity

Alex Martelli aleax at aleax.it
Tue Feb 25 17:29:40 CET 2003


Martijn Faassen wrote:
   ...

> fooBarism = FooBarism()
> 
> could be easily repaired, but is this *idiotic*? May be misguided, but

I apologize for being politically incorrect here in my choice of
terms.  If you'll accept, say, three months with biweekly long
distance phone meetings of one hour each where you have to discuss
this subtle and elegant design, and still emerge thinking that
"misguided" is the correct term to use for this no doubt excellent
choice, I'll be overjoyed to nominate you for the Nobel prize for
Peace, too.


> ability to instantiate a class with its same name, which I'd miss,

I wonder if you'd still miss it so much after those hypothetical
three months.  (I'm not going to discuss the subtler issue of vision
impaired programmers using screen-readers, because there are other
issues there -- nothing a decent _parser_ pronouncing "INDENT" and
"DEDENT" couldn't alleviate, I think, which is much easier than
determining which sets of identifiers are being discriminated only
on the basis of capitalization and thus need to be pronounced
differently -- but, hm, I said I _would_ discuss this...;-).

In the "compromise proposal" I was mentioning, such subtle and
admirable elegance might still be OK in _local_ scope, btw -- as
long as it's not the case that arbiterelegantiarum and
ArbiterElegantiarum are both exposed in the same scope, I'd
still be a pretty happy camper.  Module-level names are even
relatively easy to check -- it's harder for class based things,
of course, given the subtleties of inheritance, __getattr__,
and the like.  The same subtleties are what would make it not
too difficult to fake case-insensitive _access_ to attributes
in other modules.  For example, just to play...:


def happycamper(modobj):
    class faker:
        def __init__(self, modobj):
            for attrname in dir(modobj):
                if attrname.startswith('_'): continue
                lowername = attrname.lower()
                if hasattr(self, lowername):
                   raise ValueError, "case conflict on %r" % attrname
                setattr(self, lowername, getattr(modobj, attrname))
        def __getattr__(self, name):
            try: return self.__dict__[name.lower()]
            except KeyError: raise AttributeError, name
    return faker(modobj)

import audiodev
audiodev = happycamper(audiodev)

print audiodev.audiodev


Ah -- and the world is bright again!-)

[well -- unless one also wants to reload, I guess...;-)]


Of course, simulating the proposed compromise requires a bit
more subtlety -- a given instance of class faker should not
allow the same attribute to be FETCHED with different cases.

That's not hard though (hint: don't set attributes on self
*at __init__* but only when they're first fetched -- and when an
attribute IS first fetched, setattr it with the case it's being
fetched with, AND remove it from whatever container you put it
on at __init__ time, so future fetches with different case will
miserably fail...) and I'll gladly leave it as an exercise for
the case-obsessed;-).


> but I think I could live with that. As long as modules themselves are
> case-consistent.

Granted.  I see no added value in allowing *a single source file*
to spell the same name in a given scope in 2**N different ways
(when N is the number of letters in that name), anyway.


Alex





More information about the Python-list mailing list