~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Lib/pkgutil.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""Utilities to support packages."""
 
2
 
 
3
# NOTE: This module must remain compatible with Python 2.3, as it is shared
 
4
# by setuptools for distribution with Python 2.3 and up.
 
5
 
 
6
import os
 
7
import sys
 
8
import imp
 
9
import os.path
 
10
from types import ModuleType
 
11
 
 
12
__all__ = [
 
13
    'get_importer', 'iter_importers', 'get_loader', 'find_loader',
 
14
    'walk_packages', 'iter_modules',
 
15
    'ImpImporter', 'ImpLoader', 'read_code', 'extend_path',
 
16
]
 
17
 
 
18
def read_code(stream):
 
19
    # This helper is needed in order for the PEP 302 emulation to
 
20
    # correctly handle compiled files
 
21
    import marshal
 
22
 
 
23
    magic = stream.read(4)
 
24
    if magic != imp.get_magic():
 
25
        return None
 
26
 
 
27
    stream.read(4) # Skip timestamp
 
28
    return marshal.load(stream)
 
29
 
 
30
 
 
31
def simplegeneric(func):
 
32
    """Make a trivial single-dispatch generic function"""
 
33
    registry = {}
 
34
    def wrapper(*args, **kw):
 
35
        ob = args[0]
 
36
        try:
 
37
            cls = ob.__class__
 
38
        except AttributeError:
 
39
            cls = type(ob)
 
40
        try:
 
41
            mro = cls.__mro__
 
42
        except AttributeError:
 
43
            try:
 
44
                class cls(cls, object):
 
45
                    pass
 
46
                mro = cls.__mro__[1:]
 
47
            except TypeError:
 
48
                mro = object,   # must be an ExtensionClass or some such  :(
 
49
        for t in mro:
 
50
            if t in registry:
 
51
                return registry[t](*args, **kw)
 
52
        else:
 
53
            return func(*args, **kw)
 
54
    try:
 
55
        wrapper.__name__ = func.__name__
 
56
    except (TypeError, AttributeError):
 
57
        pass    # Python 2.3 doesn't allow functions to be renamed
 
58
 
 
59
    def register(typ, func=None):
 
60
        if func is None:
 
61
            return lambda f: register(typ, f)
 
62
        registry[typ] = func
 
63
        return func
 
64
 
 
65
    wrapper.__dict__ = func.__dict__
 
66
    wrapper.__doc__ = func.__doc__
 
67
    wrapper.register = register
 
68
    return wrapper
 
69
 
 
70
 
 
71
def walk_packages(path=None, prefix='', onerror=None):
 
72
    """Yields (module_loader, name, ispkg) for all modules recursively
 
73
    on path, or, if path is None, all accessible modules.
 
74
 
 
75
    'path' should be either None or a list of paths to look for
 
76
    modules in.
 
77
 
 
78
    'prefix' is a string to output on the front of every module name
 
79
    on output.
 
80
 
 
81
    Note that this function must import all *packages* (NOT all
 
82
    modules!) on the given path, in order to access the __path__
 
83
    attribute to find submodules.
 
84
 
 
85
    'onerror' is a function which gets called with one argument (the
 
86
    name of the package which was being imported) if any exception
 
87
    occurs while trying to import a package.  If no onerror function is
 
88
    supplied, ImportErrors are caught and ignored, while all other
 
89
    exceptions are propagated, terminating the search.
 
90
 
 
91
    Examples:
 
92
 
 
93
    # list all modules python can access
 
94
    walk_packages()
 
95
 
 
96
    # list all submodules of ctypes
 
97
    walk_packages(ctypes.__path__, ctypes.__name__+'.')
 
