Heading toward a final draft of the Py-2 instances.
This commit is contained in:
parent
df657c6b46
commit
e8dfad4721
36
README.rst
36
README.rst
|
@ -7,28 +7,28 @@ critical to the functioning of other programming languages that use the
|
|||
Python AST and Python VM, 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 allowed
|
||||
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.
|
||||
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.
|
||||
|
||||
The discovery mechanism is outlined in Python's pkgutil module; 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.
|
||||
The discovery mechanism is outlined in Python's **pkgutil** module;
|
||||
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
|
||||
finder, loader, and package module iterator, and if the path resolves to
|
||||
|
|
|
@ -5,10 +5,10 @@ __author__ = 'Kenneth M. "Elf" Sternberg'
|
|||
__email__ = 'elf.sternberg@gmail.com'
|
||||
__version__ = '0.1.0'
|
||||
|
||||
if sys.version[0:2] == (2, 7):
|
||||
from ._python27 import install
|
||||
if sys.version_info[0:2] >= (2, 6):
|
||||
from ._python2 import install
|
||||
|
||||
if sys.version[0] >= 3:
|
||||
if sys.version_info[0] >= 3:
|
||||
from ._python3 import install
|
||||
|
||||
__all__ = ['install']
|
||||
|
|
|
@ -64,34 +64,41 @@ class PolyLoader(pkgutil.ImpLoader):
|
|||
# the iter_modules; or we provide our own finder and ensure it gets
|
||||
# found before the native one.
|
||||
|
||||
We actually want to have multiple
|
||||
# SourceFileFinders, each of which either recognizes the file to be
|
||||
|
||||
# Why the heck python 2.6 insists on calling finders "importers" is
|
||||
# beyond me. At least in calls loaders "loaders".
|
||||
|
||||
class PolyFinder(object):
|
||||
def __init__(self, path = None):
|
||||
self.path = path
|
||||
|
||||
def find_on_path(self, fullname):
|
||||
def _pl_find_on_path(self, fullname, path=None):
|
||||
subname = fullname.split(".")[-1]
|
||||
if subname != fullname and self.path is None:
|
||||
return None
|
||||
# As in the original, we ignore the 'path' argument
|
||||
path = None
|
||||
if self.path is not None:
|
||||
path = [os.path.realpath(self.path)]
|
||||
|
||||
fls = ["%s/__init__.%s", "%s.%s"]
|
||||
dirpath = "/".join(fullname.split("."))
|
||||
|
||||
for pth in sys.path:
|
||||
pth = os.path.abspath(pth)
|
||||
for fp in fls:
|
||||
for (compiler, suffix) in PolyLoader._loader_handlers:
|
||||
composed_path = fp % ("%s/%s" % (pth, dirpath), suffix)
|
||||
if os.path.exists(composed_path):
|
||||
return composed_path
|
||||
|
||||
for fp in fls:
|
||||
for (compiler, suffix) in PolyLoader._loader_handlers:
|
||||
composed_path = fp % ("%s/%s" % (pth, dirpath), suffix)
|
||||
if os.path.exists(composed_path):
|
||||
return PolyLoader(composed_path)
|
||||
try:
|
||||
file, filename, etc = imp.find_module(subname, path)
|
||||
except ImportError:
|
||||
return None
|
||||
return ImpLoader(fullname, file, filename, etc)
|
||||
|
||||
def find_module(self, fullname, path=None):
|
||||
path = self.find_on_path(fullname)
|
||||
path = self._pl_find_on_path(fullname)
|
||||
if path:
|
||||
return PolyLoader(path)
|
||||
|
||||
return None
|
||||
|
||||
def _install(compiler, suffixes):
|
||||
|
||||
|
||||
|
||||
sys.meta_path.insert(0, MetaImporter())
|
||||
iter_importer_modules.register(MetaImporter, meta_iterate_modules)
|
Loading…
Reference in New Issue