[Python-Dev] New Import Hook & New Zip Importer

Just van Rossum just@letterror.com
Thu, 5 Dec 2002 02:00:23 +0100


--643623-2675965952-3248042441=:9000
Content-Type: text/plain; Charset=US-ASCII
Content-Transfer-Encoding: 7bit

Phew, it works.

The attached tgz file contains:
    zipper.patch: patches setup.py, Python/import.c, Python/importdl.h
    zipimport.c: zipimport module, move to Modules/

Do I need to mention it's a rough patch <wink>?

import.c changes:
    - Allow arbitrary objects on sys.path.
    - If a path entry ends in ".zip", replace that entry with
      a zipimporter instance. (obviously, the zipimport module
      must be available for this to work.)
    - The search algo is:
        [handle builtin modules and frozen]
        for p on sys.path:
            if hasattr(p, "find_module"):
                handler = p.find_module(name)
                if handler is None:
                    continue
            if isinstance(p, str):
                [do builtin import]

zipimport.c implements:
    - The zipimporter object; explicit use example:
          sys.path.append(zipimport.zipimporter("myarchive.zip"))
      this is effectively equivalent to
          sys.path.append("myarchive.zip")
    - the zipimporter has two methods:
        find_module(subname) -> None or self
        load_module(fullname) -> module

import.c todo/notes:
    - clean up, refactor, debug, document
    The patch adds two new static functions, find_module2() and
    load_module2(). Ideally these should _replace_ find_module and
    load_module, but since the signature of the new ones is different
    I decided to keep the originals (which are reimplemented to call
    the new ones) to keep the patch small for easier review.

zipimport.c todo:
    - rework the zipimporter class as a subclass of str
    - doco
    - add a get_source(fullname) method (linecache.py could use that!)

Have fun!

Just
--643623-2675965952-3248042441=:9000
Content-Type: application/octet-stream; Name="zipper.tgz"; X-Mac-Type="00000000"; X-Mac-Creator="00000000"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; Filename="zipper.tgz"

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
AHgAAA==
--643623-2675965952-3248042441=:9000--