include - Dynamic Module Importer¶
include package¶
-
include.
disable
(identifier, children_only=False)¶ Disable an include type
Parameters: - identifier – module or name of the include type
- children_only – disable the include type only for child processes, not the current process
The
identifier
can be specified in multiple ways to disable an include type. Seedisable()
for details.
-
include.
enable
(identifier, exclude_children=False)¶ Enable a previously disabled include type
Parameters: - identifier – module or name of the include type
- exclude_children – disable the include type only for child processes, not the current process
The
identifier
can be specified in multiple ways to disable an include type. Seedisable()
for details.
-
include.
path
(file_path)¶ Include module code from a file identified by its path
Parameters: file_path (str) – path to a file containing module code Returns: the imported module Return type: module Comparable to
execfile
, but respects the rules and constraints of modules. If invoked again with the samefile_path
, the same module is returned.import include my_config = include.path('/etc/sysconfig/app_conf.py')
-
include.
source
(source_code)¶ Include module code directly from a string
Parameters: source_code (str) – source code of the module Returns: the imported module Return type: module Comparable to
exec
in a separateglobals
namespace, but respects the rules and constraints of modules. If invoked again with the samesource_code
, the same module is returned.>>> import include >>> my_module = include.source( >>> """ ... def foo(): ... return {constant} ... """.format(constant=3)) >>> my_module.foo() == 3 True
Subpackages¶
include.base package¶
Base module for import hook modules
Each include type is backed by (at least) one import hook module.
This must implement the install()
to explicitly enable the include type.
Importing the import hook module should be free of side-effects, allowing modification before installation.
Notably, imported modules should live in a separate packagae than the import hook module.
This separate package, preferably include.mount
, is free to bootstrap the import hook module as needed.
-
include.base.
IMPORT_PATH
= 'include.mount.base'¶ package name in which to include imported modules
-
include.base.
install
()¶ Enable this type of include
Submodules¶
include.base.import_hook module¶
-
class
include.base.import_hook.
BaseIncludeLoader
(module_prefix)¶ Bases:
object
Import hook to load Python modules from an arbitrary location
Parameters: module_prefix (str) – prefix for modules to import Base class for import hooks to non-standard code sources. Implements the general structure for encoded sources: a module source translates to an artificial module path of the form
<module_prefix>.<encoded_name>
. Themodule_prefix
identifies the code source type (and import hook) while theencoded_name
contains all required information to retrieve the code.For example, a
module_prefix
ofinclude.type.files
could identify a source file type, and anencoded_name
ofSLASHtmpSLASHfooDOTpy
point to the path/tmp/foo.py
. The resulting module would appear asinclude.type.files.SLASHtmpSLASHfooDOTpy
.Note that
module_prefix
must point to a valid package, not a module. It will be actually imported by the regular import machinery, and can be used to bootstrap hooks.The
encoded_name
is a free form field. The base class provides means to escape invalid and reserved symbols (/
and.
), but subclasses are free to use them if it is suitable for them. Hooks should useencoded_name
to store a URI (or similar) to retrieve source code. As per Python rules, including a dot (.
) in theencoded_name
requires the hook to import each portion separately.-
find_module
(fullname, path=None)¶ Find the appropriate loader for module
name
Parameters:
-
load_module
(name)¶ Load and return a module
Always returns the corresponding module. If the module is already loaded, the existing module is returned.
-
module2uri
(module_name)¶ Convert an encoded module name to an unencoded source uri
-
module_prefix
¶
-
uri2module
(uri)¶ Convert an unencoded source uri to an encoded module name
-
include.encoded package¶
Load modules from encoded source code
This include type encodes raw source code as a module name.
The resulting module is self-contained:
it can be stored, loaded and transferred without the original source code.
Only the dependencies of the module (including include
) must be satisfied.
-
include.encoded.
install
()¶
Submodules¶
include.encoded.import_hook module¶
-
class
include.encoded.import_hook.
EncodedModuleLoader
(module_prefix)¶ Bases:
include.base.import_hook.BaseIncludeLoader
Load python modules from their encoded content
This import hook allows storing and using module content as a compressed data blob.
-
load_module
(name)¶ Load and return a module
Always returns the corresponding module. If the module is already loaded, the existing module is returned.
-
module2uri
(module_name)¶ Convert an encoded module name to an unencoded source uri
-
uri2module
(uri)¶ Convert an unencoded source uri to an encoded module name
-
include.files package¶
Load modules from files
-
include.files.
install
()¶
Submodules¶
include.files.import_hook module¶
-
class
include.files.import_hook.
FilePathLoader
(module_prefix)¶ Bases:
include.base.import_hook.BaseIncludeLoader
Load python file from their path
This import hook allows using encoded paths as module names to load modules directly from their file.
-
load_module
(name)¶ Load and return a module
Always returns the corresponding module. If the module is already loaded, the existing module is returned.
-
include.mount package¶
-
class
include.mount.
MountLoader
(mount_prefix, module_prefix)¶ Bases:
object
-
find_module
(name, path=None)¶
-
is_module
(name)¶ Test that name is a module name
-
is_mount
(name)¶ Test that name is a mount name
-
load_module
(name)¶ Load and return a module
-
mount2name
(mount)¶ Convert a mount name to a module name
-
name2mount
(name)¶ Convert a module name to a mount name
-
Submodules¶
include.inhibit module¶
-
include.inhibit.
DISABLED_TYPES
= <include.inhibit.DisabledIncludeTypes for '', children ''>¶ Default interface to disabled types, see
DisabledIncludeTypes
-
exception
include.inhibit.
DisabledIncludeError
¶ Bases:
exceptions.ImportError
An import operation failed due to its include type being disabled
-
class
include.inhibit.
DisabledIncludeTypes
¶ Bases:
object
Interface for disabling include types
Meta-container to control disabled include types. The methods
disable()
andenable()
allow to control which include types can be used.Disabled types cannot be used to import code, be it explicitly or implicitly via bootstrapping. Once a type is disabled, attempts to import code with it raise
DisabledIncludeError
.This is provided as a two-level filter: each type can be disabled either for both the current and any child process, or only for child processes. It is not possible to enable an include type for child processes but not the current process. Note that child processes inherit disabled types only on startup.
Note: This is a singleton, as it controls interpreter state. -
disable
(identifier, children_only=False)¶ Disable an include type
Parameters: - identifier – module or name of the include type
- children_only – disable the include type only for child processes, not the current process
The
identifier
can be specified in multiple ways to disable an include type:- module (
include.files
orinclude.mount.files
) - The base module implementing the include type.
These modules have a
module.IMPORT_PATH
attribute. - implementation path (
"include.files"
) - Import path of the module implementing the include type.
- mount path (
"include.mount.files"
) - Mount path of the module implementing the include type.
- short path (
"files"
) - Relative path of the module implementing the include type.
-
enable
(identifier, exclude_children=False)¶ Enable a previously disabled include type
Parameters: - identifier – module or name of the include type
- exclude_children – disable the include type only for child processes, not the current process
The
identifier
can be specified in multiple ways to disable an include type. Seedisable()
for details.
-
environment_key
= 'PY_INCLUDE_DISABLE'¶ Key of the environment storing include types disabled for child processes
-
-
class
include.inhibit.
DisabledTypeLoader
(module_prefix)¶ Bases:
include.base.import_hook.BaseIncludeLoader
-
load_module
(name)¶ Load and return a module
If the module is already loaded, the existing module is returned. Otherwise, raises
DisabledIncludeError
.
-
uri2module
(uri)¶ Convert an unencoded source uri to an encoded module name
Always raises
DisabledIncludeError
.
-
Automatic Bootstrapping¶
Modules imported by include
have an automatic bootstrapping mechanism:
when imported in another process, the required import hook is automatically loaded.
This allows un/pickling and transferring objects, without explicitly preparing include
in the receiver.
The only restriction is that include
must be importable before any module code is run.
Disabling Bootstrap Hooks¶
At times, bootstrapping arbitrary include types is not desired. For example, a public web service may desire to run existing, local configuration code files during startup only. As a simple remedy, individual include types can be disabled.
To disable include types, both a code and environment interface are available:
- Environment Variable
PY_INCLUDE_DISABLE
- A list of include types to disable.
Types are indicated by their module name, such as
files
for theinclude.files
type. Multiple types may be delimited by commas, with optional whitespace. For example, the listfiles, encoded
disables imports from files and encoded source. - Code Interface
include.disable()
andinclude.enable()
- Functions to disable or enable individual include types.
Types may be indicated by a variety of identifiers.
See
disable()
for details.
Bootstrapping Mechanism¶
Each include
corresponds to an include type implementation and namespace.
The former provides the actual import machinery, such as hooks and name translation.
The later is a namespace module, into which all modules imported by include
are inserted.
For each include type, a separate namespace is used. The namespace itself ensures that its include type is installed. Thus, re-importing a module in a separate process first loads its namespace and thus its import machinery.
For example, a file based import is implemented in include.files
, and the default namespace is include.mount
.
When importing a file foo
, it is inserted as include.mount.files.foo
.
Re-importing include.mount.files.foo
first imports include.mount.files
, which in turn installs include.files
.
include¶
The include
library is built to use code from arbitrary sources in your application.
In contrast to eval
, exec
and other code execution, include
creates fully featured modules.
This makes code viable for pickling, multiprocessing, IPC and more.
Using include
is straight forward - you only need the top level functions of the module:
import include
my_config = include.path('/etc/sysconfig/app_conf.py')
All ugly bits are handled by include
- once a module is imported, it works as normal.
Even in other processes, the import machinery is bootstrapped without manual intervention.
For all supported import methods, check out the public inteface of the include
module.