No usage of recursiveGet/Set/DelAttr
Claude Paroz <[email protected]> Mon, 28 Feb 2022 14:17:18 +0100
| Newsgroups | gmane.comp.python.reportlab.user |
|---|---|
| Message-ID | <[email protected]> |
Hi, I didn't find any usage of recursiveGetAttr/recursiveSetAttr/recursiveDelAttr in reportlab public code. So if they are not used in other client code, I guess they could simply be removed, as the attached patch is doing. Claude -- www.2xlibre.net
0001-Remove-recursiveGet-Set-DelAttr.patch
(text/x-patch, 8 KB)
From 1998953880fcdb4b3987dbbe49c98c6a72552090 Mon Sep 17 00:00:00 2001 From: Claude Paroz <[email protected]> Date: Thu, 17 Feb 2022 23:40:44 +0100 Subject: [PATCH 1/2] Remove recursiveGet/Set/DelAttr --- src/reportlab/lib/utils.py | 31 -------- tests/test_lib_utils.py | 153 +------------------------------------ 2 files changed, 2 insertions(+), 182 deletions(-) diff --git a/src/reportlab/lib/utils.py b/src/reportlab/lib/utils.py index 811d6906..251cfce1 100644 --- a/src/reportlab/lib/utils.py +++ b/src/reportlab/lib/utils.py @@ -1329,37 +1329,6 @@ class TimeStamp: def asctime(self): return time.asctime(self.lt) -def recursiveGetAttr(obj, name, g=None): - "Can call down into e.g. object1.object2[4].attr" - if not isStr(name): raise TypeError('invalid reursive acess using %r' % name) - name = asNative(name) - name = name.strip() - if not name: raise ValueError('empty recursive access') - dot = '.' if name and name[0] not in '[.(' else '' - return rl_safe_eval('obj%s%s'%(dot,name), g={}, l=dict(obj=obj)) - -def recursiveSetAttr(obj, name, value): - "Can call down into e.g. object1.object2[4].attr = value" - #get the thing above last. - tokens = name.split('.') - if len(tokens) == 1: - setattr(obj, name, value) - else: - most = '.'.join(tokens[:-1]) - last = tokens[-1] - parent = recursiveGetAttr(obj, most) - setattr(parent, last, value) - -def recursiveDelAttr(obj, name): - tokens = name.split('.') - if len(tokens) == 1: - delattr(obj, name) - else: - most = '.'.join(tokens[:-1]) - last = tokens[-1] - parent = recursiveGetAttr(obj, most) - delattr(parent, last) - def yieldNoneSplits(L): '''yield sublists of L separated by None; the Nones disappear''' i = 0 diff --git a/tests/test_lib_utils.py b/tests/test_lib_utils.py index fe3e4370..e9ff8208 100644 --- a/tests/test_lib_utils.py +++ b/tests/test_lib_utils.py @@ -11,9 +11,8 @@ import reportlab from reportlab import rl_config import unittest from reportlab.lib import colors -from reportlab.lib.utils import recursiveImport, recursiveGetAttr, recursiveSetAttr, rl_isfile, \ +from reportlab.lib.utils import recursiveImport, rl_isfile, \ isCompactDistro, isPyPy, TimeStamp, rl_get_module, \ - recursiveGetAttr, recursiveSetAttr, recursiveDelAttr, \ asUnicode, asUnicodeEx, asBytes def _rel_open_and_read(fn): @@ -92,24 +91,6 @@ class ImporterTestCase(unittest.TestCase): finally: os.chdir(cwd) - def test5(self): - "recursive attribute setting/getting on modules" - import reportlab.lib.units - inch = recursiveGetAttr(reportlab, 'lib.units.inch') - assert inch == 72 - - recursiveSetAttr(reportlab, 'lib.units.cubit', 18*inch) - cubit = recursiveGetAttr(reportlab, 'lib.units.cubit') - assert cubit == 18*inch - - def test6(self): - "recursive attribute setting/getting on drawings" - from reportlab.graphics.charts.barcharts import sampleH1 - drawing = sampleH1() - recursiveSetAttr(drawing, 'barchart.valueAxis.valueMax', 72) - theMax = recursiveGetAttr(drawing, 'barchart.valueAxis.valueMax') - assert theMax == 72 - def test7(self): "test open and read of a simple relative file" b = _rel_open_and_read('../docs/images/Edit_Prefs.gif') @@ -226,138 +207,8 @@ class ImporterTestCase(unittest.TestCase): self.assertRaises(AttributeError,asBytes,['abc']) self.myAssertRaisesRegex(AttributeError,"asBytes\(.*'list' object has no attribute 'encode'", asBytes,['abc']) -class RaccessTest: - l = [1, 2] - a = [0, [1, 2, [3,4]]] - b = {'x': {'y': 'y'}, 'z': [1, 2]} - z = 'z' - -class RaccessPerson: - settings = { - 'autosave': True, - 'style': { - 'height': 30, - 'width': 200 - }, - 'themes': ['light', 'dark'] - } - def __init__(self, name, age, friends): - self.name = name - self.age = age - self.friends = friends - -class RaccessTestCase(unittest.TestCase): - "Test recursive access functions" - def test1(self): - def innerTest(k,v): - obj = RaccessTest() - obj.t = obj - obj.a.append(obj) - obj.b['w'] = obj - self.assertEqual(recursiveGetAttr(obj,k),v,"error getattr(obj,%r)==%r" % (k,v)) - for k,v in [ - ('l', RaccessTest.l), - ('t.t.t.t.z', 'z'), - ('a[0]', 0), - ('a[1][0]', 1), - ('a[1][2]', [3,4]), - ('b["x"]', {'y': 'y'}), - ('b["x"]["y"]', 'y'), - ('b["z"]', [1,2]), - ('b["z"][1]', 2), - ('b["w"].z', 'z'), - ('b["w"].t.l', [1, 2]), - ('a[-1].z', 'z'), - ('l[-1]', 2), - ('a[2].t.a[-1].z', 'z'), - ('a[2].t.b["z"][0]', 1), - ('a[-1].t.z', 'z'), - ]: - innerTest(k,v) - - def test_person_example(self): - bob = RaccessPerson(name="Bob", age=31, friends=[]) - jill = RaccessPerson(name="Jill", age=29, friends=[bob]) - jack = RaccessPerson(name="Jack", age=28, friends=[bob, jill]) - - # Nothing new - self.assertEqual(recursiveGetAttr(bob, 'age') ,31) - - # Lists - self.assertEqual(recursiveGetAttr(jill, 'friends[0].name') ,'Bob') - self.assertEqual(recursiveGetAttr(jack, 'friends[-1].age') ,29) - - # Dict lookups - self.assertEqual(recursiveGetAttr(jack, 'settings["style"]["width"]') ,200) - - # Combination of lookups - self.assertEqual(recursiveGetAttr(jack, 'settings["themes"][-2]') ,'light') - self.assertEqual(recursiveGetAttr(jack, 'friends[-1].settings["themes"][1]') ,'dark') - - # Setattr - #recursiveSetAttr(bob, 'settings["style"]["width"]', 400) - #self.assertEqual(recursiveGetAttr(bob, 'settings["style"]["width"]') ,400) - - # Nested objects - recursiveSetAttr(bob, 'friends', [jack, jill]) - self.assertEqual(recursiveGetAttr(jack, 'friends[0].friends[0]') ,jack) - - recursiveSetAttr(jill, 'friends[0].age', 32) - self.assertEqual(bob.age ,32) - - # Deletion - #recursiveDelAttr(jill, 'friends[0]') - #self.assertEqual(len(jill.friends) ,0) - - recursiveDelAttr(jill, 'age') - assert not hasattr(jill, 'age') - - recursiveDelAttr(bob, 'friends[0].age') - assert not hasattr(jack, 'age') - - # Unsupported - #with self.assertRaises(NotImplementedError) as e: - # recursiveGetAttr(bob, 'friends[0+1]') - - # Nice try, function calls are not allowed - #with self.assertRaises(ValueError): - # recursiveGetAttr(bob, 'friends.pop(0)') - - # Must be an expression - with self.assertRaises(SyntaxError): - recursiveGetAttr(bob, 'friends = []') - - # Must be an expression - with self.assertRaises(SyntaxError): - recursiveGetAttr(bob, 'friends..') - - # Must be an expression - with self.assertRaises(KeyError): - recursiveGetAttr(bob, 'settings["DoesNotExist"]') - - # Must be an expression - with self.assertRaises(IndexError): - recursiveGetAttr(bob, 'friends[100]') - - def test_empty(self): - obj = RaccessTest() - with self.assertRaises(ValueError): - recursiveGetAttr(obj," ") - - with self.assertRaises(ValueError): - recursiveGetAttr(obj,"") - - with self.assertRaises(TypeError): - recursiveGetAttr(obj, 0) - - with self.assertRaises(TypeError): - recursiveGetAttr(obj, None) - - with self.assertRaises(TypeError): - recursiveGetAttr(obj, obj) - def makeSuite(): - return makeSuiteForClasses(ImporterTestCase,RaccessTestCase) + return makeSuiteForClasses(ImporterTestCase) if __name__ == "__main__": #noruntests unittest.TextTestRunner().run(makeSuite()) -- 2.30.2