Mailing List Archive

Alternative Approach to Relative Imports
Hi everybody,

I'm currently busy converting my code to use mx.DateTime instead
of just DateTime and must say that this is a real pain. Now instead
of reviving the __ discussion I'd like to turn to what could be
a workable compromise (I think Jim proposed something along these
lines already and there was similar code in ni.py).

The proposal is really only an addition to the lookup scheme
used by the importer. No additional syntax is involved and
best of all, it is backward compatible...

The current lookup does the following if you want to import
a module E from module A.B.C.D:

1. check A.B.C.E
2. check E
3. fail

Now instead of failing we could add a lookup method that
walks up the package structure:

3. check A.B.E
4. check A.E
[5. check E -- already done]
6. fail

so that the complete scheme looks like this:

1. check A.B.C.E
2. check E
3. check A.B.E
4. check A.E
[5. check E -- already done]
6. fail

That way I could leave intra-mx-package imports untouched and still
have the convenience of achieving the goal of making my mx
subpackages work in the mx context *plus* in the top-level
context thus allowing a backward compatible and flexible setup
for mx* users.

Note that the scheme finds exactly the same modules it did
previously, plus perhaps some more (which is intended), and
it does not involve any search path hacks.

How is that for a compromise ? [Ducking for cover ;-)]

--
Marc-Andre Lemburg
______________________________________________________________________
Y2000: 100 days left
Business: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/
Re: Alternative Approach to Relative Imports [ In reply to ]
[M.-A. Lemburg]
> The current lookup does the following if you want to import
> a module E from module A.B.C.D:
>
> 1. check A.B.C.E
> 2. check E
> 3. fail
>
> Now instead of failing we could add a lookup method that
> walks up the package structure:
>
> 3. check A.B.E
> 4. check A.E
> [5. check E -- already done]
> 6. fail
>
> so that the complete scheme looks like this:
>
> 1. check A.B.C.E
> 2. check E
> 3. check A.B.E
> 4. check A.E
> [5. check E -- already done]
> 6. fail
>
> That way I could leave intra-mx-package imports untouched and
> still have the convenience of achieving the goal of making my mx
> subpackages work in the mx context *plus* in the top-level
> context thus allowing a backward compatible and flexible setup
> for mx* users.

Comment 1: You're just giving yourself headaches by allowing
your users to install mx in anything other than the prescribed
manner.

Comment 2: I generally like this scheme, but think (for
consistency and confusion-reduction) that it should go straight
up the tree, instead of checking the root second.



- Gordon
Re: Alternative Approach to Relative Imports [ In reply to ]
Gordon McMillan wrote:
>
> [M.-A. Lemburg]
> > The current lookup does the following if you want to import
> > a module E from module A.B.C.D:
> >
> > 1. check A.B.C.E
> > 2. check E
> > 3. fail
> >
> > Now instead of failing we could add a lookup method that
> > walks up the package structure:
> >
> > 3. check A.B.E
> > 4. check A.E
> > [5. check E -- already done]
> > 6. fail
> >
> > so that the complete scheme looks like this:
> >
> > 1. check A.B.C.E
> > 2. check E
> > 3. check A.B.E
> > 4. check A.E
> > [5. check E -- already done]
> > 6. fail
> >
> > That way I could leave intra-mx-package imports untouched and
> > still have the convenience of achieving the goal of making my mx
> > subpackages work in the mx context *plus* in the top-level
> > context thus allowing a backward compatible and flexible setup
> > for mx* users.
>
> Comment 1: You're just giving yourself headaches by allowing
> your users to install mx in anything other than the prescribed
> manner.

Actually, I'm trying to provide them a way to smoothly switch
from the old setup to the new one. This includes myself, of
course ;-).

> Comment 2: I generally like this scheme, but think (for
> consistency and confusion-reduction) that it should go straight
> up the tree, instead of checking the root second.

That would probably break code because the search could
find some other module having the same name as a top-level
one. OTOH, perhaps that situation is not all the common to
fear too much about it.

Walking up all the way would certainly be easier to explain to
a 12-year old ;-)

