MCPcopy
hub / github.com/pytest-dev/pytest / visit_Assert

Method visit_Assert

src/_pytest/assertion/rewrite.py:845–964  ·  src/_pytest/assertion/rewrite.py::AssertionRewriter.visit_Assert

Return the AST statements to replace the ast.Assert instance. This rewrites the test of an assertion to provide intermediate values and replace it with an if statement which raises an assertion error with a detailed explanation in case the expression is false.

(self, assert_: ast.Assert)

Source from the content-addressed store, hash-verified

843 return res, self.explanation_param(self.display(res))
844
845 def visit_Assert(self, assert_: ast.Assert) -> list[ast.stmt]:
846 class="st">"""Return the AST statements to replace the ast.Assert instance.
847
848 This rewrites the test of an assertion to provide
849 intermediate values and replace it with an if statement which
850 raises an assertion error with a detailed explanation in case
851 the expression is false.
852 class="st">"""
853 if isinstance(assert_.test, ast.Tuple) and len(assert_.test.elts) >= 1:
854 import warnings
855
856 from _pytest.warning_types import PytestAssertRewriteWarning
857
858 class="cm"># TODO: This assert should not be needed.
859 assert self.module_path is not None
860 warnings.warn_explicit(
861 PytestAssertRewriteWarning(
862 class="st">"assertion is always true, perhaps remove parentheses?"
863 ),
864 category=None,
865 filename=self.module_path,
866 lineno=assert_.lineno,
867 )
868
869 self.statements: list[ast.stmt] = []
870 self.variables: list[str] = []
871 self.variable_counter = itertools.count()
872
873 if self.enable_assertion_pass_hook:
874 self.format_variables: list[str] = []
875
876 self.stack: list[dict[str, ast.expr]] = []
877 self.expl_stmts: list[ast.stmt] = []
878 self.push_format_context()
879 class="cm"># Rewrite assert into a bunch of statements.
880 top_condition, explanation = self.visit(assert_.test)
881
882 negation = ast.UnaryOp(ast.Not(), top_condition)
883
884 if self.enable_assertion_pass_hook: class="cm"># Experimental pytest_assertion_pass hook
885 msg = self.pop_format_context(ast.Constant(explanation))
886
887 class="cm"># Failed
888 if assert_.msg:
889 assertmsg = self.helper(class="st">"_format_assertmsg", assert_.msg)
890 gluestr = class="st">"\n>assert "
891 else:
892 assertmsg = ast.Constant(class="st">"")
893 gluestr = class="st">"assert "
894 err_explanation = ast.BinOp(ast.Constant(gluestr), ast.Add(), msg)
895 err_msg = ast.BinOp(assertmsg, ast.Add(), err_explanation)
896 err_name = ast.Name(class="st">"AssertionError", ast.Load())
897 fmt = self.helper(class="st">"_format_explanation", err_msg)
898 exc = ast.Call(err_name, [fmt], [])
899 raise_ = ast.Raise(exc, None)
900 statements_fail = []
901 statements_fail.extend(self.expl_stmts)
902 statements_fail.append(raise_)

Callers

nothing calls this directly

Calls 8

push_format_contextMethod · 0.95
pop_format_contextMethod · 0.95
helperMethod · 0.95
_get_assertion_exprsFunction · 0.85
traverse_nodeFunction · 0.85
visitMethod · 0.80
appendMethod · 0.80

Tested by

no test coverage detected