/usr/lib/python3/dist-packages/behave/importer.py is in python3-behave 1.2.5-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | # -*- coding: utf-8 -*-
"""
Importer module for lazy-loading/importing modules and objects.
REQUIRES: importlib (provided in Python2.7, Python3.2...)
"""
from behave._types import Unknown
import importlib
def parse_scoped_name(scoped_name):
"""
SCHEMA: my.module_name:MyClassName
EXAMPLE:
behave.formatter.plain:PlainFormatter
"""
scoped_name = scoped_name.strip()
if "::" in scoped_name:
# -- ALTERNATIVE: my.module_name::MyClassName
scoped_name = scoped_name.replace("::", ":")
module_name, object_name = scoped_name.rsplit(":", 1)
return module_name, object_name
def load_module(module_name):
return importlib.import_module(module_name)
class LazyObject(object):
"""
Provides a placeholder for an object that should be loaded lazily.
"""
def __init__(self, module_name, object_name=None):
if ":" in module_name and not object_name:
module_name, object_name = parse_scoped_name(module_name)
assert ":" not in module_name
self.module_name = module_name
self.object_name = object_name
self.resolved_object = None
def __get__(self, obj=None, type=None):
"""
Implement descriptor protocol,
useful if this class is used as attribute.
:return: Real object (lazy-loaded if necessary).
:raise ImportError: If module or object cannot be imported.
"""
__pychecker__ = "unusednames=obj,type"
resolved_object = None
if not self.resolved_object:
# -- SETUP-ONCE: Lazy load the real object.
module = load_module(self.module_name)
resolved_object = getattr(module, self.object_name, Unknown)
if resolved_object is Unknown:
msg = "%s: %s is Unknown" % (self.module_name, self.object_name)
raise ImportError(msg)
self.resolved_object = resolved_object
return resolved_object
def __set__(self, obj, value):
"""Implement descriptor protocol."""
__pychecker__ = "unusednames=obj"
self.resolved_object = value
def get(self):
return self.__get__()
class LazyDict(dict):
"""
Provides a dict that supports lazy loading of objects.
A LazyObject is provided as placeholder for a value that should be
loaded lazily.
"""
def __getitem__(self, key):
"""
Provides access to stored dict values.
Implements lazy loading of item value (if necessary).
When lazy object is loaded, its value with the dict is replaced
with the real value.
:param key: Key to access the value of an item in the dict.
:return: value
:raises: KeyError if item is not found
:raises: ImportError for a LazyObject that cannot be imported.
"""
value = dict.__getitem__(self, key)
if isinstance(value, LazyObject):
# -- LAZY-LOADING MECHANISM: Load object and replace with lazy one.
value = value.__get__()
self[key] = value
return value
def load_all(self, strict=False):
for key in list(self.keys()):
try:
self.__getitem__(key)
except ImportError:
if strict:
raise
|