98
    """
 
99
 
 
100
    def seen(p, m={}):
 
101
        if p in m:
 
102
            return True
 
103
        m[p] = True
 
104
 
 
105
    for importer, name, ispkg in iter_modules(path, prefix):
 
106
        yield importer, name, ispkg
 
107
 
 
108
        if ispkg:
 
109
            try:
 
110
                __import__(name)
 
111
            except ImportError:
 
112
                if onerror is not None:
 
113
                    onerror(name)
 
114
            except Exception:
 
115
                if onerror is not None:
 
116
                    onerror(name)
 
117
                else:
 
118
                    raise
 
119
            else:
 
120
                path = getattr(sys.modules[name], '__path__', None) or []
 
121
 
 
122
                # don't traverse path items we've seen before
 
123
                path = [p for p in path if not seen(p)]
 
124
 
 
125
                for item in walk_packages(path, name+'.', onerror):
 
126
                    yield item
 
127
 
 
128
 
 
129
def iter_modules(path=None, prefix=''):
 
130
    """Yields (module_loader, name, ispkg) for all submodules on path,
 
131
    or, if path is None, all top-level modules on sys.path.
 
132
 
 
133
    'path' should be either None or a list of paths to look for
 
134
    modules in.
 
135
 
 
136
    'prefix' is a string to output on the front of every module name
 
137
    on output.
 
138
    """
 
139
 
 
140
    if path is None:
 
141
        importers = iter_importers()
 
142
    else:
 
143
        importers = map(get_importer, path)
 
144
 
 
145
    yielded = {}
 
146
    for i in importers:
 
147
        for name, ispkg in iter_importer_modules(i, prefix):
 
148
            if name not in yielded:
 
149
                yielded[name] = 1
 
150
                yield i, name, ispkg
 
151
 
 
152
 
 
153
#@simplegeneric
 
154
def iter_importer_modules(importer, prefix=''):
 
155
    if not hasattr(importer, 'iter_modules'):
 
156
        return []
 
157
    return importer.iter_modules(prefix)
 
158
 
 
159
iter_importer_modules = simplegeneric(iter_importer_modules)
 
160
 
 
161
 
 
162
class ImpImporter:
 
163
    """PEP 302 Importer that wraps Python's "classic" import algorithm
 
164
 
 
165
    ImpImporter(dirname) produces a PEP 302 importer that searches that
 
166
    directory.  ImpImporter(None) produces a PEP 302 importer that searches
 
167
    the current sys.path, plus any modules that are frozen or built-in.
 
168
 
 
169
    Note that ImpImporter does not currently support being used by placement
 
170
    on sys.meta_path.
 
171
    """
 
172
 
 
173
    def __init__(self, path=None):
 
174
        self.path = path
 
175
 
 
176
    def find_module(self, fullname, path=None):
 
177
        # Note: we ignore 'path' argument since it is only used via meta_path
 
178
        subname = fullname.split(".")[-1]
 
179
        if subname != fullname and self.path is None:
 
180
            return None
 
181
        if self.path is None:
 
182
            path = None
 
183
        else:
 
184
            path = [os.path.realpath(self.path)]
 
185
        try:
 
186
            file, filename, etc = imp.find_module(subname, path)
 
187
        except ImportError:
 
188
            return None
 
189
        return ImpLoader(fullname, file, filename, etc)
 
190
 
 
191
    def iter_modules(self, prefix=''):
 
192
        if self.path is None or not os.path.isdir(self.path):
 
193
            return
 
194
 
 
195
        yielded = {}
 
196
        import inspect
 
197
 
 
198
        filenames = os.listdir(self.path)
 
199
        filenames.sort()  # handle packages before same-named modules
 
200
 
 
201
        for fn in filenames:
 
202
            modname = inspect.getmodulename(fn)
 
203
            if modname=='__init__' or modname in yielded:
 
204
                continue
 
205
 
 
206
            path = os.path.join(self.path, fn)
 
207
            ispkg = False
 
208
 
 
209
            if not modname and os.path.isdir(path) and '.' not in fn:
 
210
                modname = fn
 
211
                for fn in os.listdir(path):
 
212
                    subname = inspect.getmodulename(fn)
 
213
                    if subname=='__init__':
 
214
                        ispkg = True
 
215
                        break
 
216
                else:
 
217
                    continue    # not a package
 
218
 
 
219
            if modname and '.' not in modname:
 
220
                yielded[modname] = 1
 
221
                yield prefix + modname, ispkg
 
222
 
 
223
 
 
224
class ImpLoader:
 
225
    """PEP 302 Loader that wraps Python's "classic" import algorithm
 
