Browse Source

create the default cache direcotry, and initalize it.. also,

currently always reread the cache directory, but this needs to be
fixed..
main
John-Mark Gurney 5 years ago
parent
commit
5a27da467b
1 changed files with 78 additions and 3 deletions
  1. +78
    -3
      casimport/__init__.py

+ 78
- 3
casimport/__init__.py View File

@@ -22,20 +22,35 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE. # SUCH DAMAGE.


import contextlib
import glob import glob
import hashlib import hashlib
import importlib
import os.path import os.path
import pathlib
import shutil
import sys import sys
import tempfile


from importlib.abc import MetaPathFinder, Loader from importlib.abc import MetaPathFinder, Loader
from importlib.machinery import ModuleSpec from importlib.machinery import ModuleSpec


@contextlib.contextmanager
def tempset(obj, key, value):
try:
oldvalue = obj[key]
obj[key] = value
yield
finally:
obj[key] = oldvalue

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


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


@@ -50,6 +65,8 @@ class FileDirCAS(object):
return False return False


def exec_module(self, hash, module): def exec_module(self, hash, module):
self.refresh_dir()

parts = hash.split('_', 2) parts = hash.split('_', 2)
fname = self._hashes[parts[2]] fname = self._hashes[parts[2]]


@@ -93,6 +110,8 @@ class CASFinder(MetaPathFinder, Loader):
for l in self._loaders: for l in self._loaders:
ispkg = l.is_package(parts[1]) ispkg = l.is_package(parts[1])
break break
else:
return None


ms = ModuleSpec(fullname, self, is_package=True, loader_state=(parts[1], l)) ms = ModuleSpec(fullname, self, is_package=True, loader_state=(parts[1], l))


@@ -109,25 +128,56 @@ class CASFinder(MetaPathFinder, Loader):
hash, load = module.__spec__.loader_state hash, load = module.__spec__.loader_state
load.exec_module(hash, module) load.exec_module(hash, module)


def defaultinit(casf):
cachedir = pathlib.Path.home() / '.casimport_cache'
cachedir.mkdir(exist_ok=True)

casf.register(FileDirCAS(cachedir))

# The global version # The global version
_casfinder = CASFinder() _casfinder = CASFinder()
defaultinit(_casfinder)


import unittest import unittest


class Test(unittest.TestCase): class Test(unittest.TestCase):
def setUp(self): def setUp(self):
# clear out the default casfinder if there is one
self.old_meta_path = sys.meta_path self.old_meta_path = sys.meta_path
sys.meta_path = [ x for x in sys.meta_path if not isinstance(x, CASFinder) ] sys.meta_path = [ x for x in sys.meta_path if not isinstance(x, CASFinder) ]


# setup temporary directory
d = pathlib.Path(os.path.realpath(tempfile.mkdtemp()))
self.basetempdir = d
self.tempdir = d / 'subdir'
self.tempdir.mkdir()

self.fixtures = pathlib.Path(__file__).parent.parent / 'fixtures'

def tearDown(self): def tearDown(self):
# restore environment
sys.meta_path = self.old_meta_path sys.meta_path = self.old_meta_path


importlib.invalidate_caches()

# clean up sys.modules
[ sys.modules.pop(x) for x in list(sys.modules.keys()) if
x == 'cas' or x.startswith('cas.') ]

shutil.rmtree(self.basetempdir)
self.tempdir = None

def test_filedircas_limit_refresh(self):
# XXX - only refresh when the dir has changed, and each
# file has changed
pass

def test_casimport(self): def test_casimport(self):
# That a CASFinder # That a CASFinder
f = CASFinder() f = CASFinder()


# when registering the fixtures directory # when registering the fixtures directory
f.register(FileDirCAS(os.path.join(os.path.dirname(__file__), '..', 'fixtures')))
f.register(FileDirCAS(self.fixtures))


# can import the function # can import the function
from cas.v1_f_330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3 import hello from cas.v1_f_330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3 import hello
@@ -145,6 +195,31 @@ class Test(unittest.TestCase):
# and when disconnected as second time, nothing happens # and when disconnected as second time, nothing happens
f.disconnect() f.disconnect()


def test_defaultinit(self):
temphome = self.tempdir / 'home'
temphome.mkdir()
cachedir = temphome / '.casimport_cache'

with tempset(os.environ, 'HOME', str(temphome)):
with CASFinder() as f:
# Setup the defaults
defaultinit(f)

# that the cache got created
self.assertTrue(cachedir.is_dir())

# and that when hello.py is copied to the cache
shutil.copy(self.fixtures / 'hello.py', cachedir)

# it can be imported
from cas.v1_f_330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3 import hello

with CASFinder() as f:
defaultinit(f)

# and that a new CASFinder can still find it
from cas.v1_f_330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3 import hello

def test_multiplecas(self): def test_multiplecas(self):
# that once we have one # that once we have one
with CASFinder() as f: with CASFinder() as f:


Loading…
Cancel
Save