--
Marc-Andre Lemburg
______________________________________________________________________
Y2000: 100 days left
Business: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/
Re: Alternative Approach to Relative Imports [ In reply to ]
> > Comment 2: I generally like this scheme, but think (for
> > consistency and confusion-reduction) that it should go straight
> > up the tree, instead of checking the root second.
>
> That would probably break code because the search could
> find some other module having the same name as a top-level
> one. OTOH, perhaps that situation is not all the common to
> fear too much about it.
>
> Walking up all the way would certainly be easier to explain to
> a 12-year old ;-)

Yes, please. Do the long-term understandable thing here. I expect
not too many packages have defined subpackages (or submodules) whose
name conflicts with a standard library module, so you ought to be
pretty safe here!

--Guido van Rossum (home page: http://www.python.org/~guido/)
Re: Alternative Approach to Relative Imports [ In reply to ]
Guido van Rossum wrote:
>
> > > Comment 2: I generally like this scheme, but think (for
> > > consistency and confusion-reduction) that it should go straight
> > > up the tree, instead of checking the root second.
> >
> > That would probably break code because the search could
> > find some other module having the same name as a top-level
> > one. OTOH, perhaps that situation is not all the common to
> > fear too much about it.
> >
> > Walking up all the way would certainly be easier to explain to
> > a 12-year old ;-)
>
> Yes, please. Do the long-term understandable thing here. I expect
> not too many packages have defined subpackages (or submodules) whose
> name conflicts with a standard library module, so you ought to be
> pretty safe here!

Walking straight up the tree is my preference. I think it is
very natural.

Jim

--
Jim Fulton mailto:jim@digicool.com Python Powered!
Technical Director (888) 344-4332 http://www.python.org
Digital Creations http://www.digicool.com http://www.zope.org

Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email
address may not be added to any commercial mail list with out my
permission. Violation of my privacy with advertising or SPAM will
result in a suit for a MINIMUM of $500 damages/incident, $1500 for
repeats.
Re: Alternative Approach to Relative Imports [ In reply to ]
On 22 September 1999, Guido van Rossum said:
> Yes, please. Do the long-term understandable thing here. I expect
> not too many packages have defined subpackages (or submodules) whose
> name conflicts with a standard library module, so you ought to be
> pretty safe here!

Especially since doing so doesn't work: for example, the
distutils.errors module started life as distutils.exceptions. That
changed pretty quickly, once I realized why putting

import exceptions

into other distutils modules didn't work -- obviously it didn't find my
distutils.exceptions. Arguably I should have used an absolute import,
but what the heck.

Greg
--
Greg Ward - software developer gward@cnri.reston.va.us
Corporation for National Research Initiatives
1895 Preston White Drive voice: +1-703-620-8990
Reston, Virginia, USA 20191-5434 fax: +1-703-620-0913
Re: Alternative Approach to Relative Imports [ In reply to ]
Greg Ward wrote:
>
> On 22 September 1999, Guido van Rossum said:
> > Yes, please. Do the long-term understandable thing here. I expect
> > not too many packages have defined subpackages (or submodules) whose
> > name conflicts with a standard library module, so you ought to be
> > pretty safe here!
>
> Especially since doing so doesn't work: for example, the
> distutils.errors module started life as distutils.exceptions. That
> changed pretty quickly, once I realized why putting
>
> import exceptions
>
> into other distutils modules didn't work -- obviously it didn't find my
> distutils.exceptions. Arguably I should have used an absolute import,
> but what the heck.

Wow, so many positive answers -- not bad after that last round of
relative imports ;-)

Ok, then I'll use the walk-me-up approach. That'll be coded
into a PathImporter class I'm writing for imputil which will
try to mimic the standard behaviour as much as possible (to be
released in a few weeks after my vacation).

--
Marc-Andre Lemburg
______________________________________________________________________
Y2000: 100 days left
Business: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/
RE: Alternative Approach to Relative Imports [ In reply to ]
> try to mimic the standard behaviour as much as possible (to be
> released in a few weeks after my vacation).

no no Marc - you should know the rules by now - you release it mere
hours _before_ your vacation :-) Enjoy!

Mark.
Re: Alternative Approach to Relative Imports [ In reply to ]
Mark Hammond wrote:
>
> > try to mimic the standard behaviour as much as possible (to be
> > released in a few weeks after my vacation).
>
> no no Marc - you should know the rules by now - you release it mere
> hours _before_ your vacation :-) Enjoy!

