Brett Cannon | 93881c6 | 2009-01-26 01:16:50 +0000 | [diff] [blame] | 1 | """Backport of importlib.import_module from 3.x.""" |
| 2 | import sys |
| 3 | |
| 4 | def _resolve_name(name, package, level): |
| 5 | """Return the absolute name of the module to be imported.""" |
| 6 | level -= 1 |
| 7 | try: |
| 8 | if package.count('.') < level: |
| 9 | raise ValueError("attempted relative import beyond top-level " |
| 10 | "package") |
| 11 | except AttributeError: |
| 12 | raise ValueError("__package__ not set to a string") |
| 13 | base = package.rsplit('.', level)[0] |
| 14 | if name: |
| 15 | return "{0}.{1}".format(base, name) |
| 16 | else: |
| 17 | return base |
| 18 | |
| 19 | |
| 20 | def import_module(name, package=None): |
| 21 | """Import a module. |
| 22 | |
| 23 | The 'package' argument is required when performing a relative import. It |
| 24 | specifies the package to use as the anchor point from which to resolve the |
| 25 | relative import to an absolute import. |
| 26 | |
| 27 | """ |
| 28 | if name.startswith('.'): |
| 29 | if not package: |
| 30 | raise TypeError("relative imports require the 'package' argument") |
| 31 | level = 0 |
| 32 | for character in name: |
| 33 | if character != '.': |
| 34 | break |
| 35 | level += 1 |
| 36 | name = _resolve_name(name[level:], package, level) |
| 37 | __import__(name) |
| 38 | return sys.modules[name] |