226
    """
 
227
    code = source = None
 
228
 
 
229
    def __init__(self, fullname, file, filename, etc):
 
230
        self.file = file
 
231
        self.filename = filename
 
232
        self.fullname = fullname
 
233
        self.etc = etc
 
234
 
 
235
    def load_module(self, fullname):
 
236
        self._reopen()
 
237
        try:
 
238
            mod = imp.load_module(fullname, self.file, self.filename, self.etc)
 
239
        finally:
 
240
            if self.file:
 
241
                self.file.close()
 
242
        # Note: we don't set __loader__ because we want the module to look
 
243
        # normal; i.e. this is just a wrapper for standard import machinery
 
244
        return mod
 
245
 
 
246
    def get_data(self, pathname):
 
247
        return open(pathname, "rb").read()
 
248
 
 
249
    def _reopen(self):
 
250
        if self.file and self.file.closed:
 
251
            mod_type = self.etc[2]
 
252
            if mod_type==imp.PY_SOURCE:
 
253
                self.file = open(self.filename, 'rU')
 
254
            elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION):
 
255
                self.file = open(self.filename, 'rb')
 
256
 
 
257
    def _fix_name(self, fullname):
 
258
        if fullname is None:
 
259
            fullname = self.fullname
 
260
        elif fullname != self.fullname:
 
261
            raise ImportError("Loader for module %s cannot handle "
 
262
                              "module %s" % (self.fullname, fullname))
 
263
        return fullname
 
264
 
 
265
    def is_package(self, fullname):
 
266
        fullname = self._fix_name(fullname)
 
267
        return self.etc[2]==imp.PKG_DIRECTORY
 
268
 
 
269
    def get_code(self, fullname=None):
 
270
        fullname = self._fix_name(fullname)
 
271
        if self.code is None:
 
272
            mod_type = self.etc[2]
 
273
            if mod_type==imp.PY_SOURCE:
 
274
                source = self.get_source(fullname)
 
275
                self.code = compile(source, self.filename, 'exec')
 
276
            elif mod_type==imp.PY_COMPILED:
 
277
                self._reopen()
 
278
                try:
 
279
                    self.code = read_code(self.file)
 
280
                finally:
 
281
                    self.file.close()
 
282
            elif mod_type==imp.PKG_DIRECTORY:
 
283
                self.code = self._get_delegate().get_code()
 
284
        return self.code
 
285
 
 
286
    def get_source(self, fullname=None):
 
287
        fullname = self._fix_name(fullname)
 
288
        if self.source is None:
 
289
            mod_type = self.etc[2]
 
290
            if mod_type==imp.PY_SOURCE:
 
291
                self._reopen()
 
292
                try:
 
293
                    self.source = self.file.read()
 
294
                finally:
 
295
                    self.file.close()
 
296
            elif mod_type==imp.PY_COMPILED:
 
297
                if os.path.exists(self.filename[:-1]):
 
298
                    f = open(self.filename[:-1], 'rU')
 
299
                    self.source = f.read()
 
300
                    f.close()
 
301
            elif mod_type==imp.PKG_DIRECTORY:
 
302
                self.source = self._get_delegate().get_source()
 
303
        return self.source
 
304
 
 
305
 
 
306
    def _get_delegate(self):
 
307
        return ImpImporter(self.filename).find_module('__init__')
 
308
 
 
309
    def get_filename(self, fullname=None):
 
310
        fullname = self._fix_name(fullname)
 
311
        mod_type = self.etc[2]
 
312
        if self.etc[2]==imp.PKG_DIRECTORY:
 
313
            return self._get_delegate().get_filename()
 
314
        elif self.etc[2] in (imp.PY_SOURCE, imp.PY_COMPILED, imp.C_EXTENSION):
 
315
            return self.filename
 
316
        return None
 
317
 
 
318
 
 
319
try:
 
320
    import zipimport
 
321
    from zipimport import zipimporter
 
322
 
 
323
    def iter_zipimport_modules(importer, prefix=''):
 
324
        dirlist = zipimport._zip_directory_cache[importer.archive].keys()
 
325
        dirlist.sort()
 
326
        _prefix = importer.prefix
 
327
        plen = len(_prefix)
 
328
        yielded = {}
 
329
        import inspect
 
330
        for fn in dirlist:
 
331
            if not fn.startswith(_prefix):
 
332
                continue
 
333
 
 
334
            fn = fn[plen:].split(os.sep)
 
335
 
 
336
            if len(fn)==2 and fn[1].startswith('__init__.py'):
 
337
                if fn[0] not in yielded:
 
338
                    yielded[fn[0]] = 1
 
339
                    yield fn[0], True
 
340
 
 
341
            if len(fn)!=1:
 
342
                continue
 
343
 
 
344
            modname = inspect.getmodulename(fn[0])
 
345
            if modname=='__init__':
 
346
                continue
 
347
 
 
348
            if modname and '.' not in modname and modname not in yielded:
 
349
                yielded[modname] = 1
 
350
                yield prefix + modname, False
 
351
 
 
352
    iter_importer_modules.register(zipimporter, iter_zipimport_modules)
 
353
 
 
354
except ImportError:
 
355
    pass
 
356
 
 
357
 
 
358
def get_importer(path_item):
 
359
    """Retrieve a PEP 302 importer for the given path item
 
