1+ import dataclasses as dc
12import re
23import sys
34from collections .abc import Callable
@@ -15,6 +16,11 @@ def negate(condition: str) -> str:
1516 return condition [1 :]
1617 return "!" + condition
1718
19+
20+ is_a_simple_defined = re .compile (r'^defined\s*\(\s*[A-Za-z0-9_]+\s*\)$' ).match
21+
22+
23+ @dc .dataclass (repr = False )
1824class Monitor :
1925 """
2026 A simple C preprocessor that scans C source and computes, line by line,
@@ -27,25 +33,20 @@ class Monitor:
2733
2834 Anyway this implementation seems to work well enough for the CPython sources.
2935 """
36+ filename : str | None = None
37+ _ : dc .KW_ONLY
38+ verbose : bool = False
3039
31- is_a_simple_defined : Callable [[str ], re .Match [str ] | None ]
32- is_a_simple_defined = re .compile (r'^defined\s*\(\s*[A-Za-z0-9_]+\s*\)$' ).match
33-
34- def __init__ (self , filename : str | None = None , * , verbose : bool = False ) -> None :
40+ def __post_init__ (self ) -> None :
3541 self .stack : TokenStack = []
3642 self .in_comment = False
3743 self .continuation : str | None = None
3844 self .line_number = 0
39- self .filename = filename
40- self .verbose = verbose
4145
4246 def __repr__ (self ) -> str :
43- return '' .join ((
44- '<Monitor ' ,
45- str (id (self )),
46- " line=" , str (self .line_number ),
47- " condition=" , repr (self .condition ()),
48- ">" ))
47+ return (
48+ f"<Monitor { id (self )} line={ self .line_number } condition={ self .condition ()!r} >"
49+ )
4950
5051 def status (self ) -> str :
5152 return str (self .line_number ).rjust (4 ) + ": " + self .condition ()
@@ -152,7 +153,7 @@ def pop_stack() -> TokenAndCondition:
152153 if not condition :
153154 self .fail ("Invalid format for #" + token + " line: no argument!" )
154155 if token in {'if' , 'elif' }:
155- if not self . is_a_simple_defined (condition ):
156+ if not is_a_simple_defined (condition ):
156157 condition = "(" + condition + ")"
157158 if token == 'elif' :
158159 previous_token , previous_condition = pop_stack ()
0 commit comments