Ya, well ;-) I'll try my best... I already have something working
but it doesn't do the win32 + mac magic yet because that'll require
some additions to the builtin imp module. Also, I found that it
is rather slow when compared to the builtin one. Caches can
speed this up a little, but I still haven't achieved the same
performance.

BTW, while hacking along I found a few things that might be worth
discussing w/r to a general import hook scheme:

Currently, the imputil apporach uses a simple chaining technique.
Unfortunately, it doesn't allow inspecting the chain for already
loaded hooks, so the same type of hook could be loaded more than
once.

Also, there are at least two types of hooks:

1. hooks that redirect the import to some other data source

2. hooks that modify the way modules are searched

Since the first variant may well also be suited to used by
the second, the simple chaining method probably won't be
powerful enough to handle it.

I think what we really need is a set of register/deregister
APIs + some framework to differentiate between the two
hook types (and possibly other variants).

--
Marc-Andre Lemburg
______________________________________________________________________
Y2000: 98 days left
Business: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/
Re: Alternative Approach to Relative Imports [ In reply to ]
M.-A. Lemburg wrote:
>
> BTW, while hacking along I found a few things that might be worth
> discussing w/r to a general import hook scheme:
>
> Currently, the imputil apporach uses a simple chaining technique.
> Unfortunately, it doesn't allow inspecting the chain for already
> loaded hooks, so the same type of hook could be loaded more than
> once.
>
> Also, there are at least two types of hooks:
>
> 1. hooks that redirect the import to some other data source
>
> 2. hooks that modify the way modules are searched
>
> Since the first variant may well also be suited to used by
> the second, the simple chaining method probably won't be
> powerful enough to handle it.
>
> I think what we really need is a set of register/deregister
> APIs + some framework to differentiate between the two
> hook types (and possibly other variants).

Another quirk that I think needs fixing:

When I issues an import:

import mx.DateTime

the whole import is handled by the importer installed at
the start of the import. It is not possible to install a different
importer e.g. in mx/__init__.py to handle the rest of the
import (in this case the import of subpackage DateTime).
I think that the importer should honor the __importer__ function
(this is set by imputil) if present to let it continue the
import of subsequent elements in the dotted name.

Aside: Perhaps this is getting too technical for this list... should
I start an egroups mailing list for defining a new and more
flexible import mechanism ?

--
Marc-Andre Lemburg
______________________________________________________________________
Y2000: 98 days left
Business: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/
Re: Alternative Approach to Relative Imports [ In reply to ]
M.-A. Lemburg wrote:
[msg 1]
> Currently, the imputil apporach uses a simple chaining
> technique. Unfortunately, it doesn't allow inspecting the chain
> for already loaded hooks, so the same type of hook could be
> loaded more than once.

I was hoping Greg would jump in, but since he hasn't -

You're associating the hook with the strategy. That's the old
style. The imputil style is to associate the hook with the
actual stuff being managed. The strategy is a property of the
hook.

> Also, there are at least two types of hooks:
>
> 1. hooks that redirect the import to some other data source
>
> 2. hooks that modify the way modules are searched
>
> Since the first variant may well also be suited to used by the
> second, the simple chaining method probably won't be powerful
> enough to handle it.

The top level question is "is it mine to import?". Greg provides
a framework that makes it easy to use alternate data sources,
and alternate ways of finding things but that's not really the
key thing. You're a "good" importer if you can (when
appropriate) way "no it's not mine" efficiently.
[msg 2]
> Another quirk that I think needs fixing:
>
> When I issues an import:
>
> import mx.DateTime
>
> the whole import is handled by the importer installed at
> the start of the import. It is not possible to install a
> different importer e.g. in mx/__init__.py to handle the rest of
> the import (in this case the import of subpackage DateTime). I
> think that the importer should honor the __importer__ function
> (this is set by imputil) if present to let it continue the import
> of subsequent elements in the dotted name.

Sure you can. Your first importer is the "mx" importer. It has a
dict of sub-importers. When mx/DateTime/__init__.py runs, it
puts itself into that dict. The importer chain is now a tree.