360
 
 
361
    The returned importer is cached in sys.path_importer_cache
 
362
    if it was newly created by a path hook.
 
363
 
 
364
    If there is no importer, a wrapper around the basic import
 
365
    machinery is returned. This wrapper is never inserted into
 
366
    the importer cache (None is inserted instead).
 
367
 
 
368
    The cache (or part of it) can be cleared manually if a
 
369
    rescan of sys.path_hooks is necessary.
 
370
    """
 
371
    try:
 
372
        importer = sys.path_importer_cache[path_item]
 
373
    except KeyError:
 
374
        for path_hook in sys.path_hooks:
 
375
            try:
 
376
                importer = path_hook(path_item)
 
377
                break
 
378
            except ImportError:
 
379
                pass
 
380
        else:
 
381
            importer = None
 
382
        sys.path_importer_cache.setdefault(path_item, importer)
 
383
 
 
384
    if importer is None:
 
385
        try:
 
386
            importer = ImpImporter(path_item)
 
387
        except ImportError:
 
388
            importer = None
 
389
    return importer
 
390
 
 
391
 
 
392
def iter_importers(fullname=""):
 
393
    """Yield PEP 302 importers for the given module name
 
394
 
 
395
    If fullname contains a '.', the importers will be for the package
 
396
    containing fullname, otherwise they will be importers for sys.meta_path,
 
397
    sys.path, and Python's "classic" import machinery, in that order.  If
 
398
    the named module is in a package, that package is imported as a side
 
399
    effect of invoking this function.
 
400
 
 
401
    Non PEP 302 mechanisms (e.g. the Windows registry) used by the
 
402
    standard import machinery to find files in alternative locations
 
403
    are partially supported, but are searched AFTER sys.path. Normally,
 
404
    these locations are searched BEFORE sys.path, preventing sys.path
 
405
    entries from shadowing them.
 
406
 
 
407
    For this to cause a visible difference in behaviour, there must
 
