11from check50 import Failure , Missing , Mismatch
2+ import re
3+ import inspect
24
35def check50_assert (src , msg_or_exc = None , cond_type = "unknown" , left = None , right = None , context = None ):
46 """
@@ -50,16 +52,18 @@ def check50_assert(src, msg_or_exc=None, cond_type="unknown", left=None, right=N
5052 :raises check50.Failure: If msg_or_exc is a string, or if cond_type is \
5153 unrecognized.
5254 """
55+ # Grab the global and local variables as of now
56+ caller_frame = inspect .currentframe ().f_back
57+ caller_globals = caller_frame .f_globals
58+ caller_locals = caller_frame .f_locals
59+
5360 # Evaluate all variables and functions within the context dict and generate
5461 # a string of these values
5562 context_str = None
5663 if context or (left and right ):
57- import inspect
5864 for expr_str in context :
5965 try :
60- # Grab the global and local variables as of now
61- caller_frame = inspect .currentframe ().f_back
62- context [expr_str ] = eval (expr_str , caller_frame .f_globals , caller_frame .f_locals )
66+ context [expr_str ] = eval (expr_str , caller_globals , caller_locals )
6367 except Exception as e :
6468 context [expr_str ] = f"[error evaluating: { e } ]"
6569
@@ -70,7 +74,12 @@ def check50_assert(src, msg_or_exc=None, cond_type="unknown", left=None, right=N
7074 # evaluate the conditional by substituting the function calls/vars with
7175 # their results
7276 eval_src , eval_context = substitute_expressions (src , context )
73- cond = eval (eval_src , {}, eval_context )
77+
78+ # Merge globals with expression context for evaluation
79+ eval_globals = caller_globals .copy ()
80+ eval_globals .update (eval_context )
81+
82+ cond = eval (eval_src , eval_globals , eval_context )
7483
7584 # Finally, quit if the condition evaluated to True.
7685 if cond :
@@ -125,7 +134,13 @@ def substitute_expressions(src: str, context: dict) -> tuple[str, dict]:
125134
126135 for i , expr in enumerate (sorted (context .keys (), key = len , reverse = True )):
127136 placeholder = f"__expr{ i } "
128- new_src = new_src .replace (expr , placeholder )
129- new_context [placeholder ] = context [expr ]
137+
138+ # Use regex to replace only full matches of expr
139+ # Escape expr if it has special characters (like function calls)
140+ pattern = re .escape (expr )
141+ new_src , count = re .subn (rf'\b{ pattern } \b' , placeholder , new_src )
142+
143+ if count > 0 :
144+ new_context [placeholder ] = context [expr ]
130145
131146 return new_src , new_context
0 commit comments