This means, I think, that a "general" relative-path importer (ie,
one that uses the default PYTHONPATH strategy), should be
careful to install itself as the penultimate importer in the chain,
(ie, the last before __builtin__.imp). But putting a relative-path
search strategy into the "mx" importer is fine if it can quickly
determine that the target is / is not a valid name in the "mx"
namespace.

- Gordon
Re: Alternative Approach to Relative Imports [ In reply to ]
Gordon McMillan wrote:
>
> M.-A. Lemburg wrote:
> [msg 1]
> > Currently, the imputil apporach uses a simple chaining
> > technique. Unfortunately, it doesn't allow inspecting the chain
> > for already loaded hooks, so the same type of hook could be
> > loaded more than once.
>
> I was hoping Greg would jump in, but since he hasn't -
>
> You're associating the hook with the strategy. That's the old
> style. The imputil style is to associate the hook with the
> actual stuff being managed. The strategy is a property of the
> hook.

I know, but there still is no way to query what kind of hooks
are already loaded and what is worse, you cannot unload or reorder
them. I'd suggest using a list of hooks which are then
traversed in the order they appear in the list, e.g.

__importers__ = [DirectoryImporter('/usr/local/lib/python1.5'),
ArchiveImporter('/usr/local/lib/app.pyz'),
WebImporter('http://www.python.org/pylib/'),
PathImporter(('~/bin','~/lib'))]

This also has the advantage of being able to easily query
the importers during debugging and eliminates the need to
have a predefined attribute naming scheme (such as the one imputil
uses).

> > Also, there are at least two types of hooks:
> >
> > 1. hooks that redirect the import to some other data source
> >
> > 2. hooks that modify the way modules are searched
> >
> > Since the first variant may well also be suited to used by the
> > second, the simple chaining method probably won't be powerful
> > enough to handle it.
>
> The top level question is "is it mine to import?". Greg provides
> a framework that makes it easy to use alternate data sources,
> and alternate ways of finding things but that's not really the
> key thing. You're a "good" importer if you can (when
> appropriate) way "no it's not mine" efficiently.

It does a good job at this, but doesn't really separate
lookup and loading of code too well. Everything is packaged
into one single method (.get_code()) which is not always
flexible enough, e.g. it wasn't possible to implement the
walk-up-the-dotted-name scheme using modifications to
.get_code() alone.

Also, I can see many uses where you combine a lookup
hook (e.g. for loading modules across the web) with
a filtering hook (e.g. one which checks a module signature).

This should go into the framework as well, IMHO...
e.g. by having two methods .find_code() and .make_module()
(like the builtin importer).

> [msg 2]
> > Another quirk that I think needs fixing:
> >
> > When I issues an import:
> >
> > import mx.DateTime
> >
> > the whole import is handled by the importer installed at
> > the start of the import. It is not possible to install a
> > different importer e.g. in mx/__init__.py to handle the rest of
> > the import (in this case the import of subpackage DateTime). I
> > think that the importer should honor the __importer__ function
> > (this is set by imputil) if present to let it continue the import
> > of subsequent elements in the dotted name.
>
> Sure you can. Your first importer is the "mx" importer. It has a
> dict of sub-importers. When mx/DateTime/__init__.py runs, it
> puts itself into that dict. The importer chain is now a tree.

The problem is that the special importer has to be installed
*prior* to doing the mx.DateTime import, because otherwise
the importer will not take control over the DateTime subpackage
(unless I tell it to do so explicitly, which is not really
what I want to have to do).

> This means, I think, that a "general" relative-path importer (ie,
> one that uses the default PYTHONPATH strategy), should be
> careful to install itself as the penultimate importer in the chain,
> (ie, the last before __builtin__.imp). But putting a relative-path
> search strategy into the "mx" importer is fine if it can quickly
> determine that the target is / is not a valid name in the "mx"
> namespace.

Exactly... and this brings us back to the importer list
I mentioned above.

--
Marc-Andre Lemburg
______________________________________________________________________
Y2000: 98 days left
Business: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/
Re: Alternative Approach to Relative Imports [ In reply to ]
On Mon, 27 Sep 1999, Gordon McMillan wrote:
> M.-A. Lemburg wrote:
> [msg 1]
> > Currently, the imputil apporach uses a simple chaining
> > technique. Unfortunately, it doesn't allow inspecting the chain
> > for already loaded hooks, so the same type of hook could be
> > loaded more than once.
>
> I was hoping Greg would jump in, but since he hasn't -

