ELI5-ification underway\!
This commit is contained in:
parent
6506acd861
commit
67e57d7492
106
README.rst
106
README.rst
|
@ -1,67 +1,65 @@
|
||||||
Synopsis
|
Synopsis
|
||||||
--------
|
--------
|
||||||
|
|
||||||
**Polyloader** is a python module that enables the discovery and loading
|
**Polyloader** is a python module that extends the Python `import`
|
||||||
of heterogenous source code packages. This discovery and loading is
|
statement to enable the discovery and loading of heterogenous source
|
||||||
critical to the functioning of other programming languages that use the
|
|
||||||
Python AST and Python interpreter, languages such as Hy, Doge, and
|
|
||||||
Mochi.
|
|
||||||
|
|
||||||
Problem Statement
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
The Python module loader system is hard-coded to prevent the discovery
|
|
||||||
of heterogenous source code packages. From Python 2.6 through the
|
|
||||||
current (as of this writing) Python 3.5, the import mechanism allows for
|
|
||||||
the creation of file finders and importers that would transform Python's
|
|
||||||
import syntax into a *path,* assert whether or not that path could be
|
|
||||||
made to correspond to a *syntax object*, and then attempt to *load* that
|
|
||||||
syntax object as a Python module. Python *packages*, however, are
|
|
||||||
assumed to be uniformly made up of Python syntax objects, be they
|
|
||||||
**.py** source files, **.pyc/.pyo** bytecode, or **.so/.dll** files with
|
|
||||||
an exposed Python-to-C API. In Python 2 these suffixes are hard-coded
|
|
||||||
into the source in the **imp** builtin module; in Python 3 these
|
|
||||||
suffixes are constants defined in a private section of **importlib**; in
|
|
||||||
either case, they are unavailable for modification. This lack of access
|
|
||||||
to the extensions list prevents the *discovery* of heterogenous source
|
|
||||||
code packages.
|
code packages.
|
||||||
|
|
||||||
The discovery mechanism is outlined in Python's **pkgutil** module;
|
Say What?
|
||||||
features such as **pkgutil.iter_modules** do not work with heterogenous
|
---------
|
||||||
source code, which in turn means that one cannot write, for one
|
|
||||||
important example, Django management commands in an alternative syntax.
|
|
||||||
|
|
||||||
**polyloader** is a Python module that intercepts calls to the default
|
The ``import`` statement is how the Python interpreter finds a module
|
||||||
finder, loader, and package module iterator, and if the path resolves to
|
written in Python and loads it, turning it into variables, executable
|
||||||
an alternative syntax, provide the appropriate finder, loader and
|
functions, constructable classes, and other Python objects, and then
|
||||||
iterator. **polyloader** is different from traditional importlib shims
|
exposes those objects to the currently running program.
|
||||||
in that it directly affects the default source file loader, and thus
|
|
||||||
allows for the discovery and importation of suffixes not listed in
|
|
||||||
Python's defaults.
|
|
||||||
|
|
||||||
To use:
|
The ``import`` statement has long been extensible so that things other
|
||||||
-------
|
than Python code could be imported, but this feature has always had two
|
||||||
|
limitations:
|
||||||
|
|
||||||
Import polyloader in your python script's launcher or library, as well
|
1. It's annoyingly hard to write an importer. (Believe me. Polyloader
|
||||||
as the syntax compiler(s) you plan to use. For example, if you have
|
*is* one!)
|
||||||
`Mochi <https://github.com/i2y/mochi>`__ and
|
2. For filesystem-based modules (which is 99% of them) Python's importer
|
||||||
`Hy <http://docs.hylang.org/en/latest/>`__ installed, and you wanted to
|
only understands one loader type per directory. It's not possible to
|
||||||
write a Django app, edit manage.py and add the following lines at the
|
store code or data written in something other than Python in the same
|
||||||
top:
|
directory with Python module code and load it via ``import``.
|
||||||
|
|
||||||
::
|
The former requires a certain degree of abstraction and thought. For
|
||||||
|
the latter, most people ignore the problem and load module configuration
|
||||||
|
files written in JSON or YAML or whatever directly. This is fine,
|
||||||
|
except when you want to write in one of Python's extended languages like
|
||||||
|
Hy or Coconut in a framework like Django, Flask or Glitch.
|
||||||
|
|
||||||
from mochi.main import compile_file as mochi_compile
|
**Polyloader** eliminates these limitations.
|
||||||
from hy.importer import ast_compile as hy_compile
|
|
||||||
from polyloader import polyimport
|
|
||||||
polyimport(mochi_compile, ['.mochi'])
|
|
||||||
polyimport(hy_compile, ['.hy'])}
|
|
||||||
|
|
||||||
Now your views can be written in Hy and your models in Mochi, and
|
What's the real problem?
|
||||||
everything will just work.
|
------------------------
|
||||||
|
|
||||||
Dependencies
|
The real problem is that Python's traditional extensions, ``.py``,
|
||||||
------------
|
``.pyc/.pyo``, and ``.so/.dll`` files, are hard-coded in Python. In
|
||||||
|
Python 2, they're in the ``imp`` builtin; In Python 3, they're defined
|
||||||
|
in a private section of `importlib`. Either way, they're not accessible
|
||||||
|
for modification and extension.
|
||||||
|
|
||||||
|
This problem is made harder by the ``pkglib`` module, which is part of
|
||||||
|
Python's standard library. This module uses ``inspect.getmoduleinfo``,
|
||||||
|
which again only recognizes the usual extensions. Which means you can't
|
||||||
|
list multilingual modules either; this hampers the development of Django
|
||||||
|
management commands in a syntax other than Python.
|
||||||
|
|
||||||
|
What the solution?
|
||||||
|
------------------
|
||||||
|
|
||||||
|
At its heart, the Python import system runs two different internal
|
||||||
|
mechanisms to figure out what the *import string* (the dotted terms
|
||||||
|
after the word "import") "means." Each mechanism has one or more
|
||||||
|
*finders*, and the first finder to report "I have a *loader* that knows
|
||||||
|
what that import string means" wins.
|
||||||
|
|
||||||
|
The very last finder is for the filesystem. The solution is to get in
|
||||||
|
front of that finder with one that can handle all the other syntax
|
||||||
|
loaders *and* knows how to fall back on the last one for those files the
|
||||||
|
last one handles.
|
||||||
|
|
||||||
|
That's what ``polyloader`` does.
|
||||||
|
|
||||||
polymorph is self-contained. It has no dependencies other than Python
|
|
||||||
itself and your choice of language.
|
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
Details on Import and Polyloader
|
||||||
|
================================
|
||||||
|
|
||||||
|
Welcome to the Python Import ELI5!
|
||||||
|
**********************************
|
||||||
|
|
||||||
|
What is `import`?
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
``import`` is a Python statement that finds a *module* that is accessible
|
||||||
|
by the currently running process, loads it, and makes its contents
|
||||||
|
available to the scope in which the statement was made. A statement
|
||||||
|
like
|
||||||
|
|
||||||
|
``import django.db.models``
|
||||||
|
|
||||||
|
is looking for a module named ``django.db.models``. If the statement is
|
||||||
|
successful, ``django.db.models`` will be a variable name in the scope,
|
||||||
|
it will be a Python *object* (of ``class Module``, but that's not
|
||||||
|
important), and it will have functions, class constructors, variables
|
||||||
|
and constants. These Python objects will be accessible through the dot
|
||||||
|
operator.
|
||||||
|
|
||||||
|
An alternative way of writing import statements is
|
||||||
|
|
||||||
|
``from django.utils import encoding``
|
||||||
|
|
||||||
|
And then the variable will just be ``encoding``. The ``encoding``
|
||||||
|
module has a function for handling unicode-to-web translation.
|
||||||
|
Accessing it through the dot operator, it looks like this:
|
||||||
|
|
||||||
|
``ready_str = encoding.smart_str(unready_str)``
|
||||||
|
|
||||||
|
We call the parts of the import statement that describe the module the
|
||||||
|
*import string*.
|
||||||
|
|
||||||
|
``sys.path_hooks``: How does Python know where to look?
|
||||||
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
That's what's funny. Python has two independent ways of making sense of
|
||||||
|
of the import string. The old system is based on the assumption that
|
||||||
|
everything is a filesystem, with folders and filenames. This is called
|
||||||
|
the ``sys.path_hooks`` system.
|
||||||
|
|
||||||
|
In the old system, the parts of the import string would be split up, and
|
||||||
|
then a collection of directories would be scanned to see if the first
|
||||||
|
name in the import string could be matched with a subdirectory. If it
|
||||||
|
could, that directory would be scanned until the last name on the import
|
||||||
|
string. If that name was a *filename*, it would be loaded as a module.
|
||||||
|
If that name was a *directory* and that directory had a file named
|
||||||
|
``__init__.py``, then that file would be loaded as the module.
|
||||||
|
|
||||||
|
The ``sys.path_hooks`` array has a list of different methods for trying to
|
||||||
|
scan a filesystem for the parts of the import string. A ``path_hook`` is
|
||||||
|
a function that takes a path to a directory; if it can handle the
|
||||||
|
contents of the directory, it returns a **Finder**, an object whose job
|
||||||
|
is to figure out how to load the module; if it can't, it returns an
|
||||||
|
ImportError exception. The object that loads the module is called,
|
||||||
|
naturally, a **Loader**.
|
||||||
|
|
||||||
|
* To read more about **Finders**, see :ref:`eli5-finders`
|
||||||
|
* To read more about **Loaders**, see :ref:`eli5-loaders`
|
||||||
|
* To read more about **Path Hooks**, see :ref:`eli5-pathhooks`
|
||||||
|
|
||||||
|
``sys.path``: What directories are searched?
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
The list of directories is stored in an array, ``sys.path``. This path is
|
||||||
|
initialized by Python when it starts up, but programs can modify it at
|
||||||
|
run-time to point to extra directories if they want.
|
||||||
|
|
||||||
|
|
||||||
|
``sys.meta_path``: What is the new system?
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
The new system is called ``sys.meta_path``, and it's an array of
|
||||||
|
**Finders**, objects that have one method, ``find_module(fullname)``.
|
||||||
|
It's an anything-goes API that gives developers the freedom to import
|
||||||
|
modules from anywhere: databases, archives, remote web resources, even
|
||||||
|
code written on-the-fly internally. The new system can apply any
|
||||||
|
meaning at all to the import string.
|
||||||
|
|
||||||
|
In Python, the import string is offered to each object in
|
||||||
|
``sys.meta_path`` before being offered to each ``sys.path_hook``. The
|
||||||
|
filesystem is typically the last finder tried.
|
||||||
|
|
||||||
|
To read more about **Meta Paths**, see :ref:`eli5-metapaths`
|
||||||
|
|
||||||
|
Is it different between Python 2 and Python 3?
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
Python 3 moves almost everything about this process into python's
|
||||||
|
library, leaving only a bare minimum of functionality inside the Python
|
||||||
|
executable to load this library and run it. When the Python developers
|
||||||
|
did that, they added a lot of functionality to make it easier to write
|
||||||
|
new import modules. The old way still works, but there are now *Module
|
||||||
|
Specifications*, which are metadata about a module, and the old
|
||||||
|
``path_hooks`` system is now just a ``meta_path`` handler added to the
|
||||||
|
new system as the last resort.
|
||||||
|
|
||||||
|
To read more about **Module Specifications**, see :ref:`eli5-specs`
|
||||||
|
|
||||||
|
Does the old system still matter?
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
Yes, for one reason: *iteration*. Iteration is the ability to take a
|
||||||
|
path where you believe Python modules can be found, and list through
|
||||||
|
them. This facility is useful for large frameworks where a user wants
|
||||||
|
to add new commands, or new objects, or new operations; Django uses this
|
||||||
|
facility a lot! The ``pkgutil`` library depends upon Finders being able
|
||||||
|
to iterate their contents.
|
|
@ -0,0 +1,37 @@
|
||||||
|
ELI5: Explain Like I'm Five!
|
||||||
|
============================
|
||||||
|
|
||||||
|
.. _eli5-finders:
|
||||||
|
|
||||||
|
Finders
|
||||||
|
=======
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
.. _eli5-loaders:
|
||||||
|
|
||||||
|
Loaders
|
||||||
|
=======
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
.. _eli5-pathhooks:
|
||||||
|
|
||||||
|
Path Hooks
|
||||||
|
==========
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
.. _eli5-metapaths:
|
||||||
|
|
||||||
|
Meta Paths
|
||||||
|
==========
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
.. _eli5-specs:
|
||||||
|
|
||||||
|
Module Specifications
|
||||||
|
=====================
|
||||||
|
|
||||||
|
TODO
|
|
@ -3,8 +3,8 @@
|
||||||
You can adapt this file completely to your liking, but it should at least
|
You can adapt this file completely to your liking, but it should at least
|
||||||
contain the root `toctree` directive.
|
contain the root `toctree` directive.
|
||||||
|
|
||||||
Welcome to py-polymorphic-loader's documentation!
|
Welcome to polyloader
|
||||||
======================================
|
=====================
|
||||||
|
|
||||||
Contents:
|
Contents:
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ Contents:
|
||||||
readme
|
readme
|
||||||
installation
|
installation
|
||||||
usage
|
usage
|
||||||
|
details
|
||||||
contributing
|
contributing
|
||||||
authors
|
authors
|
||||||
history
|
history
|
||||||
|
|
|
@ -8,11 +8,11 @@ Installation
|
||||||
Stable release
|
Stable release
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
To install py-polymorphic-loader, run this command in your terminal:
|
To install polyloader, run this command in your terminal:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ pip install py-polymorphic-loader
|
$ pip install polyloader
|
||||||
|
|
||||||
If you don't have `pip`_ installed, this `Python installation guide`_ can guide
|
If you don't have `pip`_ installed, this `Python installation guide`_ can guide
|
||||||
you through the process.
|
you through the process.
|
||||||
|
@ -24,19 +24,19 @@ you through the process.
|
||||||
From sources
|
From sources
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The sources for py-polymorphic-loader can be downloaded from the `Github repo`_.
|
The sources for polyloader can be downloaded from the `Github repo`_.
|
||||||
|
|
||||||
You can either clone the public repository:
|
You can either clone the public repository:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ git clone git://github.com/elfsternberg/py-polymorphic-loader
|
$ git clone git://github.com/elfsternberg/polyloader
|
||||||
|
|
||||||
Or download the `tarball`_:
|
Or download the `tarball`_:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ curl -OL https://github.com/elfsternberg/py-polymorphic-loader/tarball/master
|
$ curl -OL https://github.com/elfsternberg/polyloader/tarball/master
|
||||||
|
|
||||||
Once you have a copy of the source, you can install it with:
|
Once you have a copy of the source, you can install it with:
|
||||||
|
|
||||||
|
@ -45,5 +45,5 @@ Once you have a copy of the source, you can install it with:
|
||||||
$ python setup.py install
|
$ python setup.py install
|
||||||
|
|
||||||
|
|
||||||
.. _Github repo: https://github.com/elfsternberg/py-polymorphic-loader
|
.. _Github repo: https://github.com/elfsternberg/polyloader
|
||||||
.. _tarball: https://github.com/elfsternberg/py-polymorphic-loader/tarball/master
|
.. _tarball: https://github.com/elfsternberg/polyloader/tarball/master
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
.. include:: ../README.rst
|
.. include:: ../../README.rst
|
||||||
|
|
|
@ -2,6 +2,21 @@
|
||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
||||||
To use py-polymorphic-loader in a project::
|
Import polyloader in your python script's launcher or library, as well
|
||||||
|
as the syntax compiler(s) you plan to use. For example, if you have
|
||||||
|
`Mochi <https://github.com/i2y/mochi>`__ and `Hy
|
||||||
|
<http://docs.hylang.org/en/latest/>`__ installed, and you wanted to
|
||||||
|
write a Django app, edit manage.py and add the following lines at the
|
||||||
|
top:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from mochi.main import compile_file as mochi_compile
|
||||||
|
from hy.importer import ast_compile as hy_compile
|
||||||
|
import polyloader
|
||||||
|
polyloader.install(mochi_compile, ['.mochi'])
|
||||||
|
polyloader.install(hy_compile, ['.hy'])}
|
||||||
|
|
||||||
|
Now your views can be written in Hy and your models in Mochi, and
|
||||||
|
everything will just work.
|
||||||
|
|
||||||
import py-polymorphic-loader
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<script type="text/javascript" src="doctools.js"></script>
|
<script type="text/javascript" src="doctools.js"></script>
|
||||||
<link rel="top" title="polyloader 0.1.0 documentation" href="index.html" />
|
<link rel="top" title="polyloader 0.1.0 documentation" href="index.html" />
|
||||||
<link rel="next" title="<no title>" href="authors.html" />
|
<link rel="next" title="<no title>" href="authors.html" />
|
||||||
<link rel="prev" title="Usage" href="usage.html" />
|
<link rel="prev" title="Details on Import and Polyloader" href="details.html" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="related">
|
<div class="related">
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<a href="authors.html" title="<no title>"
|
<a href="authors.html" title="<no title>"
|
||||||
accesskey="N">next</a> |</li>
|
accesskey="N">next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="usage.html" title="Usage"
|
<a href="details.html" title="Details on Import and Polyloader"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -60,8 +60,8 @@
|
||||||
<div class="sphinxsidebar">
|
<div class="sphinxsidebar">
|
||||||
<div class="sphinxsidebarwrapper">
|
<div class="sphinxsidebarwrapper">
|
||||||
<h4>Previous topic</h4>
|
<h4>Previous topic</h4>
|
||||||
<p class="topless"><a href="usage.html"
|
<p class="topless"><a href="details.html"
|
||||||
title="previous chapter">Usage</a></p>
|
title="previous chapter">Details on Import and Polyloader</a></p>
|
||||||
<h4>Next topic</h4>
|
<h4>Next topic</h4>
|
||||||
<p class="topless"><a href="authors.html"
|
<p class="topless"><a href="authors.html"
|
||||||
title="next chapter"><no title></a></p>
|
title="next chapter"><no title></a></p>
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
<a href="authors.html" title="<no title>"
|
<a href="authors.html" title="<no title>"
|
||||||
>next</a> |</li>
|
>next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="usage.html" title="Usage"
|
<a href="details.html" title="Details on Import and Polyloader"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -0,0 +1,223 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
|
||||||
|
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
|
||||||
|
<title>Details on Import and Polyloader — polyloader 0.1.0 documentation</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||||
|
<link rel="stylesheet" href="pygments.css" type="text/css" />
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var DOCUMENTATION_OPTIONS = {
|
||||||
|
URL_ROOT: './',
|
||||||
|
VERSION: '0.1.0',
|
||||||
|
COLLAPSE_INDEX: false,
|
||||||
|
FILE_SUFFIX: '.html',
|
||||||
|
HAS_SOURCE: true
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="underscore.js"></script>
|
||||||
|
<script type="text/javascript" src="doctools.js"></script>
|
||||||
|
<link rel="top" title="polyloader 0.1.0 documentation" href="index.html" />
|
||||||
|
<link rel="next" title="<no title>" href="contributing.html" />
|
||||||
|
<link rel="prev" title="Usage" href="usage.html" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="related">
|
||||||
|
<h3>Navigation</h3>
|
||||||
|
<ul>
|
||||||
|
<li class="right" style="margin-right: 10px">
|
||||||
|
<a href="genindex.html" title="General Index"
|
||||||
|
accesskey="I">index</a></li>
|
||||||
|
<li class="right" >
|
||||||
|
<a href="py-modindex.html" title="Python Module Index"
|
||||||
|
>modules</a> |</li>
|
||||||
|
<li class="right" >
|
||||||
|
<a href="contributing.html" title="<no title>"
|
||||||
|
accesskey="N">next</a> |</li>
|
||||||
|
<li class="right" >
|
||||||
|
<a href="usage.html" title="Usage"
|
||||||
|
accesskey="P">previous</a> |</li>
|
||||||
|
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="document">
|
||||||
|
<div class="documentwrapper">
|
||||||
|
<div class="bodywrapper">
|
||||||
|
<div class="body">
|
||||||
|
|
||||||
|
<div class="section" id="details-on-import-and-polyloader">
|
||||||
|
<h1>Details on Import and Polyloader<a class="headerlink" href="#details-on-import-and-polyloader" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<div class="section" id="welcome-to-the-python-import-eli5">
|
||||||
|
<h2>Welcome to the Python Import ELI5!<a class="headerlink" href="#welcome-to-the-python-import-eli5" title="Permalink to this headline">¶</a></h2>
|
||||||
|
<div class="section" id="what-is-import">
|
||||||
|
<h3>What is <cite>import</cite>?<a class="headerlink" href="#what-is-import" title="Permalink to this headline">¶</a></h3>
|
||||||
|
<p><tt class="docutils literal"><span class="pre">import</span></tt> is a Python statement that finds a <em>module</em> that is accessible
|
||||||
|
by the currently running process, loads it, and makes its contents
|
||||||
|
available to the scope in which the statement was made. A statement
|
||||||
|
like</p>
|
||||||
|
<p><tt class="docutils literal"><span class="pre">import</span> <span class="pre">django.db.models</span></tt></p>
|
||||||
|
<p>is looking for a module named <tt class="docutils literal"><span class="pre">django.db.models</span></tt>. If the statement is
|
||||||
|
successful, <tt class="docutils literal"><span class="pre">django.db.models</span></tt> will be a variable name in the scope,
|
||||||
|
it will be a Python <em>object</em> (of <tt class="docutils literal"><span class="pre">class</span> <span class="pre">Module</span></tt>, but that’s not
|
||||||
|
important), and it will have functions, class constructors, variables
|
||||||
|
and constants. These Python objects will be accessible through the dot
|
||||||
|
operator.</p>
|
||||||
|
<p>An alternative way of writing import statements is</p>
|
||||||
|
<p><tt class="docutils literal"><span class="pre">from</span> <span class="pre">django.utils</span> <span class="pre">import</span> <span class="pre">encoding</span></tt></p>
|
||||||
|
<p>And then the variable will just be <tt class="docutils literal"><span class="pre">encoding</span></tt>. The <tt class="docutils literal"><span class="pre">encoding</span></tt>
|
||||||
|
module has a function for handling unicode-to-web translation.
|
||||||
|
Accessing it through the dot operator, it looks like this:</p>
|
||||||
|
<p><tt class="docutils literal"><span class="pre">ready_str</span> <span class="pre">=</span> <span class="pre">encoding.smart_str(unready_str)</span></tt></p>
|
||||||
|
<p>We call the parts of the import statement that describe the module the
|
||||||
|
<em>import string</em>.</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="sys-path-hooks-how-does-python-know-where-to-look">
|
||||||
|
<h3><tt class="docutils literal"><span class="pre">sys.path_hooks</span></tt>: How does Python know where to look?<a class="headerlink" href="#sys-path-hooks-how-does-python-know-where-to-look" title="Permalink to this headline">¶</a></h3>
|
||||||
|
<p>That’s what’s funny. Python has two independent ways of making sense of
|
||||||
|
of the import string. The old system is based on the assumption that
|
||||||
|
everything is a filesystem, with folders and filenames. This is called
|
||||||
|
the <tt class="docutils literal"><span class="pre">sys.path_hooks</span></tt> system.</p>
|
||||||
|
<p>In the old system, the parts of the import string would be split up, and
|
||||||
|
then a collection of directories would be scanned to see if the first
|
||||||
|
name in the import string could be matched with a subdirectory. If it
|
||||||
|
could, that directory would be scanned until the last name on the import
|
||||||
|
string. If that name was a <em>filename</em>, it would be loaded as a module.
|
||||||
|
If that name was a <em>directory</em> and that directory had a file named
|
||||||
|
<tt class="docutils literal"><span class="pre">__init__.py</span></tt>, then that file would be loaded as the module.</p>
|
||||||
|
<p>The <tt class="docutils literal"><span class="pre">sys.path_hooks</span></tt> array has a list of different methods for trying to
|
||||||
|
scan a filesystem for the parts of the import string. A <tt class="docutils literal"><span class="pre">path_hook</span></tt> is
|
||||||
|
a function that takes a path to a directory; if it can handle the
|
||||||
|
contents of the directory, it returns a <strong>Finder</strong>, an object whose job
|
||||||
|
is to figure out how to load the module; if it can’t, it returns an
|
||||||
|
ImportError exception. The object that loads the module is called,
|
||||||
|
naturally, a <strong>Loader</strong>.</p>
|
||||||
|
<ul class="simple">
|
||||||
|
<li>To read more about <strong>Finders</strong>, see <a class="reference internal" href="eli5.html#eli5-finders"><em>Finders</em></a></li>
|
||||||
|
<li>To read more about <strong>Loaders</strong>, see <a class="reference internal" href="eli5.html#eli5-loaders"><em>Loaders</em></a></li>
|
||||||
|
<li>To read more about <strong>Path Hooks</strong>, see <a class="reference internal" href="eli5.html#eli5-pathhooks"><em>Path Hooks</em></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="sys-path-what-directories-are-searched">
|
||||||
|
<h3><tt class="docutils literal"><span class="pre">sys.path</span></tt>: What directories are searched?<a class="headerlink" href="#sys-path-what-directories-are-searched" title="Permalink to this headline">¶</a></h3>
|
||||||
|
<p>The list of directories is stored in an array, <tt class="docutils literal"><span class="pre">sys.path</span></tt>. This path is
|
||||||
|
initialized by Python when it starts up, but programs can modify it at
|
||||||
|
run-time to point to extra directories if they want.</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="sys-meta-path-what-is-the-new-system">
|
||||||
|
<h3><tt class="docutils literal"><span class="pre">sys.meta_path</span></tt>: What is the new system?<a class="headerlink" href="#sys-meta-path-what-is-the-new-system" title="Permalink to this headline">¶</a></h3>
|
||||||
|
<p>The new system is called <tt class="docutils literal"><span class="pre">sys.meta_path</span></tt>, and it’s an array of
|
||||||
|
<strong>Finders</strong>, objects that have one method, <tt class="docutils literal"><span class="pre">find_module(fullname)</span></tt>.
|
||||||
|
It’s an anything-goes API that gives developers the freedom to import
|
||||||
|
modules from anywhere: databases, archives, remote web resources, even
|
||||||
|
code written on-the-fly internally. The new system can apply any
|
||||||
|
meaning at all to the import string.</p>
|
||||||
|
<p>In Python, the import string is offered to each object in
|
||||||
|
<tt class="docutils literal"><span class="pre">sys.meta_path</span></tt> before being offered to each <tt class="docutils literal"><span class="pre">sys.path_hook</span></tt>. The
|
||||||
|
filesystem is typically the last finder tried.</p>
|
||||||
|
<p>To read more about <strong>Meta Paths</strong>, see <a class="reference internal" href="eli5.html#eli5-metapaths"><em>Meta Paths</em></a></p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="is-it-different-between-python-2-and-python-3">
|
||||||
|
<h3>Is it different between Python 2 and Python 3?<a class="headerlink" href="#is-it-different-between-python-2-and-python-3" title="Permalink to this headline">¶</a></h3>
|
||||||
|
<p>Python 3 moves almost everything about this process into python’s
|
||||||
|
library, leaving only a bare minimum of functionality inside the Python
|
||||||
|
executable to load this library and run it. When the Python developers
|
||||||
|
did that, they added a lot of functionality to make it easier to write
|
||||||
|
new import modules. The old way still works, but there are now <em>Module
|
||||||
|
Specifications</em>, which are metadata about a module, and the old
|
||||||
|
<tt class="docutils literal"><span class="pre">path_hooks</span></tt> system is now just a <tt class="docutils literal"><span class="pre">meta_path</span></tt> handler added to the
|
||||||
|
new system as the last resort.</p>
|
||||||
|
<p>To read more about <strong>Module Specifications</strong>, see <a class="reference internal" href="eli5.html#eli5-specs"><em>Module Specifications</em></a></p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="does-the-old-system-still-matter">
|
||||||
|
<h3>Does the old system still matter?<a class="headerlink" href="#does-the-old-system-still-matter" title="Permalink to this headline">¶</a></h3>
|
||||||
|
<p>Yes, for one reason: <em>iteration</em>. Iteration is the ability to take a
|
||||||
|
path where you believe Python modules can be found, and list through
|
||||||
|
them. This facility is useful for large frameworks where a user wants
|
||||||
|
to add new commands, or new objects, or new operations; Django uses this
|
||||||
|
facility a lot! The <tt class="docutils literal"><span class="pre">pkgutil</span></tt> library depends upon Finders being able
|
||||||
|
to iterate their contents.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sphinxsidebar">
|
||||||
|
<div class="sphinxsidebarwrapper">
|
||||||
|
<h3><a href="index.html">Table Of Contents</a></h3>
|
||||||
|
<ul>
|
||||||
|
<li><a class="reference internal" href="#">Details on Import and Polyloader</a><ul>
|
||||||
|
<li><a class="reference internal" href="#welcome-to-the-python-import-eli5">Welcome to the Python Import ELI5!</a><ul>
|
||||||
|
<li><a class="reference internal" href="#what-is-import">What is <cite>import</cite>?</a></li>
|
||||||
|
<li><a class="reference internal" href="#sys-path-hooks-how-does-python-know-where-to-look"><tt class="docutils literal"><span class="pre">sys.path_hooks</span></tt>: How does Python know where to look?</a></li>
|
||||||
|
<li><a class="reference internal" href="#sys-path-what-directories-are-searched"><tt class="docutils literal"><span class="pre">sys.path</span></tt>: What directories are searched?</a></li>
|
||||||
|
<li><a class="reference internal" href="#sys-meta-path-what-is-the-new-system"><tt class="docutils literal"><span class="pre">sys.meta_path</span></tt>: What is the new system?</a></li>
|
||||||
|
<li><a class="reference internal" href="#is-it-different-between-python-2-and-python-3">Is it different between Python 2 and Python 3?</a></li>
|
||||||
|
<li><a class="reference internal" href="#does-the-old-system-still-matter">Does the old system still matter?</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>Previous topic</h4>
|
||||||
|
<p class="topless"><a href="usage.html"
|
||||||
|
title="previous chapter">Usage</a></p>
|
||||||
|
<h4>Next topic</h4>
|
||||||
|
<p class="topless"><a href="contributing.html"
|
||||||
|
title="next chapter"><no title></a></p>
|
||||||
|
<h3>This Page</h3>
|
||||||
|
<ul class="this-page-menu">
|
||||||
|
<li><a href="_sources/details.txt"
|
||||||
|
rel="nofollow">Show Source</a></li>
|
||||||
|
</ul>
|
||||||
|
<div id="searchbox" style="display: none">
|
||||||
|
<h3>Quick search</h3>
|
||||||
|
<form class="search" action="search.html" method="get">
|
||||||
|
<input type="text" name="q" />
|
||||||
|
<input type="submit" value="Go" />
|
||||||
|
<input type="hidden" name="check_keywords" value="yes" />
|
||||||
|
<input type="hidden" name="area" value="default" />
|
||||||
|
</form>
|
||||||
|
<p class="searchtip" style="font-size: 90%">
|
||||||
|
Enter search terms or a module, class or function name.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">$('#searchbox').show(0);</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="clearer"></div>
|
||||||
|
</div>
|
||||||
|
<div class="related">
|
||||||
|
<h3>Navigation</h3>
|
||||||
|
<ul>
|
||||||
|
<li class="right" style="margin-right: 10px">
|
||||||
|
<a href="genindex.html" title="General Index"
|
||||||
|
>index</a></li>
|
||||||
|
<li class="right" >
|
||||||
|
<a href="py-modindex.html" title="Python Module Index"
|
||||||
|
>modules</a> |</li>
|
||||||
|
<li class="right" >
|
||||||
|
<a href="contributing.html" title="<no title>"
|
||||||
|
>next</a> |</li>
|
||||||
|
<li class="right" >
|
||||||
|
<a href="usage.html" title="Usage"
|
||||||
|
>previous</a> |</li>
|
||||||
|
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
© Copyright 2016, Kenneth M. "Elf" Sternberg.
|
||||||
|
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.2.
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,126 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
|
||||||
|
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
|
||||||
|
<title>ELI5: Explain Like I’m Five! — polyloader 0.1.0 documentation</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||||
|
<link rel="stylesheet" href="pygments.css" type="text/css" />
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var DOCUMENTATION_OPTIONS = {
|
||||||
|
URL_ROOT: './',
|
||||||
|
VERSION: '0.1.0',
|
||||||
|
COLLAPSE_INDEX: false,
|
||||||
|
FILE_SUFFIX: '.html',
|
||||||
|
HAS_SOURCE: true
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="underscore.js"></script>
|
||||||
|
<script type="text/javascript" src="doctools.js"></script>
|
||||||
|
<link rel="top" title="polyloader 0.1.0 documentation" href="index.html" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="related">
|
||||||
|
<h3>Navigation</h3>
|
||||||
|
<ul>
|
||||||
|
<li class="right" style="margin-right: 10px">
|
||||||
|
<a href="genindex.html" title="General Index"
|
||||||
|
accesskey="I">index</a></li>
|
||||||
|
<li class="right" >
|
||||||
|
<a href="py-modindex.html" title="Python Module Index"
|
||||||
|
>modules</a> |</li>
|
||||||
|
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="document">
|
||||||
|
<div class="documentwrapper">
|
||||||
|
<div class="bodywrapper">
|
||||||
|
<div class="body">
|
||||||
|
|
||||||
|
<div class="section" id="eli5-explain-like-i-m-five">
|
||||||
|
<h1>ELI5: Explain Like I’m Five!<a class="headerlink" href="#eli5-explain-like-i-m-five" title="Permalink to this headline">¶</a></h1>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="finders">
|
||||||
|
<span id="eli5-finders"></span><h1>Finders<a class="headerlink" href="#finders" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<p>TODO</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="loaders">
|
||||||
|
<span id="eli5-loaders"></span><h1>Loaders<a class="headerlink" href="#loaders" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<p>TODO</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="path-hooks">
|
||||||
|
<span id="eli5-pathhooks"></span><h1>Path Hooks<a class="headerlink" href="#path-hooks" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<p>TODO</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="meta-paths">
|
||||||
|
<span id="eli5-metapaths"></span><h1>Meta Paths<a class="headerlink" href="#meta-paths" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<p>TODO</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="module-specifications">
|
||||||
|
<span id="eli5-specs"></span><h1>Module Specifications<a class="headerlink" href="#module-specifications" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<p>TODO</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sphinxsidebar">
|
||||||
|
<div class="sphinxsidebarwrapper">
|
||||||
|
<h3><a href="index.html">Table Of Contents</a></h3>
|
||||||
|
<ul>
|
||||||
|
<li><a class="reference internal" href="#">ELI5: Explain Like I’m Five!</a></li>
|
||||||
|
<li><a class="reference internal" href="#finders">Finders</a></li>
|
||||||
|
<li><a class="reference internal" href="#loaders">Loaders</a></li>
|
||||||
|
<li><a class="reference internal" href="#path-hooks">Path Hooks</a></li>
|
||||||
|
<li><a class="reference internal" href="#meta-paths">Meta Paths</a></li>
|
||||||
|
<li><a class="reference internal" href="#module-specifications">Module Specifications</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>This Page</h3>
|
||||||
|
<ul class="this-page-menu">
|
||||||
|
<li><a href="_sources/eli5.txt"
|
||||||
|
rel="nofollow">Show Source</a></li>
|
||||||
|
</ul>
|
||||||
|
<div id="searchbox" style="display: none">
|
||||||
|
<h3>Quick search</h3>
|
||||||
|
<form class="search" action="search.html" method="get">
|
||||||
|
<input type="text" name="q" />
|
||||||
|
<input type="submit" value="Go" />
|
||||||
|
<input type="hidden" name="check_keywords" value="yes" />
|
||||||
|
<input type="hidden" name="area" value="default" />
|
||||||
|
</form>
|
||||||
|
<p class="searchtip" style="font-size: 90%">
|
||||||
|
Enter search terms or a module, class or function name.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">$('#searchbox').show(0);</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="clearer"></div>
|
||||||
|
</div>
|
||||||
|
<div class="related">
|
||||||
|
<h3>Navigation</h3>
|
||||||
|
<ul>
|
||||||
|
<li class="right" style="margin-right: 10px">
|
||||||
|
<a href="genindex.html" title="General Index"
|
||||||
|
>index</a></li>
|
||||||
|
<li class="right" >
|
||||||
|
<a href="py-modindex.html" title="Python Module Index"
|
||||||
|
>modules</a> |</li>
|
||||||
|
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
© Copyright 2016, Kenneth M. "Elf" Sternberg.
|
||||||
|
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.2.
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -6,7 +6,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
|
||||||
<title>Welcome to py-polymorphic-loader’s documentation! — polyloader 0.1.0 documentation</title>
|
<title>Welcome to polyloader — polyloader 0.1.0 documentation</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||||
<link rel="stylesheet" href="pygments.css" type="text/css" />
|
<link rel="stylesheet" href="pygments.css" type="text/css" />
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<script type="text/javascript" src="underscore.js"></script>
|
<script type="text/javascript" src="underscore.js"></script>
|
||||||
<script type="text/javascript" src="doctools.js"></script>
|
<script type="text/javascript" src="doctools.js"></script>
|
||||||
<link rel="top" title="polyloader 0.1.0 documentation" href="#" />
|
<link rel="top" title="polyloader 0.1.0 documentation" href="#" />
|
||||||
<link rel="next" title="<no title>" href="readme.html" />
|
<link rel="next" title="Synopsis" href="readme.html" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="related">
|
<div class="related">
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<a href="py-modindex.html" title="Python Module Index"
|
<a href="py-modindex.html" title="Python Module Index"
|
||||||
>modules</a> |</li>
|
>modules</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="readme.html" title="<no title>"
|
<a href="readme.html" title="Synopsis"
|
||||||
accesskey="N">next</a> |</li>
|
accesskey="N">next</a> |</li>
|
||||||
<li><a href="#">polyloader 0.1.0 documentation</a> »</li>
|
<li><a href="#">polyloader 0.1.0 documentation</a> »</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -48,17 +48,25 @@
|
||||||
<div class="bodywrapper">
|
<div class="bodywrapper">
|
||||||
<div class="body">
|
<div class="body">
|
||||||
|
|
||||||
<div class="section" id="welcome-to-py-polymorphic-loader-s-documentation">
|
<div class="section" id="welcome-to-polyloader">
|
||||||
<h1>Welcome to py-polymorphic-loader’s documentation!<a class="headerlink" href="#welcome-to-py-polymorphic-loader-s-documentation" title="Permalink to this headline">¶</a></h1>
|
<h1>Welcome to polyloader<a class="headerlink" href="#welcome-to-polyloader" title="Permalink to this headline">¶</a></h1>
|
||||||
<p>Contents:</p>
|
<p>Contents:</p>
|
||||||
<div class="toctree-wrapper compound">
|
<div class="toctree-wrapper compound">
|
||||||
<ul>
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="readme.html">Synopsis</a></li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="readme.html#say-what">Say What?</a></li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="readme.html#what-s-the-real-problem">What’s the real problem?</a></li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="readme.html#what-the-solution">What the solution?</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="installation.html">Installation</a><ul>
|
<li class="toctree-l1"><a class="reference internal" href="installation.html">Installation</a><ul>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="installation.html#stable-release">Stable release</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="installation.html#stable-release">Stable release</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="installation.html#from-sources">From sources</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="installation.html#from-sources">From sources</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="usage.html">Usage</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="usage.html">Usage</a></li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="details.html">Details on Import and Polyloader</a><ul>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="details.html#welcome-to-the-python-import-eli5">Welcome to the Python Import ELI5!</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,13 +87,13 @@
|
||||||
<div class="sphinxsidebarwrapper">
|
<div class="sphinxsidebarwrapper">
|
||||||
<h3><a href="#">Table Of Contents</a></h3>
|
<h3><a href="#">Table Of Contents</a></h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a class="reference internal" href="#">Welcome to py-polymorphic-loader’s documentation!</a></li>
|
<li><a class="reference internal" href="#">Welcome to polyloader</a></li>
|
||||||
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
|
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h4>Next topic</h4>
|
<h4>Next topic</h4>
|
||||||
<p class="topless"><a href="readme.html"
|
<p class="topless"><a href="readme.html"
|
||||||
title="next chapter"><no title></a></p>
|
title="next chapter">Synopsis</a></p>
|
||||||
<h3>This Page</h3>
|
<h3>This Page</h3>
|
||||||
<ul class="this-page-menu">
|
<ul class="this-page-menu">
|
||||||
<li><a href="_sources/index.txt"
|
<li><a href="_sources/index.txt"
|
||||||
|
@ -118,7 +126,7 @@
|
||||||
<a href="py-modindex.html" title="Python Module Index"
|
<a href="py-modindex.html" title="Python Module Index"
|
||||||
>modules</a> |</li>
|
>modules</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="readme.html" title="<no title>"
|
<a href="readme.html" title="Synopsis"
|
||||||
>next</a> |</li>
|
>next</a> |</li>
|
||||||
<li><a href="#">polyloader 0.1.0 documentation</a> »</li>
|
<li><a href="#">polyloader 0.1.0 documentation</a> »</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<script type="text/javascript" src="doctools.js"></script>
|
<script type="text/javascript" src="doctools.js"></script>
|
||||||
<link rel="top" title="polyloader 0.1.0 documentation" href="index.html" />
|
<link rel="top" title="polyloader 0.1.0 documentation" href="index.html" />
|
||||||
<link rel="next" title="Usage" href="usage.html" />
|
<link rel="next" title="Usage" href="usage.html" />
|
||||||
<link rel="prev" title="<no title>" href="readme.html" />
|
<link rel="prev" title="Synopsis" href="readme.html" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="related">
|
<div class="related">
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<a href="usage.html" title="Usage"
|
<a href="usage.html" title="Usage"
|
||||||
accesskey="N">next</a> |</li>
|
accesskey="N">next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="readme.html" title="<no title>"
|
<a href="readme.html" title="Synopsis"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -56,8 +56,8 @@
|
||||||
<h1>Installation<a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h1>
|
<h1>Installation<a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h1>
|
||||||
<div class="section" id="stable-release">
|
<div class="section" id="stable-release">
|
||||||
<h2>Stable release<a class="headerlink" href="#stable-release" title="Permalink to this headline">¶</a></h2>
|
<h2>Stable release<a class="headerlink" href="#stable-release" title="Permalink to this headline">¶</a></h2>
|
||||||
<p>To install py-polymorphic-loader, run this command in your terminal:</p>
|
<p>To install polyloader, run this command in your terminal:</p>
|
||||||
<div class="highlight-console"><div class="highlight"><pre><span class="gp">$</span> pip install py-polymorphic-loader
|
<div class="highlight-console"><div class="highlight"><pre><span class="gp">$</span> pip install polyloader
|
||||||
</pre></div>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
<p>If you don’t have <a class="reference external" href="https://pip.pypa.io">pip</a> installed, this <a class="reference external" href="http://docs.python-guide.org/en/latest/starting/installation/">Python installation guide</a> can guide
|
<p>If you don’t have <a class="reference external" href="https://pip.pypa.io">pip</a> installed, this <a class="reference external" href="http://docs.python-guide.org/en/latest/starting/installation/">Python installation guide</a> can guide
|
||||||
|
@ -65,13 +65,13 @@ you through the process.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="from-sources">
|
<div class="section" id="from-sources">
|
||||||
<h2>From sources<a class="headerlink" href="#from-sources" title="Permalink to this headline">¶</a></h2>
|
<h2>From sources<a class="headerlink" href="#from-sources" title="Permalink to this headline">¶</a></h2>
|
||||||
<p>The sources for py-polymorphic-loader can be downloaded from the <a class="reference external" href="https://github.com/elfsternberg/py-polymorphic-loader">Github repo</a>.</p>
|
<p>The sources for polyloader can be downloaded from the <a class="reference external" href="https://github.com/elfsternberg/polyloader">Github repo</a>.</p>
|
||||||
<p>You can either clone the public repository:</p>
|
<p>You can either clone the public repository:</p>
|
||||||
<div class="highlight-console"><div class="highlight"><pre><span class="gp">$</span> git clone git://github.com/elfsternberg/py-polymorphic-loader
|
<div class="highlight-console"><div class="highlight"><pre><span class="gp">$</span> git clone git://github.com/elfsternberg/polyloader
|
||||||
</pre></div>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
<p>Or download the <a class="reference external" href="https://github.com/elfsternberg/py-polymorphic-loader/tarball/master">tarball</a>:</p>
|
<p>Or download the <a class="reference external" href="https://github.com/elfsternberg/polyloader/tarball/master">tarball</a>:</p>
|
||||||
<div class="highlight-console"><div class="highlight"><pre><span class="gp">$</span> curl -OL https://github.com/elfsternberg/py-polymorphic-loader/tarball/master
|
<div class="highlight-console"><div class="highlight"><pre><span class="gp">$</span> curl -OL https://github.com/elfsternberg/polyloader/tarball/master
|
||||||
</pre></div>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
<p>Once you have a copy of the source, you can install it with:</p>
|
<p>Once you have a copy of the source, you can install it with:</p>
|
||||||
|
@ -98,7 +98,7 @@ you through the process.</p>
|
||||||
|
|
||||||
<h4>Previous topic</h4>
|
<h4>Previous topic</h4>
|
||||||
<p class="topless"><a href="readme.html"
|
<p class="topless"><a href="readme.html"
|
||||||
title="previous chapter"><no title></a></p>
|
title="previous chapter">Synopsis</a></p>
|
||||||
<h4>Next topic</h4>
|
<h4>Next topic</h4>
|
||||||
<p class="topless"><a href="usage.html"
|
<p class="topless"><a href="usage.html"
|
||||||
title="next chapter">Usage</a></p>
|
title="next chapter">Usage</a></p>
|
||||||
|
@ -137,7 +137,7 @@ you through the process.</p>
|
||||||
<a href="usage.html" title="Usage"
|
<a href="usage.html" title="Usage"
|
||||||
>next</a> |</li>
|
>next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="readme.html" title="<no title>"
|
<a href="readme.html" title="Synopsis"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -2,6 +2,4 @@
|
||||||
# Project: polyloader
|
# Project: polyloader
|
||||||
# Version: 0.1.0
|
# Version: 0.1.0
|
||||||
# The remainder of this file is compressed using zlib.
|
# The remainder of this file is compressed using zlib.
|
||||||
xÚŤŽ=
|
xΪ<EFBFBD><EFBFBD>Α‚0†ο<EΉ<>ΘΑ`4Ρ„„'<27>P`±l„<6C>Dή^fg5ΔΫςχϋΊ¶
j¥+Ό<>uUFς‚"…&¤Iλ:ΪΐΡΏ#$µµΟ»Δ}…ΡφD<>©~4ξ'ρ,„ήgS<67>„α‹r(Ϋ¥ΒY rΩ ΟCF®Οsb€ι^Ί¶5ζΊΒη3Ο°<CE9F>΅“^[QΞ3ςπ‚b{,ΧpήΈ<CEAE>)U«R:e΄<65>zC/3)λ<>ΩΒ+f<>"ρf$Ztή«G]ϊ~<7E>~™<1F><>ΦIΆ?¤;<3B>Y½p
|
||||||
Ă0F÷śBЬ͚t(z7V<12>l[<5B>ćöm<C3B6>K‡®ď{)°óŃᲸŽě LójBšIíŕČn!„ÆŞăŹčAKˇjF›úé]TV´ł
|
|
||||||
';b53ÄÖaşĐ=ą‡'ÖFS<>y)š„eë†%öâ9BűU~$>f±DD7“9h”
|
|
|
@ -6,7 +6,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
|
||||||
<title><no title> — polyloader 0.1.0 documentation</title>
|
<title>Synopsis — polyloader 0.1.0 documentation</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||||
<link rel="stylesheet" href="pygments.css" type="text/css" />
|
<link rel="stylesheet" href="pygments.css" type="text/css" />
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
<script type="text/javascript" src="doctools.js"></script>
|
<script type="text/javascript" src="doctools.js"></script>
|
||||||
<link rel="top" title="polyloader 0.1.0 documentation" href="index.html" />
|
<link rel="top" title="polyloader 0.1.0 documentation" href="index.html" />
|
||||||
<link rel="next" title="Installation" href="installation.html" />
|
<link rel="next" title="Installation" href="installation.html" />
|
||||||
<link rel="prev" title="Welcome to py-polymorphic-loader’s documentation!" href="index.html" />
|
<link rel="prev" title="Welcome to polyloader" href="index.html" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="related">
|
<div class="related">
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<a href="installation.html" title="Installation"
|
<a href="installation.html" title="Installation"
|
||||||
accesskey="N">next</a> |</li>
|
accesskey="N">next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="index.html" title="Welcome to py-polymorphic-loader’s documentation!"
|
<a href="index.html" title="Welcome to polyloader"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -52,6 +52,62 @@
|
||||||
<div class="bodywrapper">
|
<div class="bodywrapper">
|
||||||
<div class="body">
|
<div class="body">
|
||||||
|
|
||||||
|
<div class="section" id="synopsis">
|
||||||
|
<h1>Synopsis<a class="headerlink" href="#synopsis" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<p><strong>Polyloader</strong> is a python module that extends the Python <cite>import</cite>
|
||||||
|
statement to enable the discovery and loading of heterogenous source
|
||||||
|
code packages.</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="say-what">
|
||||||
|
<h1>Say What?<a class="headerlink" href="#say-what" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<p>The <tt class="docutils literal"><span class="pre">import</span></tt> statement is how the Python interpreter finds a module
|
||||||
|
written in Python and loads it, turning it into variables, executable
|
||||||
|
functions, constructable classes, and other Python objects, and then
|
||||||
|
exposes those objects to the currently running program.</p>
|
||||||
|
<p>The <tt class="docutils literal"><span class="pre">import</span></tt> statement has long been extensible so that things other
|
||||||
|
than Python code could be imported, but this feature has always had two
|
||||||
|
limitations:</p>
|
||||||
|
<ol class="arabic simple">
|
||||||
|
<li>It’s annoyingly hard to write an importer. (Believe me. Polyloader
|
||||||
|
<em>is</em> one!)</li>
|
||||||
|
<li>For filesystem-based modules (which is 99% of them) Python’s importer
|
||||||
|
only understands one loader type per directory. It’s not possible to
|
||||||
|
store code or data written in something other than Python in the same
|
||||||
|
directory with Python module code and load it via <tt class="docutils literal"><span class="pre">import</span></tt>.</li>
|
||||||
|
</ol>
|
||||||
|
<p>The former requires a certain degree of abstraction and thought. For
|
||||||
|
the latter, most people ignore the problem and load module configuration
|
||||||
|
files written in JSON or YAML or whatever directly. This is fine,
|
||||||
|
except when you want to write in one of Python’s extended languages like
|
||||||
|
Hy or Coconut in a framework like Django, Flask or Glitch.</p>
|
||||||
|
<p><strong>Polyloader</strong> eliminates these limitations.</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="what-s-the-real-problem">
|
||||||
|
<h1>What’s the real problem?<a class="headerlink" href="#what-s-the-real-problem" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<p>The real problem is that Python’s traditional extensions, <tt class="docutils literal"><span class="pre">.py</span></tt>,
|
||||||
|
<tt class="docutils literal"><span class="pre">.pyc/.pyo</span></tt>, and <tt class="docutils literal"><span class="pre">.so/.dll</span></tt> files, are hard-coded in Python. In
|
||||||
|
Python 2, they’re in the <tt class="docutils literal"><span class="pre">imp</span></tt> builtin; In Python 3, they’re defined
|
||||||
|
in a private section of <cite>importlib</cite>. Either way, they’re not accessible
|
||||||
|
for modification and extension.</p>
|
||||||
|
<p>This problem is made harder by the <tt class="docutils literal"><span class="pre">pkglib</span></tt> module, which is part of
|
||||||
|
Python’s standard library. This module uses <tt class="docutils literal"><span class="pre">inspect.getmoduleinfo</span></tt>,
|
||||||
|
which again only recognizes the usual extensions. Which means you can’t
|
||||||
|
list multilingual modules either; this hampers the development of Django
|
||||||
|
management commands in a syntax other than Python.</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="what-the-solution">
|
||||||
|
<h1>What the solution?<a class="headerlink" href="#what-the-solution" title="Permalink to this headline">¶</a></h1>
|
||||||
|
<p>At its heart, the Python import system runs two different internal
|
||||||
|
mechanisms to figure out what the <em>import string</em> (the dotted terms
|
||||||
|
after the word “import”) “means.” Each mechanism has one or more
|
||||||
|
<em>finders</em>, and the first finder to report “I have a <em>loader</em> that knows
|
||||||
|
what that import string means” wins.</p>
|
||||||
|
<p>The very last finder is for the filesystem. The solution is to get in
|
||||||
|
front of that finder with one that can handle all the other syntax
|
||||||
|
loaders <em>and</em> knows how to fall back on the last one for those files the
|
||||||
|
last one handles.</p>
|
||||||
|
<p>That’s what <tt class="docutils literal"><span class="pre">polyloader</span></tt> does.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,9 +115,17 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="sphinxsidebar">
|
<div class="sphinxsidebar">
|
||||||
<div class="sphinxsidebarwrapper">
|
<div class="sphinxsidebarwrapper">
|
||||||
|
<h3><a href="index.html">Table Of Contents</a></h3>
|
||||||
|
<ul>
|
||||||
|
<li><a class="reference internal" href="#">Synopsis</a></li>
|
||||||
|
<li><a class="reference internal" href="#say-what">Say What?</a></li>
|
||||||
|
<li><a class="reference internal" href="#what-s-the-real-problem">What’s the real problem?</a></li>
|
||||||
|
<li><a class="reference internal" href="#what-the-solution">What the solution?</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<h4>Previous topic</h4>
|
<h4>Previous topic</h4>
|
||||||
<p class="topless"><a href="index.html"
|
<p class="topless"><a href="index.html"
|
||||||
title="previous chapter">Welcome to py-polymorphic-loader’s documentation!</a></p>
|
title="previous chapter">Welcome to polyloader</a></p>
|
||||||
<h4>Next topic</h4>
|
<h4>Next topic</h4>
|
||||||
<p class="topless"><a href="installation.html"
|
<p class="topless"><a href="installation.html"
|
||||||
title="next chapter">Installation</a></p>
|
title="next chapter">Installation</a></p>
|
||||||
|
@ -100,7 +164,7 @@
|
||||||
<a href="installation.html" title="Installation"
|
<a href="installation.html" title="Installation"
|
||||||
>next</a> |</li>
|
>next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="index.html" title="Welcome to py-polymorphic-loader’s documentation!"
|
<a href="index.html" title="Welcome to polyloader"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
<li><a href="index.html">polyloader 0.1.0 documentation</a> »</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Search.setIndex({envversion:42,terms:{compil:[7,8],set:8,suffix:[7,8],creat:8,process:1,onc:1,modul:[0,2],automat:8,pip:1,through:1,have:1,instal:0,tarbal:1,stabl:0,download:1,guid:1,assum:8,your:1,page:0,index:0,git:1,from:0,activ:8,content:[0,2],leav:8,which:8,master:1,you:1,"public":1,can:1,elfsternberg:1,setup:1,sourc:0,run:[8,1],thi:1,python:[8,1],usag:0,clone:1,copi:1,upon:8,curl:1,standard:8,repo:1,releas:0,mechan:8,repositori:1,termin:1,pair:8,don:1,reset:7,search:0,github:1,last:8,packag:2,remov:8,current:8,http:1,manag:8,project:6,instanc:8,command:1,either:1,context:8,lifetim:8,com:1,scope:8,"import":6},objtypes:{"0":"py:module","1":"py:function"},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"]},filenames:["index","installation","modules","contributing","readme","authors","usage","polyloader","todo","history"],titles:["Welcome to py-polymorphic-loader’s documentation!","Installation","polyloader","<no title>","<no title>","<no title>","Usage","polyloader package","<no title>","<no title>"],objects:{"":{polyloader:[7,0,0,"-"]},polyloader:{reset:[7,1,1,""],install:[7,1,1,""]}},titleterms:{polymorph:0,sourc:1,from:1,welcom:0,modul:7,usag:6,indic:0,loader:0,content:7,packag:7,polyload:[7,2],tabl:0,releas:1,stabl:1,document:0,instal:1}})
|
Search.setIndex({envversion:42,terms:{load:[9,5],all:[9,5],code:[9,5],just:[7,5],move:5,multilingu:9,syntax:[7,9],veri:9,through:[1,5],abil:5,follow:7,discoveri:9,annoyingli:9,find:[9,5],languag:9,suffix:[8,10],access:[9,5],onli:[9,5],depend:5,execut:[9,5],smart_str:5,flask:9,point:5,had:[9,5],except:[9,5],than:9,resort:5,add:[7,5],program:[9,5],those:9,appli:5,reason:5,sens:5,folder:5,main:7,app:7,match:5,take:5,real:0,fly:5,them:[9,5],sourc:0,"return":5,string:[9,5],thei:[9,5],get:9,handl:[9,5],initi:5,util:5,framework:[9,5],ast_compil:7,mechan:[9,10],fall:9,front:9,now:[7,5],archiv:5,requir:9,name:5,tri:5,term:9,like:5,specif:5,hook:5,edit:7,anyth:5,list:[9,5],iter:5,method:5,"try":5,collect:5,either:[9,1],each:[9,5],did:5,unicod:5,page:0,mean:[9,5],compil:[7,8,10],everyth:[7,5],been:9,set:10,natur:5,hard:9,resourc:5,assumpt:5,see:5,meta:5,bare:5,stabl:0,download:1,http:1,fullnam:5,todo:4,hamper:9,librari:[7,9,5],out:[9,5],variabl:[9,5],index:0,insid:5,goe:5,unready_str:5,someth:9,abl:5,per:9,dll:9,current:[9,10,5],figur:[9,5],leav:[10,5],limit:9,content:[0,2,5],"public":1,metadata:5,altern:5,elfsternberg:1,elimin:9,object:[9,5],run:[9,10,1,5],extend:9,web:5,importerror:5,inspect:9,usag:0,privat:9,standard:[9,10],extens:9,job:5,base:[9,5],modif:9,believ:[9,5],repositori:1,found:5,releas:0,from:[0,5],process:[1,5],modifi:5,problem:0,interpret:9,importlib:9,about:5,last:[9,10,5],would:5,befor:5,freedom:5,could:[9,5],success:5,manag:[7,9,10],turn:9,degre:9,instanc:10,context:10,constructor:5,typic:5,view:7,com:1,first:[9,5],oper:5,via:9,user:5,finder:5,directli:9,extra:5,win:9,arrai:5,independ:5,encod:5,pkglib:9,automat:10,loader:5,mochi:7,glitch:9,api:5,yaml:9,latter:9,instal:0,guid:1,facil:5,your:[7,1],git:1,ready_str:5,pkgutil:5,wai:[9,5],script:7,top:7,scan:5,two:[9,5],"long":9,github:1,avail:5,start:5,json:9,handler:5,master:1,statement:[9,5],time:5,call:5,type:9,until:5,store:[9,5],more:[9,5],"function":[9,5],setup:1,lot:5,offer:5,termin:1,peopl:9,copi:1,back:9,remot:5,part:[9,5],understand:9,translat:5,scope:[10,5],line:7,former:9,written:[7,9,5],reset:8,made:[9,5],word:9,describ:5,possibl:9,launcher:7,remov:10,work:[7,5],harder:9,intern:[9,5],can:[7,9,1,5],easier:5,defin:9,"__init__":5,minimum:5,compile_fil:7,whatev:9,assum:10,report:9,modul:5,find_modul:5,heart:9,coconut:9,featur:9,constant:5,file:[9,5],creat:10,give:5,almost:5,certain:9,"abstract":9,filenam:5,ani:5,activ:10,packag:2,pip:1,hy_compil:7,have:[7,9,1,5],tarbal:1,synopsi:0,curl:1,sai:0,getmoduleinfo:9,alwai:9,develop:[9,5],want:[7,9,5],thing:9,make:5,expos:9,when:[9,5],same:9,write:[7,9,5],funni:5,builtin:9,other:9,read:5,split:5,which:[9,10,5],subdirectori:5,command:[9,1,5],you:[7,9,1,5],mochi_compil:7,enabl:9,even:5,imp:9,recogn:9,again:9,configur:9,clone:1,after:9,upon:[10,5],solut:0,most:9,larg:5,plan:7,pyo:9,pair:10,construct:9,pyc:9,data:9,"class":[9,5],tradit:9,repo:1,lifetim:10,don:1,whose:5,filesystem:[9,5],anywher:5,well:7,fine:9,django:[7,9,5],thought:9,heterogen:9,exampl:7,ignor:9,thi:[9,1,5],databas:5,onc:1,model:[7,5],section:9,dot:[9,5],usual:9},objtypes:{"0":"py:module","1":"py:function"},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"]},filenames:["index","installation","modules","contributing","eli5","details","authors","usage","polyloader","readme","todo","history"],titles:["Welcome to polyloader","Installation","polyloader","<no title>","ELI5: Explain Like I’m Five!","Details on Import and Polyloader","<no title>","Usage","polyloader package","Synopsis","<no title>","<no title>"],objects:{"":{polyloader:[8,0,0,"-"]},polyloader:{reset:[8,1,1,""],install:[8,1,1,""]}},titleterms:{sai:9,old:5,modul:[4,8],meta_path:5,system:5,hook:4,meta:4,tabl:0,stabl:1,still:5,what:[9,5],from:1,welcom:[0,5],explain:4,solut:9,detail:5,content:8,how:5,between:5,"new":5,instal:1,finder:4,real:9,sourc:1,synopsi:9,python:5,usag:7,differ:5,eli5:[4,5],path_hook:5,indic:0,"import":5,releas:1,path:[4,5],loader:4,look:5,search:5,like:4,specif:4,packag:8,directori:5,doe:5,matter:5,polyload:[0,2,5,8],five:4,problem:9,where:5,know:5}})
|
|
@ -0,0 +1,111 @@
|
||||||
|
Details on Import and Polyloader
|
||||||
|
================================
|
||||||
|
|
||||||
|
Welcome to the Python Import ELI5!
|
||||||
|
**********************************
|
||||||
|
|
||||||
|
What is `import`?
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
``import`` is a Python statement that finds a *module* that is accessible
|
||||||
|
by the currently running process, loads it, and makes its contents
|
||||||
|
available to the scope in which the statement was made. A statement
|
||||||
|
like
|
||||||
|
|
||||||
|
``import django.db.models``
|
||||||
|
|
||||||
|
is looking for a module named ``django.db.models``. If the statement is
|
||||||
|
successful, ``django.db.models`` will be a variable name in the scope,
|
||||||
|
it will be a Python *object* (of ``class Module``, but that's not
|
||||||
|
important), and it will have functions, class constructors, variables
|
||||||
|
and constants. These Python objects will be accessible through the dot
|
||||||
|
operator.
|
||||||
|
|
||||||
|
An alternative way of writing import statements is
|
||||||
|
|
||||||
|
``from django.utils import encoding``
|
||||||
|
|
||||||
|
And then the variable will just be ``encoding``. The ``encoding``
|
||||||
|
module has a function for handling unicode-to-web translation.
|
||||||
|
Accessing it through the dot operator, it looks like this:
|
||||||
|
|
||||||
|
``ready_str = encoding.smart_str(unready_str)``
|
||||||
|
|
||||||
|
We call the parts of the import statement that describe the module the
|
||||||
|
*import string*.
|
||||||
|
|
||||||
|
``sys.path_hooks``: How does Python know where to look?
|
||||||
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
That's what's funny. Python has two independent ways of making sense of
|
||||||
|
of the import string. The old system is based on the assumption that
|
||||||
|
everything is a filesystem, with folders and filenames. This is called
|
||||||
|
the ``sys.path_hooks`` system.
|
||||||
|
|
||||||
|
In the old system, the parts of the import string would be split up, and
|
||||||
|
then a collection of directories would be scanned to see if the first
|
||||||
|
name in the import string could be matched with a subdirectory. If it
|
||||||
|
could, that directory would be scanned until the last name on the import
|
||||||
|
string. If that name was a *filename*, it would be loaded as a module.
|
||||||
|
If that name was a *directory* and that directory had a file named
|
||||||
|
``__init__.py``, then that file would be loaded as the module.
|
||||||
|
|
||||||
|
The ``sys.path_hooks`` array has a list of different methods for trying to
|
||||||
|
scan a filesystem for the parts of the import string. A ``path_hook`` is
|
||||||
|
a function that takes a path to a directory; if it can handle the
|
||||||
|
contents of the directory, it returns a **Finder**, an object whose job
|
||||||
|
is to figure out how to load the module; if it can't, it returns an
|
||||||
|
ImportError exception. The object that loads the module is called,
|
||||||
|
naturally, a **Loader**.
|
||||||
|
|
||||||
|
* To read more about **Finders**, see :ref:`eli5-finders`
|
||||||
|
* To read more about **Loaders**, see :ref:`eli5-loaders`
|
||||||
|
* To read more about **Path Hooks**, see :ref:`eli5-pathhooks`
|
||||||
|
|
||||||
|
``sys.path``: What directories are searched?
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
The list of directories is stored in an array, ``sys.path``. This path is
|
||||||
|
initialized by Python when it starts up, but programs can modify it at
|
||||||
|
run-time to point to extra directories if they want.
|
||||||
|
|
||||||
|
|
||||||
|
``sys.meta_path``: What is the new system?
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
The new system is called ``sys.meta_path``, and it's an array of
|
||||||
|
**Finders**, objects that have one method, ``find_module(fullname)``.
|
||||||
|
It's an anything-goes API that gives developers the freedom to import
|
||||||
|
modules from anywhere: databases, archives, remote web resources, even
|
||||||
|
code written on-the-fly internally. The new system can apply any
|
||||||
|
meaning at all to the import string.
|
||||||
|
|
||||||
|
In Python, the import string is offered to each object in
|
||||||
|
``sys.meta_path`` before being offered to each ``sys.path_hook``. The
|
||||||
|
filesystem is typically the last finder tried.
|
||||||
|
|
||||||
|
To read more about **Meta Paths**, see :ref:`eli5-metapaths`
|
||||||
|
|
||||||
|
Is it different between Python 2 and Python 3?
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
Python 3 moves almost everything about this process into python's
|
||||||
|
library, leaving only a bare minimum of functionality inside the Python
|
||||||
|
executable to load this library and run it. When the Python developers
|
||||||
|
did that, they added a lot of functionality to make it easier to write
|
||||||
|
new import modules. The old way still works, but there are now *Module
|
||||||
|
Specifications*, which are metadata about a module, and the old
|
||||||
|
``path_hooks`` system is now just a ``meta_path`` handler added to the
|
||||||
|
new system as the last resort.
|
||||||
|
|
||||||
|
To read more about **Module Specifications**, see :ref:`eli5-specs`
|
||||||
|
|
||||||
|
Does the old system still matter?
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
Yes, for one reason: *iteration*. Iteration is the ability to take a
|
||||||
|
path where you believe Python modules can be found, and list through
|
||||||
|
them. This facility is useful for large frameworks where a user wants
|
||||||
|
to add new commands, or new objects, or new operations; Django uses this
|
||||||
|
facility a lot! The ``pkgutil`` library depends upon Finders being able
|
||||||
|
to iterate their contents.
|
|
@ -0,0 +1,37 @@
|
||||||
|
ELI5: Explain Like I'm Five!
|
||||||
|
============================
|
||||||
|
|
||||||
|
.. _eli5-finders:
|
||||||
|
|
||||||
|
Finders
|
||||||
|
=======
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
.. _eli5-loaders:
|
||||||
|
|
||||||
|
Loaders
|
||||||
|
=======
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
.. _eli5-pathhooks:
|
||||||
|
|
||||||
|
Path Hooks
|
||||||
|
==========
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
.. _eli5-metapaths:
|
||||||
|
|
||||||
|
Meta Paths
|
||||||
|
==========
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
.. _eli5-specs:
|
||||||
|
|
||||||
|
Module Specifications
|
||||||
|
=====================
|
||||||
|
|
||||||
|
TODO
|
|
@ -3,8 +3,8 @@
|
||||||
You can adapt this file completely to your liking, but it should at least
|
You can adapt this file completely to your liking, but it should at least
|
||||||
contain the root `toctree` directive.
|
contain the root `toctree` directive.
|
||||||
|
|
||||||
Welcome to py-polymorphic-loader's documentation!
|
Welcome to polyloader
|
||||||
======================================
|
=====================
|
||||||
|
|
||||||
Contents:
|
Contents:
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ Contents:
|
||||||
readme
|
readme
|
||||||
installation
|
installation
|
||||||
usage
|
usage
|
||||||
|
details
|
||||||
contributing
|
contributing
|
||||||
authors
|
authors
|
||||||
history
|
history
|
||||||
|
|
|
@ -8,11 +8,11 @@ Installation
|
||||||
Stable release
|
Stable release
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
To install py-polymorphic-loader, run this command in your terminal:
|
To install polyloader, run this command in your terminal:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ pip install py-polymorphic-loader
|
$ pip install polyloader
|
||||||
|
|
||||||
If you don't have `pip`_ installed, this `Python installation guide`_ can guide
|
If you don't have `pip`_ installed, this `Python installation guide`_ can guide
|
||||||
you through the process.
|
you through the process.
|
||||||
|
@ -24,19 +24,19 @@ you through the process.
|
||||||
From sources
|
From sources
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The sources for py-polymorphic-loader can be downloaded from the `Github repo`_.
|
The sources for polyloader can be downloaded from the `Github repo`_.
|
||||||
|
|
||||||
You can either clone the public repository:
|
You can either clone the public repository:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ git clone git://github.com/elfsternberg/py-polymorphic-loader
|
$ git clone git://github.com/elfsternberg/polyloader
|
||||||
|
|
||||||
Or download the `tarball`_:
|
Or download the `tarball`_:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ curl -OL https://github.com/elfsternberg/py-polymorphic-loader/tarball/master
|
$ curl -OL https://github.com/elfsternberg/polyloader/tarball/master
|
||||||
|
|
||||||
Once you have a copy of the source, you can install it with:
|
Once you have a copy of the source, you can install it with:
|
||||||
|
|
||||||
|
@ -45,5 +45,5 @@ Once you have a copy of the source, you can install it with:
|
||||||
$ python setup.py install
|
$ python setup.py install
|
||||||
|
|
||||||
|
|
||||||
.. _Github repo: https://github.com/elfsternberg/py-polymorphic-loader
|
.. _Github repo: https://github.com/elfsternberg/polyloader
|
||||||
.. _tarball: https://github.com/elfsternberg/py-polymorphic-loader/tarball/master
|
.. _tarball: https://github.com/elfsternberg/polyloader/tarball/master
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
.. include:: ../README.rst
|
.. include:: ../../README.rst
|
||||||
|
|
|
@ -2,6 +2,21 @@
|
||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
||||||
To use py-polymorphic-loader in a project::
|
Import polyloader in your python script's launcher or library, as well
|
||||||
|
as the syntax compiler(s) you plan to use. For example, if you have
|
||||||
|
`Mochi <https://github.com/i2y/mochi>`__ and `Hy
|
||||||
|
<http://docs.hylang.org/en/latest/>`__ installed, and you wanted to
|
||||||
|
write a Django app, edit manage.py and add the following lines at the
|
||||||
|
top:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from mochi.main import compile_file as mochi_compile
|
||||||
|
from hy.importer import ast_compile as hy_compile
|
||||||
|
import polyloader
|
||||||
|
polyloader.install(mochi_compile, ['.mochi'])
|
||||||
|
polyloader.install(hy_compile, ['.hy'])}
|
||||||
|
|
||||||
|
Now your views can be written in Hy and your models in Mochi, and
|
||||||
|
everything will just work.
|
||||||
|
|
||||||
import py-polymorphic-loader
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
<script type="text/javascript" src="underscore.js"></script>
|
<script type="text/javascript" src="underscore.js"></script>
|
||||||
<script type="text/javascript" src="doctools.js"></script>
|
<script type="text/javascript" src="doctools.js"></script>
|
||||||
<link rel="top" title="polyloader 0.1.0 documentation" href="index.html" />
|
<link rel="top" title="polyloader 0.1.0 documentation" href="index.html" />
|
||||||
<link rel="next" title="<no title>" href="contributing.html" />
|
<link rel="next" title="Details on Import and Polyloader" href="details.html" />
|
||||||
<link rel="prev" title="Installation" href="installation.html" />
|
<link rel="prev" title="Installation" href="installation.html" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
<a href="py-modindex.html" title="Python Module Index"
|
<a href="py-modindex.html" title="Python Module Index"
|
||||||
>modules</a> |</li>
|
>modules</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="contributing.html" title="<no title>"
|
<a href="details.html" title="Details on Import and Polyloader"
|
||||||
accesskey="N">next</a> |</li>
|
accesskey="N">next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="installation.html" title="Installation"
|
<a href="installation.html" title="Installation"
|
||||||
|
@ -54,10 +54,20 @@
|
||||||
|
|
||||||
<div class="section" id="usage">
|
<div class="section" id="usage">
|
||||||
<h1>Usage<a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h1>
|
<h1>Usage<a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h1>
|
||||||
<p>To use py-polymorphic-loader in a project:</p>
|
<p>Import polyloader in your python script’s launcher or library, as well
|
||||||
<div class="highlight-python"><div class="highlight"><pre>import py-polymorphic-loader
|
as the syntax compiler(s) you plan to use. For example, if you have
|
||||||
|
<a class="reference external" href="https://github.com/i2y/mochi">Mochi</a> and <a class="reference external" href="http://docs.hylang.org/en/latest/">Hy</a> installed, and you wanted to
|
||||||
|
write a Django app, edit manage.py and add the following lines at the
|
||||||
|
top:</p>
|
||||||
|
<div class="highlight-python"><div class="highlight"><pre>from mochi.main import compile_file as mochi_compile
|
||||||
|
from hy.importer import ast_compile as hy_compile
|
||||||
|
import polyloader
|
||||||
|
polyloader.install(mochi_compile, ['.mochi'])
|
||||||
|
polyloader.install(hy_compile, ['.hy'])}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
|
<p>Now your views can be written in Hy and your models in Mochi, and
|
||||||
|
everything will just work.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,8 +80,8 @@
|
||||||
<p class="topless"><a href="installation.html"
|
<p class="topless"><a href="installation.html"
|
||||||
title="previous chapter">Installation</a></p>
|
title="previous chapter">Installation</a></p>
|
||||||
<h4>Next topic</h4>
|
<h4>Next topic</h4>
|
||||||
<p class="topless"><a href="contributing.html"
|
<p class="topless"><a href="details.html"
|
||||||
title="next chapter"><no title></a></p>
|
title="next chapter">Details on Import and Polyloader</a></p>
|
||||||
<h3>This Page</h3>
|
<h3>This Page</h3>
|
||||||
<ul class="this-page-menu">
|
<ul class="this-page-menu">
|
||||||
<li><a href="_sources/usage.txt"
|
<li><a href="_sources/usage.txt"
|
||||||
|
@ -104,7 +114,7 @@
|
||||||
<a href="py-modindex.html" title="Python Module Index"
|
<a href="py-modindex.html" title="Python Module Index"
|
||||||
>modules</a> |</li>
|
>modules</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="contributing.html" title="<no title>"
|
<a href="details.html" title="Details on Import and Polyloader"
|
||||||
>next</a> |</li>
|
>next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="installation.html" title="Installation"
|
<a href="installation.html" title="Installation"
|
||||||
|
|
Loading…
Reference in New Issue