408
    be a module or package name that is accessible via both sys.path
 
409
    and one of the non PEP 302 file system mechanisms. In this case,
 
410
    the emulation will find the former version, while the builtin
 
411
    import mechanism will find the latter.
 
412
 
 
413
    Items of the following types can be affected by this discrepancy:
 
414
        imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY
 
415
    """
 
416
    if fullname.startswith('.'):
 
417
        raise ImportError("Relative module names not supported")
 
418
    if '.' in fullname:
 
419
        # Get the containing package's __path__
 
420
        pkg = '.'.join(fullname.split('.')[:-1])
 
421
        if pkg not in sys.modules:
 
422
            __import__(pkg)
 
423
        path = getattr(sys.modules[pkg], '__path__', None) or []
 
424
    else:
 
425
        for importer in sys.meta_path:
 
426
            yield importer
 
427
        path = sys.path
 
428
    for item in path:
 
429
        yield get_importer(item)
 
430
    if '.' not in fullname:
 
431
        yield ImpImporter()
 
432
 
 
433
def get_loader(module_or_name):
 
434
    """Get a PEP 302 "loader" object for module_or_name
 
435
 
 
436
    If the module or package is accessible via the normal import
 
437
    mechanism, a wrapper around the relevant part of that machinery
 
438
    is returned.  Returns None if the module cannot be found or imported.
 
439
    If the named module is not already imported, its containing package
 
440
    (if any) is imported, in order to establish the package __path__.
 
441
 
 
442
    This function uses iter_importers(), and is thus subject to the same
 
443
    limitations regarding platform-specific special import locations such
 
444
    as the Windows registry.
 
445
    """
 
446
    if module_or_name in sys.modules:
 
447
        module_or_name = sys.modules[module_or_name]
 
448
    if isinstance(module_or_name, ModuleType):
 
449
        module = module_or_name
 
450
        loader = getattr(module, '__loader__', None)
 
451
        if loader is not None:
 
452
            return loader
 
453
        fullname = module.__name__
 
454
    else:
 
455
        fullname = module_or_name
 
456
    return find_loader(fullname)
 
457
 
 
458
def find_loader(fullname):
 
459
    """Find a PEP 302 "loader" object for fullname
 
460
 
 
461
    If fullname contains dots, path must be the containing package's __path__.
 
462
    Returns None if the module cannot be found or imported. This function uses
 
463
    iter_importers(), and is thus subject to the same limitations regarding
 
464
    platform-specific special import locations such as the Windows registry.
 
465
    """
 
466
    for importer in iter_importers(fullname):
 
467
        loader = importer.find_module(fullname)
 
468
        if loader is not None:
 
469
            return loader
 
470
 
 
471
    return None
 
472
 
 
473
 
 
474
def extend_path(path, name):
 
475
    """Extend a package's path.
 
476
 
 
477
    Intended use is to place the following code in a package's __init__.py:
 
478
 
 
479
        from pkgutil import extend_path
 
480
        __path__ = extend_path(__path__, __name__)
 
481
 
 
482
    This will add to the package's __path__ all subdirectories of
 
483
    directories on sys.path named after the package.  This is useful
 
484
    if one wants to distribute different parts of a single logical
 
485
    package as multiple directories.
 
486
 
 
487
    It also looks for *.pkg files beginning where * matches the name
 
488
    argument.  This feature is similar to *.pth files (see site.py),
 
489
    except that it doesn't special-case lines starting with 'import'.
 
490
    A *.pkg file is trusted at face value: apart from checking for
 
491
    duplicates, all entries found in a *.pkg file are added to the
 
492
    path, regardless of whether they are exist the filesystem.  (This
 
493
    is a feature.)
 
494
 
 
495
    If the input path is not a list (as is the case for frozen
 
496
    packages) it is returned unchanged.  The input path is not
 
497
    modified; an extended copy is returned.  Items are only appended
 
498
    to the copy at the end.
 
