11from check50 import Failure , Missing , Mismatch
22import ast
33
4- def check50_assert (cond : bool , src : str ):
4+ def check50_assert (cond , src , msg_or_exc = None ):
55 """
66 Asserts a conditional statement. If the condition evaluates to True,
7- nothing happens. Otherwise, the condition will raise a check50 exception.
8- Used in rewriting check files. Evaluates subconditions in order and raises
9- the first exception it sees. The specific exception raised depends on the
10- type of conditional statement (see also `classify_ast`.)
7+ nothing happens. Otherwise, it will look for a message or exception that
8+ follows the condition (seperated by a comma). If the msg_or_exc is not
9+ a string, an exception, or not provided, then the additional argument is
10+ silently ignored, raising a check50.Failure.
11+
12+ Used for rewriting check files.
13+
14+ Example usage:
15+ ```
16+ assert x in y, check50.Missing(x, y)
17+ ```
18+ will be converted to
19+ ```
20+ check50_assert(x in y, "x in y", check50.Missing(x, y))
21+ ```
1122
1223 :param cond: The conditional statement.
1324 :type cond: bool
1425 :param src: The source code string of the conditional expression \
1526 (e.g., 'x in y'), extracted from the AST.
1627 :type src: str
17-
18- :raises check50.Missing, check50.Mismatch, or check50.Failure: if the condition fails
28+ :param msg_or_exc: The message or exception following the conditional in \
29+ the assertion statement.
30+ :type msg_or_exc: str, BaseException, optional
31+
32+ :raises check50.Failure: if msg_or_exc is a string, if msg_or_exc is not
33+ included, or if both msg_or_exc is not a string and
34+ not an exception
35+ :raises msg_or_exc: if msg_or_exc is an exception
1936 """
2037 if cond :
2138 return
22-
23- expr = ast .parse (src , mode = "eval" ).body
24- exc = classify_ast (expr ) # the exception that should be raised
25- raise exc (f"Assertion failed: { src } " )
26-
27- def classify_ast (expr ):
28- """
29- Classifies an AST expression to return an exception based on the operator.
30-
31- For instance, if the expression was read as "x not in [1,2,3]", the
32- function would return a check50.Missing error.
33-
34- :param expr: The AST expression.
35- :type expr: ast.expr
36-
37- :raises check50.Missing: if the comparison operator is one of: \
38- (ast.In, ast.NotIn)
39- :raises check50.Mismatch: if the comparison operator is one of: \
40- (ast.Eq, ast.NotEq, ast.Gt, ast.Lt, ast.GtE, \
41- ast.LtE)
42- :raises check50.Failure: if not a comparison, or otherwise
43- """
44- if isinstance (expr , ast .Compare ):
45- for op in expr .ops :
46- if isinstance (op , (ast .In , ast .NotIn )):
47- return Missing
48- elif isinstance (op , (ast .Eq , ast .NotEq , ast .Gt , ast .Lt , ast .GtE , ast .LtE )):
49- return Mismatch
50-
51- return Failure
39+
40+ if isinstance (msg_or_exc , str ):
41+ raise Failure (msg_or_exc )
42+ elif isinstance (msg_or_exc , BaseException ):
43+ raise msg_or_exc
44+ else :
45+ raise Failure (f"Assertion failure: { src } " )
0 commit comments