From d38952dd0012314a535efcb0f535a3610c70766b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B6rg=20Lehmann?= Date: Tue, 30 Dec 2003 15:00:01 +0000 Subject: [PATCH] As discussed on pyx-devel, I introduced a new attr subclass sortbeforeexlusiveattr, which combines sortbeforeattr and exlusiveattr. Included is a unit test. git-svn-id: https://pyx.svn.sourceforge.net/svnroot/pyx/trunk/pyx@1197 069f4177-920e-0410-937b-c2a4a81bcd90 --- pyx/attr.py | 40 ++++++++++++++++++++++++++++++++++++++-- pyx/style.py | 8 ++------ pyx/text.py | 16 ++++------------ test/unit/test_attr.py | 13 +++++++++++++ 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/pyx/attr.py b/pyx/attr.py index 745bb3b0..8001e949 100644 --- a/pyx/attr.py +++ b/pyx/attr.py @@ -89,8 +89,8 @@ class attr: class exclusiveattr(attr): - """an attribute which swallows all but the last of the same type in an - attribute list""" + """an attribute which swallows all but the last of the same type (specified + by the exlusiveclass argument to the constructor) in an attribute list""" def __init__(self, exclusiveclass): self.exclusiveclass = exclusiveclass @@ -132,6 +132,42 @@ class sortbeforeattr(attr): return result +class sortbeforeexclusiveattr(attr): + + """an attribute which swallows all but the last of the same type (specified + by the exlusiveclass argument to the constructor) in an attribute list and + places itself previous to all attributes given in the beforetheclasses + argument to the constructor""" + + def __init__(self, exclusiveclass, beforetheclasses): + self.exclusiveclass = exclusiveclass + self.beforetheclasses = beforetheclasses + + def merge(self, attrs): + first = 1 + result = [] + try: + for attr in attrs: + if first and isinstance(attr, self.beforetheclasses): + result.append(self) + first = 0 + if not isinstance(attr, self.exclusiveclass): + result.append(attr) + except TypeError: # workaround for Python 2.1 and older + for attr in attrs: + if first: + for dependedclass in self.beforetheclasses: + if isinstance(attr, dependedclass): + result.append(self) + first = 0 + break + if not isinstance(attr, self.exclusiveclass): + result.append(attr) + if first: + result.append(self) + return result + + class clearclass(attr): """a special attribute which allows to remove all predecessing attributes of diff --git a/pyx/style.py b/pyx/style.py index 62d7bd65..4ea91d78 100644 --- a/pyx/style.py +++ b/pyx/style.py @@ -138,17 +138,13 @@ linestyle.dashdotted = linestyle(linecap.round, dash([0, 3, 3, 3])) linestyle.clear = attr.clearclass(linestyle) -class linewidth(unit.length, attr.exclusiveattr, attr.sortbeforeattr, strokestyle): +class linewidth(unit.length, attr.sortbeforeexclusiveattr, strokestyle): """linewidth of paths""" def __init__(self, l="0 cm"): unit.length.__init__(self, l=l, default_type="w") - attr.exclusiveattr.__init__(self, linewidth) - attr.sortbeforeattr.__init__(self, [dash, linestyle]) - - def merge(self, attrs): - return attr.sortbeforeattr.merge(self, attr.exclusiveattr.merge(self, attrs)[:-1]) + attr.sortbeforeexclusiveattr.__init__(self, linewidth, [dash, linestyle]) def write(self, file): file.write("%f setlinewidth\n" % unit.topt(self)) diff --git a/pyx/text.py b/pyx/text.py index 20531262..a404ffe1 100644 --- a/pyx/text.py +++ b/pyx/text.py @@ -1686,7 +1686,7 @@ for s in defaultsizelist: _textattrspreamble += "\\newbox\\PyXBoxVBox%\n\\newdimen\PyXDimenVBox%\n" -class parbox_pt(attr.exclusiveattr, attr.sortbeforeattr, textattr): +class parbox_pt(attr.sortbeforeexclusiveattr, textattr): top = 1 middle = 2 @@ -1695,11 +1695,7 @@ class parbox_pt(attr.exclusiveattr, attr.sortbeforeattr, textattr): def __init__(self, width, baseline=top): self.width = width self.baseline = baseline - attr.exclusiveattr.__init__(self, parbox_pt) - attr.sortbeforeattr.__init__(self, [_localattr]) - - def merge(self, attrs): - return attr.sortbeforeattr.merge(self, attr.exclusiveattr.merge(self, attrs)[:-1]) + attr.sortbeforeexclusiveattr.__init__(self, parbox_pt, [_localattr]) def apply(self, expr): if self.baseline == self.top: @@ -1719,14 +1715,10 @@ class parbox(parbox_pt): _textattrspreamble += "\\newbox\\PyXBoxVAlign%\n\\newdimen\PyXDimenVAlign%\n" -class valign(attr.exclusiveattr, attr.sortbeforeattr, textattr): +class valign(attr.sortbeforeexclusiveattr, textattr): def __init__(self): - attr.exclusiveattr.__init__(self, valign) - attr.sortbeforeattr.__init__(self, [parbox_pt, _localattr]) - - def merge(self, attrs): - return attr.sortbeforeattr.merge(self, attr.exclusiveattr.merge(self, attrs)[:-1]) + attr.sortbeforeexclusiveattr.__init__(self, valign, [parbox_pt, _localattr]) class _valigntop(valign): diff --git a/test/unit/test_attr.py b/test/unit/test_attr.py index 52ad61d5..31daf080 100644 --- a/test/unit/test_attr.py +++ b/test/unit/test_attr.py @@ -15,6 +15,10 @@ class A3(sortbeforeattr): pass class B3(sortbeforeattr): pass class C3(attr): pass +class A4(sortbeforeexclusiveattr): pass +class B4(sortbeforeexclusiveattr): pass +class C4(attr): pass + class AttrTestCase(unittest.TestCase): @@ -53,6 +57,15 @@ class AttrTestCase(unittest.TestCase): c2 = C3() assert mergeattrs([a1, b2, b1, c2, a2, c1]) == [a1, a2, b2, b1, c2, c1] + def testExclusiveSort(self): + a1 = A4(A4, (B4, C4)) + a2 = A4(A4, (B4, C4)) + b1 = B4(B4, (C4)) + b2 = B4(B4, (C4)) + c1 = C4() + c2 = C4() + assert mergeattrs([b2, a1, b1, c2, a2, c1]) == [a2, b1, c2, c1] + suite = unittest.TestSuite((unittest.makeSuite(AttrTestCase, 'test'), )) -- 2.11.4.GIT