From e21d5520135d0be5476f644d9ad6c19b3e998644 Mon Sep 17 00:00:00 2001 From: James G Sack Date: Thu, 27 Mar 2008 07:24:06 +0000 Subject: [PATCH] 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 --- src/gen/lib/grampstype.py | 29 ++++++++++++++++++------- src/gen/lib/test/grampstype_test.py | 33 ++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/gen/lib/grampstype.py b/src/gen/lib/grampstype.py index c1824341c..2f93786a1 100644 --- a/src/gen/lib/grampstype.py +++ b/src/gen/lib/grampstype.py @@ -31,12 +31,17 @@ Base type for all gramps types. #------------------------------------------------------------------------ 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. """ - new_data = dict([ (item[key_col], item[data_col]) - for item in data ]) + if blacklist: + 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 class GrampsTypeMeta(type): @@ -51,20 +56,28 @@ class GrampsTypeMeta(type): mcs.__class_init__(namespace) 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 _DEFAULT = 0 _DATAMAP = [] + _BLACKLIST = None __metaclass__ = GrampsTypeMeta def __class_init__(cls, namespace): - cls._I2SMAP = _init_map(cls._DATAMAP, 0, 1) - cls._S2IMAP = _init_map(cls._DATAMAP, 1, 0) - cls._I2EMAP = _init_map(cls._DATAMAP, 0, 2) - cls._E2IMAP = _init_map(cls._DATAMAP, 2, 0) + cls._I2SMAP = _init_map(cls._DATAMAP, 0, 1, cls._BLACKLIST) + cls._S2IMAP = _init_map(cls._DATAMAP, 1, 0, cls._BLACKLIST) + cls._I2EMAP = _init_map(cls._DATAMAP, 0, 2, cls._BLACKLIST) + cls._E2IMAP = _init_map(cls._DATAMAP, 2, 0, cls._BLACKLIST) __class_init__ = classmethod(__class_init__) diff --git a/src/gen/lib/test/grampstype_test.py b/src/gen/lib/test/grampstype_test.py index 2b07c2f35..8db39024a 100644 --- a/src/gen/lib/test/grampstype_test.py +++ b/src/gen/lib/test/grampstype_test.py @@ -8,17 +8,28 @@ from gen.lib.grampstype import GrampsType, _init_map # some simple map items to test with vals = "zz ab cd ef".split() 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): _DEFAULT = 1 # just avoiding the pre-coded 0 _CUSTOM = 3 # just avoiding the pre-coded 0 _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): # some basic tests - def test1a(s): + def test1a_basic(s): s.gt=GT0() s.assertTrue(isinstance(s.gt, GrampsType)) # spot-check that MAPs get built @@ -30,7 +41,7 @@ class Test1(U.TestCase): # (we ignore instance here -- maybe SB tested, too?) # this test depends on having _DEFAULT=1, _CUSTOM=3 # NB: tuple tests w/ lengths < 2 fail before release 10403 - def test1b(s): + def test1b_init_value(s): for i,v,u in ( (None, 1,u''), # all DEFAULT (0, 0,u''), @@ -51,6 +62,22 @@ class Test1(U.TestCase): s.assertEquals(g,u, 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__": U.main()