I'm in a middle of a move back to CA. Unpacking now...

> You're associating the hook with the strategy. That's the old
> style. The imputil style is to associate the hook with the
> actual stuff being managed. The strategy is a property of the
> hook.

Quite true. The chaining is simply an artifact of what has been installed
as the import hook. I've always envisioned the potential for a "Importer
Manager" that installs just like any other hook, but provides higher-level
functions for importers to install themselves. The manager simply
delegates the get_code() function to the sub-importers. Of course, the
manager could use whatever technique to improve the speed of Importer
selection.

With respect to speed, I think the main point is to realize that the
imputil technique is not inherently slow. It just depends on how you
design your Importer subclasses -- do you install one or a hundred
Importers?

The imputil scheme is more about simplifying how people hook into the
process (implement get_code() rather than a load/import combo). It also
provides a simple capability (chaining) to allow *multiple* hooks to be
installed.

> > Also, there are at least two types of hooks:
> >
> > 1. hooks that redirect the import to some other data source
> >
> > 2. hooks that modify the way modules are searched

Just one way -- your second is a variant of the first. "other data source"
is a functional superset which includes searching. Importers don't simply
alter searching -- they must perform the actual import (from wherever).

This is the big change in mindset from the "ihooks" method -- find it and
import it on the spot. The net effect is an Importer either imports a
module or it doesn't (and the system can fallback to try another
Importer).

[. one the examples that people always like to specify was importing via
URL which was actually quite difficult to use in the old scheme -- how do
you separate an HTTP GET into a find/load step? Effectively, you had to
double-fetch, or you had to place the whole module (which you retrieved
during the find step) into your context for passing to the load. The other
issue was the distinct semantics also implied that you could separate the
functions -- I believe that to be quite unnecessary functionality. ]

> > Since the first variant may well also be suited to used by the
> > second, the simple chaining method probably won't be powerful
> > enough to handle it.
>
> The top level question is "is it mine to import?". Greg provides
> a framework that makes it easy to use alternate data sources,
> and alternate ways of finding things but that's not really the
> key thing. You're a "good" importer if you can (when
> appropriate) way "no it's not mine" efficiently.

Very true!

> [msg 2]
> > Another quirk that I think needs fixing:
> >
> > When I issues an import:
> >
> > import mx.DateTime
> >
> > the whole import is handled by the importer installed at
> > the start of the import. It is not possible to install a
> > different importer e.g. in mx/__init__.py to handle the rest of
> > the import (in this case the import of subpackage DateTime). I
> > think that the importer should honor the __importer__ function
> > (this is set by imputil) if present to let it continue the import
> > of subsequent elements in the dotted name.
>
> Sure you can. Your first importer is the "mx" importer. It has a
> dict of sub-importers. When mx/DateTime/__init__.py runs, it
> puts itself into that dict. The importer chain is now a tree.

Gordon's on top of it here... :-) Yes, it is simply a matter of
perspective on the import process. An importer does not have to be a
static entity. It also can be much more than a way to search a path... it
can be highly dynamic and flexible. Whatever you like. Just implement
get_code() to map a module "mx.DateTime" to a code/module object. There
are a bazillion ways to do that :-)

> This means, I think, that a "general" relative-path importer (ie,
> one that uses the default PYTHONPATH strategy), should be
> careful to install itself as the penultimate importer in the chain,
> (ie, the last before __builtin__.imp). But putting a relative-path
> search strategy into the "mx" importer is fine if it can quickly
> determine that the target is / is not a valid name in the "mx"
> namespace.

Part of the Importer work was done to satisfy importing modules from the
COM+ namespace. I wanted to be able to say "import COM.foo.bar". The
importer would handle all "COM." imports and delegate the "foo.bar" to the
underlying Python/COM framework.

In other words... yes, the Importer scheme should work *very* well for
the "whatever...." type of module namespace.

Cheers,
-g

