comparison roundup/mlink_expr.py @ 8472:224ccb8b49ca

refactor: change some classes to use __slots__ Speed up access to and reduce size of some low level classes. A few classes in security.py, rest.py are heavily used. But for all, it prevents adding random properties to lower level classes that people shouldn't be mucking with. While doing this I found some test cases accessing an invalid property name and this change caused the cases to crash. admin.py: Use new method Role.props_dict() and Permission.props_dict() where original code just referenced __dict__ when printing Role/Permission. mlink_expr.py: Add slots to multiple classes. Classes Binary and Unary set real properties/attributes. Classes that inherit from them (Equals, Empty, Not, Or, And) define empty slots tuple to eliminate need for __dict__. Class Expression also gets a slot. rate_limit.py: RateLimit and Gcra classes get slots. A couple of pep8 fixes: sort imports, remove trailing spaces on a line, remove unused noqa comment. rest.py: Add slots to class SimulateFieldStorageFromJson and FsValue classes. The memory savings from this could be useful as well as speedier access to the attributes. security.py: Add slots to Permission class. To prevent conflict between slot limit_perm_to_props_only and the class variable of the same name, rename the class variable to limit_perm_to_props_only_default. Also define method props_dict() to allow other code to get a dict to iterate over when checking permissions. Add slots to class Role along with props_dict() method. Add slots to class Security. Also have to add explicit __dict__ slot to support test override of the hasPermission() method. Add props_dict() method, currently unused, but added for symmetry. support.py: TruthDict and PrioList gets slots. test/test_cgi.py: Fix incorrect setting of permission property. Was setting permissions. So testing may not have been doing what we thought it was. Multiple places found with this typo. Remove setting of permissions in some places where it should have no effect on the test and looks like it was just copypasta. test/test_xmlrpc.py Remove setting of permissions in some places where it should have no effect on the test and looks like it was just copypasta.
author John Rouillard <rouilj@ieee.org>
date Mon, 03 Nov 2025 00:13:04 -0500
parents 741ea8a86012
children
comparison
equal deleted inserted replaced
8471:8e72dc7b7f2f 8472:224ccb8b49ca
58 return "%s: context=%s" % (self.args[0], self.context) 58 return "%s: context=%s" % (self.args[0], self.context)
59 59
60 60
61 class Binary: 61 class Binary:
62 62
63 __slots__ = ("x", "y")
64
63 def __init__(self, x, y): 65 def __init__(self, x, y):
64 self.x = x 66 self.x = x
65 self.y = y 67 self.y = y
66 68
67 def visit(self, visitor): 69 def visit(self, visitor):
69 self.y.visit(visitor) 71 self.y.visit(visitor)
70 72
71 73
72 class Unary: 74 class Unary:
73 75
76 __slots__ = ("x",)
77
74 def __init__(self, x): 78 def __init__(self, x):
75 self.x = x 79 self.x = x
76 80
77 def generate(self, atom): 81 def generate(self, atom):
78 return atom(self) 82 return atom(self)
81 self.x.visit(visitor) 85 self.x.visit(visitor)
82 86
83 87
84 class Equals(Unary): 88 class Equals(Unary):
85 89
90 __slots__ = ()
91
86 def evaluate(self, v): 92 def evaluate(self, v):
87 return self.x in v 93 return self.x in v
88 94
89 def visit(self, visitor): 95 def visit(self, visitor):
90 visitor(self) 96 visitor(self)
93 return "Value %s" % self.x 99 return "Value %s" % self.x
94 100
95 101
96 class Empty(Unary): 102 class Empty(Unary):
97 103
104 __slots__ = ()
105
98 def evaluate(self, v): 106 def evaluate(self, v):
99 return not v 107 return not v
100 108
101 def visit(self, visitor): 109 def visit(self, visitor):
102 visitor(self) 110 visitor(self)
105 return "ISEMPTY(-1)" 113 return "ISEMPTY(-1)"
106 114
107 115
108 class Not(Unary): 116 class Not(Unary):
109 117
118 __slots__ = ()
119
110 def evaluate(self, v): 120 def evaluate(self, v):
111 return not self.x.evaluate(v) 121 return not self.x.evaluate(v)
112 122
113 def generate(self, atom): 123 def generate(self, atom):
114 return "NOT(%s)" % self.x.generate(atom) 124 return "NOT(%s)" % self.x.generate(atom)
116 def __repr__(self): 126 def __repr__(self):
117 return "NOT(%s)" % self.x 127 return "NOT(%s)" % self.x
118 128
119 129
120 class Or(Binary): 130 class Or(Binary):
131
132 __slots__ = ()
121 133
122 def evaluate(self, v): 134 def evaluate(self, v):
123 return self.x.evaluate(v) or self.y.evaluate(v) 135 return self.x.evaluate(v) or self.y.evaluate(v)
124 136
125 def generate(self, atom): 137 def generate(self, atom):
130 def __repr__(self): 142 def __repr__(self):
131 return "(%s OR %s)" % (self.y, self.x) 143 return "(%s OR %s)" % (self.y, self.x)
132 144
133 145
134 class And(Binary): 146 class And(Binary):
147
148 __slots__ = ()
135 149
136 def evaluate(self, v): 150 def evaluate(self, v):
137 return self.x.evaluate(v) and self.y.evaluate(v) 151 return self.x.evaluate(v) and self.y.evaluate(v)
138 152
139 def generate(self, atom): 153 def generate(self, atom):
183 return pop() 197 return pop()
184 198
185 199
186 class Expression: 200 class Expression:
187 201
202 __slots__ = ("evaluate",)
203
188 def __init__(self, v, is_link=False): 204 def __init__(self, v, is_link=False):
189 try: 205 try:
190 opcodes = [int(x) for x in v] 206 opcodes = [int(x) for x in v]
191 if min(opcodes) >= -1: 207 if min(opcodes) >= -1:
192 raise ValueError() 208 raise ValueError()

Roundup Issue Tracker: http://roundup-tracker.org/