/usr/lib/python3/dist-packages/invoke/loader.py is in python3-invoke 0.11.1+dfsg1-1.
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 | import os
import sys
import imp
from .collection import Collection
from .exceptions import CollectionNotFound
from .util import debug
DEFAULT_COLLECTION_NAME = 'tasks'
class Loader(object):
"""
Abstract class defining how to load a session's base `.Collection`.
"""
def find(self, name):
"""
Implementation-specific finder method seeking collection ``name``.
Must return a 4-tuple valid for use by `imp.load_module`, which is
typically a name string followed by the contents of the 3-tuple
returned by `imp.find_module` (``file``, ``pathname``,
``description``.)
For a sample implementation, see `.FilesystemLoader`.
"""
raise NotImplementedError
def load(self, name=DEFAULT_COLLECTION_NAME):
"""
Load and return collection identified by ``name``.
This method requires a working implementation of `.find` in order to
function.
In addition to importing the named module, it will add the module's
parent directory to the front of `sys.path` to provide normal Python
import behavior (i.e. so the loaded module may load local-to-it modules
or packages.)
"""
# Find the named tasks module, depending on implementation.
# Will raise an exception if not found.
fd, path, desc = self.find(name)
try:
# Ensure containing directory is on sys.path in case the module
# being imported is trying to load local-to-it names.
parent = os.path.dirname(path)
sys.path.insert(0, parent)
# Actual import
module = imp.load_module(name, fd, path, desc)
# Make a collection from it, and done
return Collection.from_module(module, loaded_from=parent)
finally:
# Ensure we clean up the opened file object returned by find(), if
# there was one (eg found packages, vs modules, don't open any
# file.)
if fd:
fd.close()
class FilesystemLoader(Loader):
"""
Loads Python files from the filesystem (e.g. ``tasks.py``.)
Searches recursively towards filesystem root from a given start point.
"""
def __init__(self, start=None):
self._start = start
@property
def start(self):
# Lazily determine default CWD
return self._start or os.getcwd()
def find(self, name):
# Accumulate all parent directories
start = self.start
debug("FilesystemLoader find starting at {0!r}".format(start))
parents = [os.path.abspath(start)]
parents.append(os.path.dirname(parents[-1]))
while parents[-1] != parents[-2]:
parents.append(os.path.dirname(parents[-1]))
# Make sure we haven't got duplicates on the end
if parents[-1] == parents[-2]:
parents = parents[:-1]
# Use find_module with our list of parents. ImportError from
# find_module means "couldn't find" not "found and couldn't import" so
# we turn it into a more obvious exception class.
try:
tup = imp.find_module(name, parents)
debug("Found module: {0!r}".format(tup[1]))
return tup
except ImportError:
raise CollectionNotFound(name=name, start=start)
|