[Python-Dev] Relative Package Imports

Tim Peters tim_one@email.msn.com
Wed, 15 Sep 1999 23:38:22 -0400


Sure is a lot of traffic on this -- can't we go back to hating the new
license <wink>?

[MAL]
> ...
> Sticking this technology into the import statement is really only
> a more elegant approach. Nothing more. The whole thing already
> works using the current Python implementation.

Your point there has been made many times -- I'm not missing it.  My point
has also been made many times, so one more can't hurt <wink>:  it still
looks to me like bad practice, so I don't *want* (more, actively oppose) it
to be made easier to spell.

>> + JimF and MAL's shared notion that they're the only ones making
significant
>>   use of packages is myopic.

> Oh, c'mon Tim, we never did say that. We only mentioned having used
> package for quite a while. This includes having seen all the different
> pitfalls they have to offer.

Well, JimF was laying it on a bit thick in two msgs, and sucked you in as
his implicit conspirator.  My apologies if you feel tarred unfairly.  Yet
you still can't resist implying that only you two are aware of the pitfalls
<wink>.

>> [on Dragon's "relentlessly straightforward" import policies]

> This is perfectly ok if you're just using your own code, but it
> gets a mess when third-party packages are involved simply because
> you can't be sure they don't use import hooks, local imports or
> hacks to __path__ etc. If you still want them to be useable, you'll
> have to go down and dive into their structure. This takes time, is
> error prone and not necessarily fun.

While true, it's much safer to install a "cheating" package at top level,
since the cheats presumably *assume* that's where the package is to be run
from.  If someone distributes a package that does not run correctly from top
level, that's one hopeless package.  Else it does run correctly from top
level, and then the only person with a problem here is one who insists on
running it from some embedded location.  You then buy the need to dive into
their code very carefully indeed -- relative imports don't save you from the
huge variety of "clever tricks" they *may* be playing with hooks and path
hacks.

But note that, unlike Jim (& perhaps you too), I have almost no fear of
top-level name collisions.  If we do nothing about that, it will be years
before it becomes a real problem; and several months before that <wink>, we
can flock to Java's hokey but effective reverse-domain scheme (which I
suspect you're already in favor of -- fine by me!).

> Also, I don't know how "explicitly, long-windedly and straightforwardly"
> writing module imports is any different from using relative imports.

Hugely and profoundly different, as your example shows:

> An example:
>
> mx
> 	.DateTime
> 	.ODBC.Windows
>
> In ODBC.Windows I would write:
>
> 	import __.__.DateTime
>
> which is just as explicit as writing
>
> 	import mx.DateTime
>
> except that the information about the top-level hierarchy is *not*
> included in the import information.

Exactly:  now instead of a bulletproof absolute import in a self-contained
importer, whose precise meaning is clear from casual static inspection,
you've got a relative one whose meaning depends vitally on where the
importer happens to live.  As code moves around, the import may fail to work
when you're lucky, or pick up an unintended DateTime package when you're
not.  The semantics of the import are indeed relative now:  you see the
opportunity to type three additional characters <wink> as a strength, and I
see nothing but headaches masquerading as convenience.

As further consequence, simple "search-and-replace" strategies are rendered
at best useless.  That is, a simple grep can no longer find all & only
references to mx's flavor of DateTime:  it picks up all references to all
DateTime guys, with no way short of a structure-aware tree crawler to sort
them out again.  Complexity spreads.

Of course, in the end, I lose no matter what.  If *everyone* used dirt-dumb
fully-qualified imports, all hassles with shifting package structure could
be solved with a text editor in seconds.  But that's not whiz-bang enough,
so people *will* play endlessly dubious tricks with hooks, paths, relative
imports, and metapackages too once Gordon gets around to them <wink>.
Having an explicit way to spell relative imports would make my life easier
because at least those are statically recognizable for what they are.  I
don't want them and won't use them, but it could ease the pain others will
cause by using them.  That's not enough to make me in favor of them, though;
just enough so I won't pout if they do go in.

> Anyway, I'm not too inclined continuing this discussion anymore.
> I would never have thought that such a nifty little patch would
> have stirred up so much negative response. I'll just hack up my
> very own import mechanism using imputil and be done. So there!

Don't feel picked on, M-A!  Opposition is normal and healthy; and the last
idea I got anywhere with was list.pop().

and-even-then-jimf-tried-to-stick-a-default-on-it<wink>-ly y'rs  - tim