499
 
 
500
    It is assumed that sys.path is a sequence.  Items of sys.path that
 
501
    are not (unicode or 8-bit) strings referring to existing
 
502
    directories are ignored.  Unicode items of sys.path that cause
 
503
    errors when used as filenames may cause this function to raise an
 
504
    exception (in line with os.path.isdir() behavior).
 
505
    """
 
506
 
 
507
    if not isinstance(path, list):
 
508
        # This could happen e.g. when this is called from inside a
 
509
        # frozen package.  Return the path unchanged in that case.
 
510
        return path
 
511
 
 
512
    pname = os.path.join(*name.split('.')) # Reconstitute as relative path
 
513
    # Just in case os.extsep != '.'
 
514
    sname = os.extsep.join(name.split('.'))
 
515
    sname_pkg = sname + os.extsep + "pkg"
 
516
    init_py = "__init__" + os.extsep + "py"
 
517
 
 
518
    path = path[:] # Start with a copy of the existing path
 
519
 
 
520
    for dir in sys.path:
 
521
        if not isinstance(dir, basestring) or not os.path.isdir(dir):
 
522
            continue
 
523
        subdir = os.path.join(dir, pname)
 
524
        # XXX This may still add duplicate entries to path on
 
525
        # case-insensitive filesystems
 
526
        initfile = os.path.join(subdir, init_py)
 
527
        if subdir not in path and os.path.isfile(initfile):
 
528
            path.append(subdir)
 
529
        # XXX Is this the right thing for subpackages like zope.app?
 
530
        # It looks for a file named "zope.app.pkg"
 
531
        pkgfile = os.path.join(dir, sname_pkg)
 
532
        if os.path.isfile(pkgfile):
 
533
            try:
 
534
                f = open(pkgfile)
 
535
            except IOError, msg:
 
536
                sys.stderr.write("Can't open %s: %s\n" %
 
537
                                 (pkgfile, msg))
 
538
            else:
 
539
                for line in f:
 
540
                    line = line.rstrip('\n')
 
541
                    if not line or line.startswith('#'):
 
542
                        continue
 
543
                    path.append(line) # Don't check for existence!
 
544
                f.close()
 
545
 
 
546
    return path
 
547
 
 
548
def get_data(package, resource):
 
549
    """Get a resource from a package.
 
550
 
 
551
    This is a wrapper round the PEP 302 loader get_data API. The package
 
552
    argument should be the name of a package, in standard module format
 
553
    (foo.bar). The resource argument should be in the form of a relative
 
554
    filename, using '/' as the path separator. The parent directory name '..'
 
555
    is not allowed, and nor is a rooted name (starting with a '/').
 
556
 
 
557
    The function returns a binary string, which is the contents of the
 
558
    specified resource.
 
559
 
 
560
    For packages located in the filesystem, which have already been imported,
 
561
    this is the rough equivalent of
 
562
 
 
563
        d = os.path.dirname(sys.modules[package].__file__)
 
564
        data = open(os.path.join(d, resource), 'rb').read()
 
565
 
 
566
    If the package cannot be located or loaded, or it uses a PEP 302 loader
 
567
    which does not support get_data(), then None is returned.
 
568
    """
 
569
 
 
570
    loader = get_loader(package)
 
571
    if loader is None or not hasattr(loader, 'get_data'):
 
572
        return None
 
573
    mod = sys.modules.get(package) or loader.load_module(package)
 
574
    if mod is None or not hasattr(mod, '__file__'):
 
575
        return None
 
576
 
 
577
    # Modify the resource name to be compatible with the loader.get_data
 
578
    # signature - an os.path format "filename" starting with the dirname of
 
579
    # the package's __file__
 
580
    parts = resource.split('/')
 
581
    parts.insert(0, os.path.dirname(mod.__file__))
 
582
    resource_name = os.path.join(*parts)
 
583
    return loader.get_data(resource_name)