Implement InspectLoader for FrozenImporter.
This commit is contained in:
parent
2b9fd47da7
commit
8d11013169
|
@ -284,7 +284,8 @@ find and load modules.
|
||||||
.. class:: FrozenImporter
|
.. class:: FrozenImporter
|
||||||
|
|
||||||
An :term:`importer` for frozen modules. This class implements the
|
An :term:`importer` for frozen modules. This class implements the
|
||||||
:class:`importlib.abc.Finder` and :class:`importlib.abc.Loader` ABCs.
|
:class:`importlib.abc.Finder` and :class:`importlib.abc.InspectLoader`
|
||||||
|
ABCs.
|
||||||
|
|
||||||
Only class methods are defined by this class to alleviate the need for
|
Only class methods are defined by this class to alleviate the need for
|
||||||
instantiation.
|
instantiation.
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
to do
|
to do
|
||||||
/////
|
/////
|
||||||
|
|
||||||
* Implement InspectLoader for FrozenImporter.
|
|
||||||
|
|
||||||
+ Expose function to see if a frozen module is a package.
|
|
||||||
|
|
||||||
* Make sure that there is documentation *somewhere* fully explaining the
|
* Make sure that there is documentation *somewhere* fully explaining the
|
||||||
semantics of import that can be referenced from the package's documentation
|
semantics of import that can be referenced from the package's documentation
|
||||||
(even if it is in the package documentation itself, although it might be best
|
(even if it is in the package documentation itself, although it might be best
|
||||||
|
|
|
@ -183,6 +183,16 @@ def _requires_builtin(fxn):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def _requires_frozen(fxn):
|
||||||
|
"""Decorator to verify the named module is frozen."""
|
||||||
|
def wrapper(self, fullname):
|
||||||
|
if not imp.is_frozen(fullname):
|
||||||
|
raise ImportError("{0} is not a frozen module".format(fullname))
|
||||||
|
return fxn(self, fullname)
|
||||||
|
_wrap(wrapper, fxn)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def _suffix_list(suffix_type):
|
def _suffix_list(suffix_type):
|
||||||
"""Return a list of file suffixes based on the imp file type."""
|
"""Return a list of file suffixes based on the imp file type."""
|
||||||
return [suffix[0] for suffix in imp.get_suffixes()
|
return [suffix[0] for suffix in imp.get_suffixes()
|
||||||
|
@ -261,10 +271,9 @@ class FrozenImporter:
|
||||||
@classmethod
|
@classmethod
|
||||||
@set_package
|
@set_package
|
||||||
@set_loader
|
@set_loader
|
||||||
|
@_requires_frozen
|
||||||
def load_module(cls, fullname):
|
def load_module(cls, fullname):
|
||||||
"""Load a frozen module."""
|
"""Load a frozen module."""
|
||||||
if cls.find_module(fullname) is None:
|
|
||||||
raise ImportError("{0} is not a frozen module".format(fullname))
|
|
||||||
is_reload = fullname in sys.modules
|
is_reload = fullname in sys.modules
|
||||||
try:
|
try:
|
||||||
return imp.init_frozen(fullname)
|
return imp.init_frozen(fullname)
|
||||||
|
@ -273,6 +282,24 @@ class FrozenImporter:
|
||||||
del sys.modules[fullname]
|
del sys.modules[fullname]
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@_requires_frozen
|
||||||
|
def get_code(cls, fullname):
|
||||||
|
"""Return the code object for the frozen module."""
|
||||||
|
return imp.get_frozen_object(fullname)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@_requires_frozen
|
||||||
|
def get_source(cls, fullname):
|
||||||
|
"""Return None as frozen modules do not have source code."""
|
||||||
|
return None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@_requires_frozen
|
||||||
|
def is_package(cls, fullname):
|
||||||
|
"""Return if the frozen module is a package."""
|
||||||
|
return imp.is_frozen_package(fullname)
|
||||||
|
|
||||||
|
|
||||||
class PyLoader:
|
class PyLoader:
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@ class Loader(metaclass=abc.ABCMeta):
|
||||||
"""Abstract method which when implemented should load a module."""
|
"""Abstract method which when implemented should load a module."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
Loader.register(machinery.FrozenImporter)
|
|
||||||
|
|
||||||
|
|
||||||
class Finder(metaclass=abc.ABCMeta):
|
class Finder(metaclass=abc.ABCMeta):
|
||||||
|
|
||||||
|
@ -75,6 +73,7 @@ class InspectLoader(Loader):
|
||||||
return NotImplementedError
|
return NotImplementedError
|
||||||
|
|
||||||
InspectLoader.register(machinery.BuiltinImporter)
|
InspectLoader.register(machinery.BuiltinImporter)
|
||||||
|
InspectLoader.register(machinery.FrozenImporter)
|
||||||
|
|
||||||
|
|
||||||
class PyLoader(_bootstrap.PyLoader, InspectLoader):
|
class PyLoader(_bootstrap.PyLoader, InspectLoader):
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
from importlib import machinery
|
from importlib import machinery
|
||||||
|
import imp
|
||||||
|
import unittest
|
||||||
from .. import abc
|
from .. import abc
|
||||||
from .. import util
|
from .. import util
|
||||||
|
|
||||||
|
@ -53,9 +55,41 @@ class LoaderTests(abc.LoaderTests):
|
||||||
'_not_real')
|
'_not_real')
|
||||||
|
|
||||||
|
|
||||||
|
class InspectLoaderTests(unittest.TestCase):
|
||||||
|
|
||||||
|
"""Tests for the InspectLoader methods for FrozenImporter."""
|
||||||
|
|
||||||
|
def test_get_code(self):
|
||||||
|
# Make sure that the code object is good.
|
||||||
|
name = '__hello__'
|
||||||
|
code = machinery.FrozenImporter.get_code(name)
|
||||||
|
mod = imp.new_module(name)
|
||||||
|
exec(code, mod.__dict__)
|
||||||
|
self.assert_(hasattr(mod, 'initialized'))
|
||||||
|
|
||||||
|
def test_get_source(self):
|
||||||
|
# Should always return None.
|
||||||
|
result = machinery.FrozenImporter.get_source('__hello__')
|
||||||
|
self.assert_(result is None)
|
||||||
|
|
||||||
|
def test_is_package(self):
|
||||||
|
# Should be able to tell what is a package.
|
||||||
|
test_for = (('__hello__', False), ('__phello__', True),
|
||||||
|
('__phello__.spam', False))
|
||||||
|
for name, is_package in test_for:
|
||||||
|
result = machinery.FrozenImporter.is_package(name)
|
||||||
|
self.assert_(bool(result) == is_package)
|
||||||
|
|
||||||
|
def test_failure(self):
|
||||||
|
# Raise ImportError for modules that are not frozen.
|
||||||
|
for meth_name in ('get_code', 'get_source', 'is_package'):
|
||||||
|
method = getattr(machinery.FrozenImporter, meth_name)
|
||||||
|
self.assertRaises(ImportError, method, 'importlib')
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
from test.support import run_unittest
|
from test.support import run_unittest
|
||||||
run_unittest(LoaderTests)
|
run_unittest(LoaderTests, InspectLoaderTests)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -1951,6 +1951,28 @@ get_frozen_object(char *name)
|
||||||
return PyMarshal_ReadObjectFromString((char *)p->code, size);
|
return PyMarshal_ReadObjectFromString((char *)p->code, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
is_frozen_package(char *name)
|
||||||
|
{
|
||||||
|
struct _frozen *p = find_frozen(name);
|
||||||
|
int size;
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
PyErr_Format(PyExc_ImportError,
|
||||||
|
"No such frozen object named %.200s",
|
||||||
|
name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = p->size;
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
Py_RETURN_TRUE;
|
||||||
|
else
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Initialize a frozen module.
|
/* Initialize a frozen module.
|
||||||
Return 1 for success, 0 if the module is not found, and -1 with
|
Return 1 for success, 0 if the module is not found, and -1 with
|
||||||
an exception set if the initialization failed.
|
an exception set if the initialization failed.
|
||||||
|
@ -2958,6 +2980,16 @@ imp_get_frozen_object(PyObject *self, PyObject *args)
|
||||||
return get_frozen_object(name);
|
return get_frozen_object(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
imp_is_frozen_package(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s:is_frozen_package", &name))
|
||||||
|
return NULL;
|
||||||
|
return is_frozen_package(name);
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
imp_is_builtin(PyObject *self, PyObject *args)
|
imp_is_builtin(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
@ -3191,6 +3223,7 @@ static PyMethodDef imp_methods[] = {
|
||||||
{"reload", imp_reload, METH_O, doc_reload},
|
{"reload", imp_reload, METH_O, doc_reload},
|
||||||
/* The rest are obsolete */
|
/* The rest are obsolete */
|
||||||
{"get_frozen_object", imp_get_frozen_object, METH_VARARGS},
|
{"get_frozen_object", imp_get_frozen_object, METH_VARARGS},
|
||||||
|
{"is_frozen_package", imp_is_frozen_package, METH_VARARGS},
|
||||||
{"init_builtin", imp_init_builtin, METH_VARARGS},
|
{"init_builtin", imp_init_builtin, METH_VARARGS},
|
||||||
{"init_frozen", imp_init_frozen, METH_VARARGS},
|
{"init_frozen", imp_init_frozen, METH_VARARGS},
|
||||||
{"is_builtin", imp_is_builtin, METH_VARARGS},
|
{"is_builtin", imp_is_builtin, METH_VARARGS},
|
||||||
|
|
Loading…
Reference in New Issue