I want Python’s import to look something like this
import google.protobuf.message from ('Python Google Protocol Buffers', '2.5.0', 'c9818b6c4f44a10a96d8409044da41a540b40272')
The extra information is hints – hints to the import system to make sure that it found the correct google package, hints to a search/download system on where to look for it if it’s not already present locally. This would basically replace pip. I don’t want to need to install packages. I don’t mind installing packages, you can prebake a system, but it should be an option for efficiency’s sake, not something that everyone must do.
Go has taken a big step in this direction, but it’s a little inflexible. It will download a package from a remote repository, but you have to specify the path, and it’s to a specific repository. This has long-term implications, all your code will need updating if the repository moves. Also, this is not very distributed, and you can’t package things up easily for bundle distribution. Every first-time run of a Go program is going to hit the remote repositories – packages are cached in your local program, but not even system-wide.
What I want is very loose coupling. If I have modules preinstalled on my system and they are the right modules, they get used. If not, my import casts a net to find it, and this search process can be enhanced as desired. For example, a company might want to keep a local cache server of packages so that most searches can be satisfied locally, only going out to other networks for unknown packages. Or an organization might push a giant set of likely-defined modules to every system.
I also want as much flexibility as possible. I like the Google search approach – no schema that has to absolutely be followed, it’s all hints, hints to a search engine. But the hints are specific enough that you’ll find exactly what you are looking for.
Also, I want something that automatically handles architecture differences, platform differences, compiler/interpreter differences, and so on. If I run my code in Python 2.7, I want it to use a Python 2.7-compatible library (e.g. perhaps already precompiled for my exact version of Python), but if I run it in Python 3.3, I might expect a different Python 3.3-savvy library to be used. Or if I’m running on a Windows 7 64-bit machine, then I want any native code to be specific to my architecture and operating system.
surrogate is a library used to create stubs for non-existing modules in sys.modules. Its aim is for unit testing, but it’s an example of manipulating sys.modules.
PEP 302 — New Import Hooks is the original specification for import hooks, kept around because the current system uses it for documentation on how to make custom importers.
The current system is described in The import system and importlib in the Python 3 documentation; also see sys.meta_path and related in the sys module reference. I don’t yet know how much of this is in Python 2.7. However, this still doesn’t let me get extra hint information to my custom importer.
The sum of all knowledge of Python packaging is contained herein: Python Packaging User Guide. OK, maybe not quite, but this is from the Python Packaging Authority, a group working on packaging and installing distributions in Python.
Bento is another interesting Python package system.
Some related module-system PEPs
- PEP 328 — Imports: Multi-Line and Absolute/Relative
- PEP 338 — Executing modules as scripts
- PEP 366 — Main module explicit relative imports
- PEP 273 — Import Modules from Zip Archives
- New import hooks + Import from Zip files
- PEP 376 — Database of Installed Python Distributions
- PEP 426 — Metadata for Python Software Packages 2.0