+def _assert_format_equal(expected: str, actual: str) -> None:
+ if actual != expected and not os.environ.get("SKIP_AST_PRINT"):
+ bdv: DebugVisitor[Any]
+ out("Expected tree:", fg="green")
+ try:
+ exp_node = black.lib2to3_parse(expected)
+ bdv = DebugVisitor()
+ list(bdv.visit(exp_node))
+ except Exception as ve:
+ err(str(ve))
+ out("Actual tree:", fg="red")
+ try:
+ exp_node = black.lib2to3_parse(actual)
+ bdv = DebugVisitor()
+ list(bdv.visit(exp_node))
+ except Exception as ve:
+ err(str(ve))
+
+ if actual != expected:
+ out(diff(expected, actual, "expected", "actual"))
+
+ assert actual == expected
+
+
+def assert_format(
+ source: str,
+ expected: str,
+ mode: black.Mode = DEFAULT_MODE,
+ *,
+ fast: bool = False,
+ minimum_version: Optional[Tuple[int, int]] = None,
+) -> None:
+ """Convenience function to check that Black formats as expected.
+
+ You can pass @minimum_version if you're passing code with newer syntax to guard
+ safety guards so they don't just crash with a SyntaxError. Please note this is
+ separate from TargetVerson Mode configuration.
+ """
+ actual = black.format_str(source, mode=mode)
+ _assert_format_equal(expected, actual)
+ # It's not useful to run safety checks if we're expecting no changes anyway. The
+ # assertion right above will raise if reality does actually make changes. This just
+ # avoids wasted CPU cycles.
+ if not fast and source != expected:
+ # Unfortunately the AST equivalence check relies on the built-in ast module
+ # being able to parse the code being formatted. This doesn't always work out
+ # when checking modern code on older versions.
+ if minimum_version is None or sys.version_info >= minimum_version:
+ black.assert_equivalent(source, actual)
+ black.assert_stable(source, actual, mode=mode)
+
+