1
0
mirror of https://github.com/gsi-upm/senpy synced 2024-11-24 17:12:29 +00:00

Add an option to force the load of shelf plugins

Closes gsi-upm/senpy#34
This commit is contained in:
J. Fernando Sánchez 2017-05-17 16:25:13 +02:00
parent f76b777b9f
commit ea91e3e4a4
4 changed files with 47 additions and 5 deletions

View File

@ -183,7 +183,11 @@ Training a classifier can be time time consuming. To avoid running the training
def deactivate(self): def deactivate(self):
self.close() self.close()
You can speficy a 'shelf_file' in your .senpy file. By default the ShelfMixin creates a file based on the plugin name and stores it in that plugin's folder. You can specify a 'shelf_file' in your .senpy file. By default the ShelfMixin creates a file based on the plugin name and stores it in that plugin's folder.
Shelves may get corrupted if the plugin exists unexpectedly.
A corrupt shelf prevents the plugin from loading.
If you do not care about the pickle, you can force your plugin to remove the corrupted file and load anyway, set the 'force_shelf' to True in your .senpy file.
I want to implement my service as a plugin, How i can do it? I want to implement my service as a plugin, How i can do it?
???????????????????????????????????????????????????????????? ????????????????????????????????????????????????????????????

View File

@ -237,7 +237,10 @@ class BaseModel(SenpyMixin, dict):
self.__setitem__(self._get_key(key), value) self.__setitem__(self._get_key(key), value)
def __delattr__(self, key): def __delattr__(self, key):
self.__delitem__(self._get_key(key)) try:
object.__delattr__(self, key)
except AttributeError:
self.__delitem__(self._get_key(key))
def _plain_dict(self): def _plain_dict(self):
d = {k: v for (k, v) in self.items() if k[0] != "_"} d = {k: v for (k, v) in self.items() if k[0] != "_"}

View File

@ -98,8 +98,10 @@ class ShelfMixin(object):
if os.path.isfile(self.shelf_file): if os.path.isfile(self.shelf_file):
try: try:
self.__dict__['_sh'] = pickle.load(open(self.shelf_file, 'rb')) self.__dict__['_sh'] = pickle.load(open(self.shelf_file, 'rb'))
except EOFError: except (EOFError, pickle.UnpicklingError):
logger.warning('corrupted shelf file!') logger.warning('{} has a corrupted shelf file!'.format(self.id))
if not self.get('force_shelf', False):
raise
return self._sh return self._sh
@sh.deleter @sh.deleter

View File

@ -83,7 +83,40 @@ class PluginsTest(TestCase):
res2 = a.analyse(input=1) res2 = a.analyse(input=1)
assert res2.entries[0].nif__isString == 2 assert res2.entries[0].nif__isString == 2
def test_two(self): def test_corrupt_shelf(self):
''' Reusing the values of a previous shelf '''
emptyfile = os.path.join(self.shelf_dir, "emptyfile")
invalidfile = os.path.join(self.shelf_dir, "invalid_file")
with open(emptyfile, 'w+b'), open(invalidfile, 'w+b') as inf:
inf.write(b'ohno')
files = {emptyfile: ['empty file', EOFError],
invalidfile: ['invalid file', pickle.UnpicklingError]}
for fn in files:
with open(fn, 'rb') as f:
msg, error = files[fn]
a = ShelfDummyPlugin(info={
'name': 'shelve',
'version': 'test',
'shelf_file': f.name
})
assert os.path.isfile(a.shelf_file)
print('Shelf file: %s' % a.shelf_file)
with self.assertRaises(error):
# By default, raise an error
a.sh['a'] = 'fromA'
a.save()
del a._sh
assert os.path.isfile(a.shelf_file)
a.force_shelf = True
a.sh['a'] = 'fromA'
a.save()
b = pickle.load(f)
assert b['a'] == 'fromA'
def test_reuse_shelf(self):
''' Reusing the values of a previous shelf ''' ''' Reusing the values of a previous shelf '''
a = ShelfDummyPlugin(info={ a = ShelfDummyPlugin(info={
'name': 'shelve', 'name': 'shelve',