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.
|
Python AST and Python VM, languages such as Hy, Doge, and Mochi.
|
||||||
|
|
||||||
Problem Statement
|
Problem Statement
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
The Python module loader system is hard-coded to prevent the discovery
|
The Python module loader system is hard-coded to prevent the discovery
|
||||||
of heterogenous source code packages. From Python 2.6 through the
|
of heterogenous source code packages. From Python 2.6 through the
|
||||||
current (as of this writing) Python 3.5, the import mechanism allowed
|
current (as of this writing) Python 3.5, the import mechanism allows for
|
||||||
for the creation of file finders and importers that would transform
|
the creation of file finders and importers that would transform Python's
|
||||||
Python's import syntax into a *path,* assert whether or not that path
|
import syntax into a *path,* assert whether or not that path could be
|
||||||
could be made to correspond to a *syntax object*, and then attempt to
|
made to correspond to a *syntax object*, and then attempt to *load* that
|
||||||
*load* that syntax object as a Python module. Python *packages*,
|
syntax object as a Python module. Python *packages*, however, are
|
||||||
however, are assumed to be uniformly made up of Python syntax objects,
|
assumed to be uniformly made up of Python syntax objects, be they
|
||||||
be they **.py** source files, **.pyc/.pyo** bytecode, or **.so/.dll**
|
**.py** source files, **.pyc/.pyo** bytecode, or **.so/.dll** files with
|
||||||
files with an exposed Python-to-C API. In Python 2 these suffixes are
|
an exposed Python-to-C API. In Python 2 these suffixes are hard-coded
|
||||||
hard-coded into the source in the **imp** builtin module; in Python 3
|
into the source in the **imp** builtin module; in Python 3 these
|
||||||
these suffixes are constants defined in a private section of
|
suffixes are constants defined in a private section of **importlib**; in
|
||||||
**importlib**; in either case, they are unavailable for modification.
|
either case, they are unavailable for modification. This lack of access
|
||||||
This lack of access to the extensions list prevents the *discovery* of
|
to the extensions list prevents the *discovery* of heterogenous source
|
||||||
heterogenous source code packages.
|
code packages.
|
||||||
|
|
||||||
The discovery mechanism is outlined in Python's pkgutil module; features
|
The discovery mechanism is outlined in Python's **pkgutil** module;
|
||||||
such as **pkgutil.iter_modules** do not work with heterogenous source
|
features such as **pkgutil.iter_modules** do not work with heterogenous
|
||||||
code, which in turn means that one cannot write, for one important
|
source code, which in turn means that one cannot write, for one
|
||||||
example, Django management commands in an alternative syntax.
|
important example, Django management commands in an alternative syntax.
|
||||||
|
|
||||||
**polyloader** is a python module that intercepts calls to the default
|
**polyloader** is a python module that intercepts calls to the default
|
||||||
finder, loader, and package module iterator, and if the path resolves to
|
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'
|
__email__ = 'elf.sternberg@gmail.com'
|
||||||
__version__ = '0.1.0'
|
__version__ = '0.1.0'
|
||||||
|
|
||||||
if sys.version[0:2] == (2, 7):
|
if sys.version_info[0:2] >= (2, 6):
|
||||||
from ._python27 import install
|
from ._python2 import install
|
||||||
|
|
||||||
if sys.version[0] >= 3:
|
if sys.version_info[0] >= 3:
|
||||||
from ._python3 import install
|
from ._python3 import install
|
||||||
|
|
||||||
__all__ = ['install']
|
__all__ = ['install']
|
||||||
|
|
|
@ -64,34 +64,41 @@ class PolyLoader(pkgutil.ImpLoader):
|
||||||
# the iter_modules; or we provide our own finder and ensure it gets
|
# the iter_modules; or we provide our own finder and ensure it gets
|
||||||
# found before the native one.
|
# found before the native one.
|
||||||
|
|
||||||
We actually want to have multiple
|
# Why the heck python 2.6 insists on calling finders "importers" is
|
||||||
# SourceFileFinders, each of which either recognizes the file to be
|
# beyond me. At least in calls loaders "loaders".
|
||||||
|
|
||||||
class PolyFinder(object):
|
class PolyFinder(object):
|
||||||
def __init__(self, path = None):
|
def __init__(self, path = None):
|
||||||
self.path = path
|
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"]
|
fls = ["%s/__init__.%s", "%s.%s"]
|
||||||
dirpath = "/".join(fullname.split("."))
|
for fp in fls:
|
||||||
|
for (compiler, suffix) in PolyLoader._loader_handlers:
|
||||||
for pth in sys.path:
|
composed_path = fp % ("%s/%s" % (pth, dirpath), suffix)
|
||||||
pth = os.path.abspath(pth)
|
if os.path.exists(composed_path):
|
||||||
for fp in fls:
|
return PolyLoader(composed_path)
|
||||||
for (compiler, suffix) in PolyLoader._loader_handlers:
|
try:
|
||||||
composed_path = fp % ("%s/%s" % (pth, dirpath), suffix)
|
file, filename, etc = imp.find_module(subname, path)
|
||||||
if os.path.exists(composed_path):
|
except ImportError:
|
||||||
return composed_path
|
return None
|
||||||
|
return ImpLoader(fullname, file, filename, etc)
|
||||||
|
|
||||||
def find_module(self, fullname, path=None):
|
def find_module(self, fullname, path=None):
|
||||||
path = self.find_on_path(fullname)
|
path = self._pl_find_on_path(fullname)
|
||||||
if path:
|
if path:
|
||||||
return PolyLoader(path)
|
return PolyLoader(path)
|
||||||
|
return None
|
||||||
|
|
||||||
def _install(compiler, suffixes):
|
def _install(compiler, suffixes):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sys.meta_path.insert(0, MetaImporter())
|
sys.meta_path.insert(0, MetaImporter())
|
||||||
iter_importer_modules.register(MetaImporter, meta_iterate_modules)
|
iter_importer_modules.register(MetaImporter, meta_iterate_modules)
|
Loading…
Reference in New Issue