PyWart: "Python's import statement and the history of external dependencies"

Rick Johnson rantingrickjohnson at gmail.com
Fri Nov 21 04:53:29 CET 2014


On Thursday, November 20, 2014 6:15:03 PM UTC-6, alex23 wrote:
> On 16/11/2014 3:01 PM, Rick Johnson wrote:
> [...]
> > Actually, Python is not alone in this deficiency, no, Python
> > is just *ANOTHER* language in a *STRING* of languages over
> > the years who has *YET AGAIN* implemented the same old
> > crusty design patterns, packaged them in a shiny metallic
> > wrapping paper with a big red bow on top, and hoped that no
> > one would notice the stench...
>
> Are you sure that's not just you?
>
> >      1. Name clashes!
> >      2. Smaller name pool!
>
>
> Just off the top of my head, we have several solutions for
> this:
>
> 1) Rebinding imports
>
>      import foo as foo2
>
> 2) Namespace packages
>
>      import mypackage.foo

I was not talking about name clashes within the script
(which are the problem of the programmer, because he and
only he has *DIRECT* control over the contents of any
scripts he writes!) no, i was talking about two or more
modules who share the same name who then, in effect,
*SHADOW* each other (this is problem for which the
programmer *CANNOT* solve *INTUITIVELY* because he cannot
*EASILY* control the manner in which the underlying import
mechanism finds modules). If you had taken the time to read
my example utilizing a "lobby boy", then you might have
understood what i was talking about.

FOR INSTANCE: Let's say i write a module that presents a
reusable GUI calendar widget, and then i name the module
"calender.py".

Then Later, when i try to import *MY* GUI widget named
"calendar", i will not get *MY* calendar widget, no, i will
get the Python calendar module.

The reason Python finds the library module instead of my
module is because the Python library is higher in search
path than my module.

OKAY, FAIR ENOUGH...

Now, i could *TRY* to be "cleaver" and inject the directory
that holds *MY* "calendar module" as the *FIRST* directory
of sys.path, and this will work, but it's a TOTAL FREAKING
HACK, and unbeknownst to most first-time "import hackers",
the changes to sys.path does not only affect the "contents" of
sys.path within the "current module", but *ALL* modules
further down the "import chain" will suffer the changes!

############################################################
#                        BE WARNED:                        #
############################################################
# Contrary to popular belief, sys.path is *NOT* a module,  #
# no, it's a global!                                       #
############################################################

This is another confusing fundamental of Python, it seems *MORE*
intuitive that changes to the "import search path" would only
affect the *CURRENT* module's "import search path", but that's
is not the case!

############################################################
#                    Lesson Of The Day                     #
############################################################
# Try to be intuitive, and python will *break* you!        #
############################################################

And you know why, it's because our "dear leaders" have this
irrational phobia of global variables. But the joke is on
them, because they fail to realize that importing a module
into more than one namespace is creating globals!

    YOU CAN PUT LIPSTICK ON A PIG, BUT IT'S STILL A PIG!

This is what happens when your emperor stops wearing
clothes, and more proof that Python's import mechanism sucks
dingo balls!

Now some people will say: "Don't name your modules the same
as a Python library modules and problem solved!"

Sorry, but that's not good enough for me! I believe that the
current import mechanism is only *HALF* of what it should
be. Currently, import uses an "implicit" name resolution via
predefined paths in sys.path, and for 75% of the time, this
"implicit" import mechanism will work just fine -- it's a
slow algorithm, but fast enough for humans not to notice.

HOWEVER,

in the 25% of cases where *NAME SHADOWING* or where the
author knows the location and can specify the location to
save "lobby boy" from knocking on doors until his knuckles
bleed, the author should have an option defining the search
path *LOCALLY* (in a manner that will *NOT* affect the
"import search path" further down the import chain), WITHOUT
needing to import one of the many discombobulated and
confusing import tools that Python has tortured this
community with.


>
> 3) Filepath imports (deprecated in 3.4 but under discussion for
> reprecation or replacement)
>
>      import importlib.machinery
>
>      loader = importlib.machinery.SourceFileLoader("module.name",
>          "/path /to/file.py")
>      foo = loader.load_module()
>      foo.MyClass()

That's ridiculously noisy. I have an idea, if you *REALLY*
want to introduce boilerplate hell then Python should adopt
"import header files", NOT!

> 4) Virtual environments
>
> In before "but WHY so MANY different WAYS OMG PYTHON you
> M.F.P.O.S.": because they offer flexibility.
>
> >      3. Machinery is too implicit!
>
> See: importlib
>
> >      4. Circular imports are inevitable!
>
> They're also clear indication of bad design. That's not
> something Python should explicitly set out to support.

I think your confusing "circular references" with "circular
imports", and while the two have much in common, and both
should be avoid when possible, there are times when both are
unavoidable (if you want to write sane code!). But this a
discussion better suited to a thread of it's own.

> >      5. Much too difficult to use and/or explain!
>
> Well sure, if your reaction to things you don't understand
> is to rant against them instead of asking questions, then
> I can see how that would be true.

I've asked questions on this list, and you know what kind of
help i get, NONE! I can distinctly remember asking D'Aprano
to help explain the new format method and he flat out
refused, even though he time for "Devils Advocating", he had
no time to help me -- go figure!

The only time i get *real* help from people on this list is
when i ask them privately. I won't mention any names but it
would be nice to feel like a welcomed member who could
participate fully.

You may not believe me, but i have seen some major
improvements in the community since i've been here. Whilst
my complaints to the caretakers of Python.org about the
lackluster and discombobulated nature of the site were
initially taken as offensive, i was pleased to see my
recommendations fully implemented within a year or so. Heck,
i can remember a time when you had to navigate four or five
pages (from the home page) just to see the damn docs, now,
both 2.x and 3.x docs are just a single click away!

    THANKS RICK!

About three years ago i started contacting every owner of a
major Python tutorial and pleaded with them to upgrade
their tuts to Python 3.x, again, some took the advice as
offensive, but most of them finally admitted the importance
of sticking to the latest Python version.

    THANKS RICK!

Probably my proudest achievement is to see all the
neophytes who have gained the courage to interact with this
community. Before i came along, most of them hide in the
shadows and only watched, unwilling to participate for fear
of ridicule by our rabid attack dogs. But, after witnessing
the hell that i went through, and my public lynching, but
then my triumphant rise as like a "Phoenix From The Ashes",
they realized that the fearless can *NEVER* be defeated, and
that those who carry *ABSOLUTE* resolve to succeed, *WILL*
succeed -- even if they don't get *ANY* credit for their
contributions!

    THANKS RICK!

PS: You have to pat *yourself* on the back 'round here.




More information about the Python-list mailing list