Skip to content

Commit 3fdb8cb

Browse files
committed
Use structural pattern matching
1 parent 0305252 commit 3fdb8cb

File tree

10 files changed

+144
-134
lines changed

10 files changed

+144
-134
lines changed

webware/Admin/AppControl.py

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -12,60 +12,61 @@ def writeContent(self):
1212
wr = self.writeln
1313
action = self.request().field("action", None)
1414

15-
if action is None:
16-
wr('''<form action="AppControl" method="post">
15+
match action:
16+
case None:
17+
wr('''<form action="AppControl" method="post">
1718
<table>
1819
<tr><td><input type="submit" name="action" value="Clear cache"></td>
1920
<td>Clear the class and instance caches of each servlet factory.</td>
2021
</tr><tr>
2122
<td><input type="submit" name="action" value="Reload"></td>
2223
<td>Reload the selected Python modules. Be careful!</td></tr>''')
23-
wr('<tr><td></td><td>')
24-
for n in sorted(sys.modules):
25-
m = sys.modules[n]
26-
if (not n.endswith('__init__') and not hasattr(m, '__path__')
27-
and not hasattr(m, '__orig_file__')):
28-
# show only the easily reloadable modules
29-
wr(f'<input type="checkbox" name="reloads" value="{n}">'
30-
f' {n}<br>')
31-
wr('</td></tr>\n</table>\n</form>')
24+
wr('<tr><td></td><td>')
25+
for n in sorted(sys.modules):
26+
m = sys.modules[n]
27+
if (not n.endswith('__init__') and not hasattr(m, '__path__')
28+
and not hasattr(m, '__orig_file__')):
29+
# show only the easily reloadable modules
30+
wr(f'<input type="checkbox" name="reloads" value="{n}">'
31+
f' {n}<br>')
32+
wr('</td></tr>\n</table>\n</form>')
3233

33-
elif action == "Clear cache":
34-
from URLParser import ServletFactoryManager
35-
factories = [f for f in ServletFactoryManager._factories
36-
if f._classCache]
37-
wr('<p>')
38-
for factory in factories:
39-
wr(f'Flushing cache of {factory.name()}...<br>')
40-
factory.flushCache()
41-
wr('</p>')
42-
wr('<p style="color:green">The caches of all factories'
43-
' have been flushed.</p>')
44-
wr('<p>Click here to view the Servlet cache:'
45-
' <a href="ServletCache">Servlet Cache</a></p>')
34+
case "Clear cache":
35+
from URLParser import ServletFactoryManager
36+
factories = [f for f in ServletFactoryManager._factories
37+
if f._classCache]
38+
wr('<p>')
39+
for factory in factories:
40+
wr(f'Flushing cache of {factory.name()}...<br>')
41+
factory.flushCache()
42+
wr('</p>')
43+
wr('<p style="color:green">The caches of all factories'
44+
' have been flushed.</p>')
45+
wr('<p>Click here to view the Servlet cache:'
46+
' <a href="ServletCache">Servlet Cache</a></p>')
4647

47-
elif action == "Reload":
48-
wr('<p>Reloading selected modules. Any existing classes'
49-
' will continue to use the old module definitions,'
50-
' as will any functions/variables imported using "from".'
51-
' Use "Clear Cache" to clean out any servlets'
52-
' in this condition.<p>')
53-
reloadNames = req.field("reloads", None)
54-
if not isinstance(reloadNames, list):
55-
reloadNames = [reloadNames]
56-
wr('<p>')
57-
for n in reloadNames:
58-
m = sys.modules.get(n)
59-
if m:
60-
wr(f"Reloading {self.htmlEncode(str(m))}...<br>")
61-
try:
62-
reload(m)
63-
except Exception as e:
64-
wr('<span style="color:red">Could not reload, '
65-
f'error was "{e}".</span><br>')
66-
wr('</p>')
67-
wr('<p style="color:green">The selected modules'
68-
' have been reloaded.</p>')
48+
case "Reload":
49+
wr('<p>Reloading selected modules. Any existing classes'
50+
' will continue to use the old module definitions,'
51+
' as will any functions/variables imported using "from".'
52+
' Use "Clear Cache" to clean out any servlets'
53+
' in this condition.<p>')
54+
reloadNames = req.field("reloads", None)
55+
if not isinstance(reloadNames, list):
56+
reloadNames = [reloadNames]
57+
wr('<p>')
58+
for n in reloadNames:
59+
m = sys.modules.get(n)
60+
if m:
61+
wr(f"Reloading {self.htmlEncode(str(m))}...<br>")
62+
try:
63+
reload(m)
64+
except Exception as e:
65+
wr('<span style="color:red">Could not reload, '
66+
f'error was "{e}".</span><br>')
67+
wr('</p>')
68+
wr('<p style="color:green">The selected modules'
69+
' have been reloaded.</p>')
6970

70-
else:
71-
wr(f'<p>Cannot perform "{action}".</p>')
71+
case _:
72+
wr(f'<p>Cannot perform "{action}".</p>')

webware/HTTPResponse.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,17 @@ def setCookie(
123123
cookie = Cookie(name, value)
124124
t = expires
125125
if isinstance(t, str):
126-
if t == 'ONCLOSE':
127-
t = None
128-
elif t == 'NOW':
129-
cookie.delete()
130-
return
131-
elif t == 'NEVER':
132-
t = gmtime()
133-
t = (t[0] + 10,) + t[1:]
134-
elif t.startswith('+'):
135-
t = time() + timeDecode(t[1:])
126+
match t:
127+
case 'ONCLOSE':
128+
t = None
129+
case 'NOW':
130+
cookie.delete()
131+
return
132+
case 'NEVER':
133+
t = gmtime()
134+
t = (t[0] + 10,) + t[1:]
135+
case _ if t.startswith('+'):
136+
t = time() + timeDecode(t[1:])
136137
if t:
137138
if isinstance(t, int | float):
138139
t = gmtime(t)

webware/JSONRPCServlet.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,13 @@ def jsonCall(self):
8383
try:
8484
if self._debug:
8585
self.log(f"json call {call}(call)")
86-
if isinstance(params, list):
87-
result = method(*params)
88-
elif isinstance(params, dict):
89-
result = method(**params)
90-
else:
91-
result = method()
86+
match params:
87+
case list():
88+
result = method(*params)
89+
case dict():
90+
result = method(**params)
91+
case _:
92+
result = method()
9293
self.writeResult(result)
9394
except Exception:
9495
err = StringIO()

webware/MiscUtils/DataTable.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -579,10 +579,12 @@ def setHeadings(self, headings):
579579
"""
580580
if not headings:
581581
self._headings = []
582-
elif isinstance(headings[0], str):
583-
self._headings = list(map(TableColumn, headings))
584-
elif isinstance(headings[0], TableColumn):
585-
self._headings = list(headings)
582+
else:
583+
match headings[0]:
584+
case str():
585+
self._headings = list(map(TableColumn, headings))
586+
case TableColumn():
587+
self._headings = list(headings)
586588
for heading in self._headings:
587589
if heading.type() is None:
588590
heading.setType(self._defaultType)

webware/PSP/BraceConverter.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,24 +60,25 @@ def parseLine(self, line, writer):
6060
self.line = self.line[match.end(1):]
6161
else:
6262
c = self.line[0]
63-
if c == "'":
64-
self.handleQuote("'", writer)
65-
self.skipQuote(writer)
66-
elif c == '"':
67-
self.handleQuote('"', writer)
68-
self.skipQuote(writer)
69-
elif c == '{':
70-
self.openBrace(writer)
71-
elif c == '}':
72-
self.closeBrace(writer)
73-
elif c == ':':
74-
self.openBlock(writer)
75-
elif c == '#':
76-
writer.printChars(self.line)
77-
self.line = ''
78-
else:
79-
# should never get here
80-
raise ValueError(f'Invalid character: {c!r}')
63+
match c:
64+
case "'":
65+
self.handleQuote("'", writer)
66+
self.skipQuote(writer)
67+
case '"':
68+
self.handleQuote('"', writer)
69+
self.skipQuote(writer)
70+
case '{':
71+
self.openBrace(writer)
72+
case '}':
73+
self.closeBrace(writer)
74+
case ':':
75+
self.openBlock(writer)
76+
case '#':
77+
writer.printChars(self.line)
78+
self.line = ''
79+
case _:
80+
# should never get here
81+
raise ValueError(f'Invalid character: {c!r}')
8182
writer.printChars('\n')
8283

8384
def openBlock(self, writer):

webware/PSP/PSPParser.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,17 @@ def checkDirective(self, handler, reader):
117117
reader.advance(len(match))
118118
# parse the directive attr:val pair dictionary
119119
attrs = reader.parseTagAttributes()
120-
if match == 'page':
121-
checkAttributes('Page directive', attrs, ([], {
122-
'imports', 'extends', 'method',
123-
'isThreadSafe', 'isInstanceSafe',
124-
'indentType', 'indentSpaces',
125-
'gobbleWhitespace', 'formatter'}))
126-
elif match == 'include':
127-
checkAttributes('Include directive', attrs, (['file'], []))
128-
else:
129-
raise PSPParserException(f'{match} directive not implemented')
120+
match match:
121+
case 'page':
122+
checkAttributes('Page directive', attrs, ([], {
123+
'imports', 'extends', 'method',
124+
'isThreadSafe', 'isInstanceSafe',
125+
'indentType', 'indentSpaces',
126+
'gobbleWhitespace', 'formatter'}))
127+
case 'include':
128+
checkAttributes('Include directive', attrs, (['file'], []))
129+
case _:
130+
raise PSPParserException(f'{match} directive not implemented')
130131
reader.skipSpaces() # skip to where we expect a close tag
131132
if reader.matches('%>'):
132133
reader.advance(2) # advance past it

webware/PSP/ParseEventHandler.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -190,21 +190,22 @@ def handleDirective(self, directive, start, stop, attrs):
190190
"""Flush any template data and create a new DirectiveGenerator."""
191191
self._parser.flushCharData(self.tmplStart, self.tmplStop)
192192
# big switch
193-
if directive == 'page':
194-
for h in attrs:
195-
if h in self.directiveHandlers:
196-
self.directiveHandlers[h](self, attrs[h], start, stop)
197-
else:
198-
raise ValueError(f'No page directive handler: {h}')
199-
elif directive == 'include':
200-
filename = attrs['file']
201-
encoding = attrs.get('encoding')
202-
try:
203-
self._reader.pushFile(filename, encoding)
204-
except IOError as e:
205-
raise IOError(f'PSP include file not found: {filename}') from e
206-
else:
207-
raise ValueError('Invalid directive: {directive}')
193+
match directive:
194+
case 'page':
195+
for h in attrs:
196+
if h in self.directiveHandlers:
197+
self.directiveHandlers[h](self, attrs[h], start, stop)
198+
else:
199+
raise ValueError(f'No page directive handler: {h}')
200+
case 'include':
201+
filename = attrs['file']
202+
encoding = attrs.get('encoding')
203+
try:
204+
self._reader.pushFile(filename, encoding)
205+
except IOError as e:
206+
raise IOError(f'PSP include file not found: {filename}') from e
207+
case _:
208+
raise ValueError('Invalid directive: {directive}')
208209

209210
def handleScript(self, start, stop, attrs):
210211
"""Handle scripting elements"""

webware/PSP/ServletWriter.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,17 @@ def setIndention(self):
4747
self._indent = '\t' if self._useTabs else self._indentSpaces
4848

4949
def setIndentType(self, indentType):
50-
if indentType == 'tabs':
51-
self._useTabs = True
52-
self.setIndention()
53-
elif indentType == 'spaces':
54-
self._useTabs = False
55-
self.setIndention()
56-
elif indentType == 'braces':
57-
self._useTabs = False
58-
self._useBraces = True
59-
self.setIndention()
50+
match indentType:
51+
case 'tabs':
52+
self._useTabs = True
53+
self.setIndention()
54+
case 'spaces':
55+
self._useTabs = False
56+
self.setIndention()
57+
case 'braces':
58+
self._useTabs = False
59+
self._useBraces = True
60+
self.setIndention()
6061

6162
def close(self):
6263
pyCode = self._file.getvalue()

webware/RPCServlet.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ def resultForException(self, e, trans):
3535
"""
3636
# report exception back to server
3737
setting = trans.application().setting('RPCExceptionReturn')
38-
if setting == 'occurred':
39-
result = 'unhandled exception'
40-
elif setting == 'exception':
41-
result = str(e)
42-
elif setting == 'traceback':
43-
result = ''.join(traceback.format_exception(*sys.exc_info()))
44-
else:
45-
raise ValueError(f'Invalid setting: {setting!r}')
46-
return result
38+
match setting:
39+
case 'occurred':
40+
return 'unhandled exception'
41+
case 'exception':
42+
return str(e)
43+
case 'traceback':
44+
return ''.join(traceback.format_exception(*sys.exc_info()))
45+
case _:
46+
raise ValueError(f'Invalid setting: {setting!r}')
4747

4848
@staticmethod
4949
def sendOK(contentType, contents, trans, contentEncoding=None):

webware/Scripts/WebwareCLI.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ def main(args=None):
2828
args = parser.parse_args(args)
2929
command = args.command
3030
del args.command
31-
if command == 'make':
32-
make(args)
33-
elif command == 'serve':
34-
serve(args)
31+
match command:
32+
case 'make':
33+
make(args)
34+
case 'serve':
35+
serve(args)
3536

3637

3738
if __name__ == '__main__':

0 commit comments

Comments
 (0)