--
Greg Stein, http://www.lyra.org/
Re: Alternative Approach to Relative Imports [ In reply to ]
Greg Stein wrote:
>
> On Mon, 27 Sep 1999, Gordon McMillan wrote:
> > M.-A. Lemburg wrote:
> > [msg 1]
> > > Currently, the imputil apporach uses a simple chaining
> > > technique. Unfortunately, it doesn't allow inspecting the chain
> > > for already loaded hooks, so the same type of hook could be
> > > loaded more than once.
> > You're associating the hook with the strategy. That's the old
> > style. The imputil style is to associate the hook with the
> > actual stuff being managed. The strategy is a property of the
> > hook.
>
> Quite true. The chaining is simply an artifact of what has been installed
> as the import hook. I've always envisioned the potential for a "Importer
> Manager" that installs just like any other hook, but provides higher-level
> functions for importers to install themselves. The manager simply
> delegates the get_code() function to the sub-importers. Of course, the
> manager could use whatever technique to improve the speed of Importer
> selection.
>
> With respect to speed, I think the main point is to realize that the
> imputil technique is not inherently slow. It just depends on how you
> design your Importer subclasses -- do you install one or a hundred
> Importers?
>
> The imputil scheme is more about simplifying how people hook into the
> process (implement get_code() rather than a load/import combo). It also
> provides a simple capability (chaining) to allow *multiple* hooks to be
> installed.

As I wrote in my reply to Gordon, this setup has some drawbacks
which an "Import Manager" could easily solve, e.g. by using a
list of importers.

> > > Also, there are at least two types of hooks:
> > >
> > > 1. hooks that redirect the import to some other data source
> > >
> > > 2. hooks that modify the way modules are searched
>
> Just one way -- your second is a variant of the first. "other data source"
> is a functional superset which includes searching. Importers don't simply
> alter searching -- they must perform the actual import (from wherever).

Yes, I was just argueing for two types of functionality, not the
old scheme. E.g. the Import Manager could provide a set of
filters which implement signature checks or know how to un-gzip
code plus a set of lookup functions for scanning directories
or zip archives.

I would like the importers to take advantage of such functionality.
Of course, all of this could be implemented in form of classes
which the importers then use as mixin classes.

> This is the big change in mindset from the "ihooks" method -- find it and
> import it on the spot. The net effect is an Importer either imports a
> module or it doesn't (and the system can fallback to try another
> Importer).
>
> [. one the examples that people always like to specify was importing via
> URL which was actually quite difficult to use in the old scheme -- how do
> you separate an HTTP GET into a find/load step? Effectively, you had to
> double-fetch, or you had to place the whole module (which you retrieved
> during the find step) into your context for passing to the load. The other
> issue was the distinct semantics also implied that you could separate the
> functions -- I believe that to be quite unnecessary functionality. ]

.get_code() is fine for these kind of tasks, but there are
some other areas (such as lazy imports) which work better
using the split setup. This is pretty easy to implement btw,
just have the Import Manager check whether the importer provides
.get_code() and then have it revert to using .find_module(),
.load_module() if it doesn't.

The more I think about it, the more I like the idea of an
Import Manager instead of the chaining approach.

> > > Since the first variant may well also be suited to used by the
> > > second, the simple chaining method probably won't be powerful
> > > enough to handle it.
> >
> > The top level question is "is it mine to import?". Greg provides
> > a framework that makes it easy to use alternate data sources,
> > and alternate ways of finding things but that's not really the
> > key thing. You're a "good" importer if you can (when
> > appropriate) way "no it's not mine" efficiently.
>
> Very true!
>
> > [msg 2]
> > > Another quirk that I think needs fixing:
> > >
> > > When I issues an import:
> > >
> > > import mx.DateTime
> > >
> > > the whole import is handled by the importer installed at
> > > the start of the import. It is not possible to install a
> > > different importer e.g. in mx/__init__.py to handle the rest of
> > > the import (in this case the import of subpackage DateTime). I
> > > think that the importer should honor the __importer__ function
> > > (this is set by imputil) if present to let it continue the import
> > > of subsequent elements in the dotted name.
> >
> > Sure you can. Your first importer is the "mx" importer. It has a
> > dict of sub-importers. When mx/DateTime/__init__.py runs, it
> > puts itself into that dict. The importer chain is now a tree.
>
> Gordon's on top of it here... :-) Yes, it is simply a matter of
> perspective on the import process. An importer does not have to be a
> static entity. It also can be much more than a way to search a path... it
> can be highly dynamic and flexible. Whatever you like. Just implement
> get_code() to map a module "mx.DateTime" to a code/module object. There
> are a bazillion ways to do that :-)

