Added support for blacklisted (eg, obsolete/retired) type values.

Updated unittest to verify changes. No effect on existing code.
Basic pieces are ready for fixing #1680, but now awaiting a translation
strategy and code for reading a database with blacklisted values.
At that point #1680 fix will simply require adding a line like
  _BLACKLIST=[CAUSEDEATH]
to eventtype.py.


svn: r10405
This commit is contained in:
James G Sack 2008-03-27 07:24:06 +00:00
parent bca1d41204
commit e21d552013
2 changed files with 51 additions and 11 deletions

View File

@ -31,12 +31,17 @@ Base type for all gramps types.
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from gettext import gettext as _ from gettext import gettext as _
def _init_map(data, key_col, data_col): def _init_map(data, key_col, data_col, blacklist=None):
""" """
Initialize the map, building a new map from the specified columns. Initialize the map, building a new map from the specified columns.
""" """
new_data = dict([ (item[key_col], item[data_col]) if blacklist:
for item in data ]) new_data = dict([ (item[key_col], item[data_col])
for item in data
if not item[0] in blacklist ])
else:
new_data = dict([ (item[key_col], item[data_col])
for item in data ])
return new_data return new_data
class GrampsTypeMeta(type): class GrampsTypeMeta(type):
@ -51,20 +56,28 @@ class GrampsTypeMeta(type):
mcs.__class_init__(namespace) mcs.__class_init__(namespace)
class GrampsType(object): class GrampsType(object):
"""Base class for all Gramps object types.""" """Base class for all Gramps object types.
_DATAMAP is a 3-tuple like (index, localized_string, english_string)
_BLACKLIST is a list of indices to ignore (obsolete/retired entries)
(gramps policy is never to delete type values,
or reuse the name (TOKEN) of any specific type value)
"""
_CUSTOM = 0 _CUSTOM = 0
_DEFAULT = 0 _DEFAULT = 0
_DATAMAP = [] _DATAMAP = []
_BLACKLIST = None
__metaclass__ = GrampsTypeMeta __metaclass__ = GrampsTypeMeta
def __class_init__(cls, namespace): def __class_init__(cls, namespace):
cls._I2SMAP = _init_map(cls._DATAMAP, 0, 1) cls._I2SMAP = _init_map(cls._DATAMAP, 0, 1, cls._BLACKLIST)
cls._S2IMAP = _init_map(cls._DATAMAP, 1, 0) cls._S2IMAP = _init_map(cls._DATAMAP, 1, 0, cls._BLACKLIST)
cls._I2EMAP = _init_map(cls._DATAMAP, 0, 2) cls._I2EMAP = _init_map(cls._DATAMAP, 0, 2, cls._BLACKLIST)
cls._E2IMAP = _init_map(cls._DATAMAP, 2, 0) cls._E2IMAP = _init_map(cls._DATAMAP, 2, 0, cls._BLACKLIST)
__class_init__ = classmethod(__class_init__) __class_init__ = classmethod(__class_init__)

View File

@ -8,17 +8,28 @@ from gen.lib.grampstype import GrampsType, _init_map
# some simple map items to test with # some simple map items to test with
vals = "zz ab cd ef".split() vals = "zz ab cd ef".split()
keys = range(len(vals)) keys = range(len(vals))
MAP = [ (k,v*2,v) for (k,v) in zip(keys, vals) ] MAP = [ (k,v*2,v) for (k,v) in zip(keys, vals) ]
BLIST= [1,3]
class GT0(GrampsType): class GT0(GrampsType):
_DEFAULT = 1 # just avoiding the pre-coded 0 _DEFAULT = 1 # just avoiding the pre-coded 0
_CUSTOM = 3 # just avoiding the pre-coded 0 _CUSTOM = 3 # just avoiding the pre-coded 0
_DATAMAP = MAP _DATAMAP = MAP
# NOTE: this type of code might be used in a migration utility
# to allow conversions or other handling of retired type-values
# A migration utility might instantiate several of these with
# varying blacklist-specs
class GT1(GT0):
_BLACKLIST = BLIST
class GT2(GT1):
_BLACKLIST=None
class Test1(U.TestCase): class Test1(U.TestCase):
# some basic tests # some basic tests
def test1a(s): def test1a_basic(s):
s.gt=GT0() s.gt=GT0()
s.assertTrue(isinstance(s.gt, GrampsType)) s.assertTrue(isinstance(s.gt, GrampsType))
# spot-check that MAPs get built # spot-check that MAPs get built
@ -30,7 +41,7 @@ class Test1(U.TestCase):
# (we ignore instance here -- maybe SB tested, too?) # (we ignore instance here -- maybe SB tested, too?)
# this test depends on having _DEFAULT=1, _CUSTOM=3 # this test depends on having _DEFAULT=1, _CUSTOM=3
# NB: tuple tests w/ lengths < 2 fail before release 10403 # NB: tuple tests w/ lengths < 2 fail before release 10403
def test1b(s): def test1b_init_value(s):
for i,v,u in ( for i,v,u in (
(None, 1,u''), # all DEFAULT (None, 1,u''), # all DEFAULT
(0, 0,u''), (0, 0,u''),
@ -51,6 +62,22 @@ class Test1(U.TestCase):
s.assertEquals(g,u, s.assertEquals(g,u,
msg(g,u, "initialization string from '%s'" % `i`)) msg(g,u, "initialization string from '%s'" % `i`))
# test blacklist functionality added to enable fix of bug #1680
class Test2(U.TestCase):
def test2a_blacklist(s):
s.gt=GT1()
# check that MAPs have lengths reduced by blacklist
e= len(keys) - len(BLIST)
g= len(s.gt._E2IMAP)
s.assertEquals(g,e, msg(g,e, "expected length of blacklisted MAP"))
s.ub=GT2()
# check that these MAPS are now un-blacklisted
e= len(keys)
g= len(s.ub._E2IMAP)
s.assertEquals(g,e, msg(g,e, "expected length of un-blacklisted MAP"))
if __name__ == "__main__": if __name__ == "__main__":
U.main() U.main()