Browse Source

add a bunch of docs... also make a method static that can be..

main
John-Mark Gurney 4 years ago
parent
commit
162fbf5e79
1 changed files with 47 additions and 1 deletions
  1. +47
    -1
      casimport/__init__.py

+ 47
- 1
casimport/__init__.py View File

@@ -37,6 +37,18 @@ from importlib.machinery import ModuleSpec

@contextlib.contextmanager
def tempset(obj, key, value):
'''A context (with) manager for changing the value of an item in a
dictionary, and restoring it after the with block.

Example usage:
```
d = dict(a=5, b=10)
with tempset(d, 'a', 15):
print(repr(d['a'])
print(repr(d['a'])
```
'''

try:
oldvalue = obj[key]
obj[key] = value
@@ -45,16 +57,26 @@ def tempset(obj, key, value):
obj[key] = oldvalue

class FileDirCAS(object):
'''A file loader for CAS that operates on a directory. It looks
at files, caches their hash, and loads them upon request.'''

def __init__(self, path):
self._path = pathlib.Path(path)
self._hashes = {}

def refresh_dir(self):
'''Internal method to refresh the internal cache of
hashes.'''

for i in glob.glob(os.path.join(self._path, '*.py')):
_, hash = self.read_hash_file(i)
self._hashes[hash] = i

def read_hash_file(self, fname):
@staticmethod
def read_hash_file(fname):
'''Helper function that will read the file at fname, and
return the tuple of it's contents and it's hash.'''

with open(fname, 'rb') as fp:
data = fp.read()
hash = hashlib.sha256(data).hexdigest()
@@ -62,9 +84,15 @@ class FileDirCAS(object):
return data, hash

def is_package(self, hash):
'''Decode the provided hash, and decide if it's a package
or not.'''

return False

def exec_module(self, hash, module):
'''Give the hash and module, load the code associated
with the hash, and exec it in the module's context.'''

self.refresh_dir()

parts = hash.split('_', 2)
@@ -78,6 +106,10 @@ class FileDirCAS(object):
exec(data, module.__dict__)

class CASFinder(MetaPathFinder, Loader):
'''Overall class for using Content Addressable Storage to load
Python modules into your code. It contains code to dispatch to
the various loaders to attempt to load the hash.'''

def __init__(self):
self._loaders = []

@@ -93,12 +125,26 @@ class CASFinder(MetaPathFinder, Loader):
self.disconnect()

def disconnect(self):
'''Disconnect this Finder from being used to load modules.

As this claims an entire namespace, only the first loaded
one will work, and any others will be hidden until the
first one is disconnected.

This can be used w/ a with block to automatically
disconnect when no longer needed. This is mostly useful
for testing.'''

try:
sys.meta_path.remove(self)
except ValueError:
pass

def register(self, loader):
'''Register a loader w/ this finder. This will attempt
to load the hash passed to it. It is also (currently)
responsible for executing the code in the module.'''

self._loaders.append(loader)

# MetaPathFinder methods


Loading…
Cancel
Save