Except that they don't work due to the fact that the
builtin importer is not recursively using __import__ for the imports.
An Import Manager would help with this too :-)

> > This means, I think, that a "general" relative-path importer (ie,
> > one that uses the default PYTHONPATH strategy), should be
> > careful to install itself as the penultimate importer in the chain,
> > (ie, the last before __builtin__.imp). But putting a relative-path
> > search strategy into the "mx" importer is fine if it can quickly
> > determine that the target is / is not a valid name in the "mx"
> > namespace.
>
> Part of the Importer work was done to satisfy importing modules from the
> COM+ namespace. I wanted to be able to say "import COM.foo.bar". The
> importer would handle all "COM." imports and delegate the "foo.bar" to the
> underlying Python/COM framework.
>
> In other words... yes, the Importer scheme should work *very* well for
> the "whatever...." type of module namespace.

--
Marc-Andre Lemburg
______________________________________________________________________
Y2000: 98 days left
Business: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/
Re: Alternative Approach to Relative Imports [ In reply to ]
"M.-A. Lemburg" wrote:
>
> I know, but there still is no way to query what kind of hooks
> are already loaded and what is worse, you cannot unload or reorder
> them.

I think this is a valid point. I am interested in hooks to read
modules from a file archive. If you are a developer, it is
necessary to turn this hook OFF, so that you can revert to the
usual directory tree where your current source is.

I am solving this by leaving a global variable "Importer" in
sitecustomize, and calling sitecustomize.Importer.enable(0).
This works, but it might be useful if imputil could de-install
a hook as well as install it.

Jim Ahlstrom
Re: Alternative Approach to Relative Imports [ In reply to ]
On Wed, 29 Sep 1999, James C. Ahlstrom wrote:
> "M.-A. Lemburg" wrote:
> > I know, but there still is no way to query what kind of hooks
> > are already loaded and what is worse, you cannot unload or reorder
> > them.
>
> I think this is a valid point. I am interested in hooks to read
> modules from a file archive. If you are a developer, it is
> necessary to turn this hook OFF, so that you can revert to the
> usual directory tree where your current source is.
>
> I am solving this by leaving a global variable "Importer" in
> sitecustomize, and calling sitecustomize.Importer.enable(0).
> This works, but it might be useful if imputil could de-install
> a hook as well as install it.

It was a design point to not provide this functionality. It is pretty
difficult to unhook the importers from the chain. I specifically said,
"well... when you alter the import behavior, then it will stay that way."

I figured this was entirely safe since an Importer could have an
enable/disable flag like you implemented, or my (theoretical) Import
Manager could pull an Importer out of its list that it was managing.

I'm not sure that we want an Import Manager to always be installed in the
hooks, but it could be a good idea to have a standard manager in the
library somewhere (which Importers could state a dependency upon its
installation).

Cheers,
-g

--
Greg Stein, http://www.lyra.org/
Re: Alternative Approach to Relative Imports [ In reply to ]
Greg Stein wrote:

> It was a design point to not provide this functionality. It is pretty
> difficult to unhook the importers from the chain. I specifically said,
> "well... when you alter the import behavior, then it will stay that way."
>
> I figured this was entirely safe since an Importer could have an
> enable/disable flag like you implemented, or my (theoretical) Import
> Manager could pull an Importer out of its list that it was managing.

I think my design of leaving a global "Importer" instance variable
in imputil is a bit lame. Each importer is a class instance, but I
don't see a list of importers in imputil.

Suppose impuil kept a list of installed importers
imputil.ImporterList[].
Then to access an importer I have installed, I can write:
for im in imputil.ImporterList:
if isinstance(im, MyImporter):
im.enable(0)
It would not be necessary to dis-install an importer, imputil would
just undertake to keep a list of installed importers, and if someone
wanted to control their installed importers, they would use the list.

I do not feel too strongly about this. Maybe it is a good idea.
What do you think? I can just use my global variable I guess.

Jim Ahlstrom