msg = (
"Expected diff isn't equal to the actual. If you made changes to"
" expression.py and this is an anticipated difference, overwrite"
- f" tests/data/expression_skip_magic_trailing_comma.diff with {dump}"
+ " tests/data/miscellaneous/expression_skip_magic_trailing_comma.diff"
+ f" with {dump}"
)
self.assertEqual(expected, actual, msg)
self.assertFormatEqual(contents_spc, fs(contents_spc))
self.assertFormatEqual(contents_spc, fs(contents_tab))
+ def test_false_positive_symlink_output_issue_3384(self) -> None:
+ # Emulate the behavior when using the CLI (`black ./child --verbose`), which
+ # involves patching some `pathlib.Path` methods. In particular, `is_dir` is
+ # patched only on its first call: when checking if "./child" is a directory it
+ # should return True. The "./child" folder exists relative to the cwd when
+ # running from CLI, but fails when running the tests because cwd is different
+ project_root = Path(THIS_DIR / "data" / "nested_gitignore_tests")
+ working_directory = project_root / "root"
+ target_abspath = working_directory / "child"
+ target_contents = (
+ src.relative_to(working_directory) for src in target_abspath.iterdir()
+ )
+
+ def mock_n_calls(responses: List[bool]) -> Callable[[], bool]:
+ def _mocked_calls() -> bool:
+ if responses:
+ return responses.pop(0)
+ return False
+
+ return _mocked_calls
+
+ with patch("pathlib.Path.iterdir", return_value=target_contents), patch(
+ "pathlib.Path.cwd", return_value=working_directory
+ ), patch("pathlib.Path.is_dir", side_effect=mock_n_calls([True])):
+ ctx = FakeContext()
+ ctx.obj["root"] = project_root
+ report = MagicMock(verbose=True)
+ black.get_sources(
+ ctx=ctx,
+ src=("./child",),
+ quiet=False,
+ verbose=True,
+ include=DEFAULT_INCLUDE,
+ exclude=None,
+ report=report,
+ extend_exclude=None,
+ force_exclude=None,
+ stdin_filename=None,
+ )
+ assert not any(
+ mock_args[1].startswith("is a symbolic link that points outside")
+ for _, mock_args, _ in report.path_ignored.mock_calls
+ ), "A symbolic link was reported."
+ report.path_ignored.assert_called_once_with(
+ Path("child", "b.py"), "matches a .gitignore file content"
+ )
+
def test_report_verbose(self) -> None:
report = Report(verbose=True)
out_lines = []
self.assertEqual(config["exclude"], r"\.pyi?$")
self.assertEqual(config["include"], r"\.py?$")
+ def test_parse_pyproject_toml_project_metadata(self) -> None:
+ for test_toml, expected in [
+ ("only_black_pyproject.toml", ["py310"]),
+ ("only_metadata_pyproject.toml", ["py37", "py38", "py39", "py310"]),
+ ("neither_pyproject.toml", None),
+ ("both_pyproject.toml", ["py310"]),
+ ]:
+ test_toml_file = THIS_DIR / "data" / "project_metadata" / test_toml
+ config = black.parse_pyproject_toml(str(test_toml_file))
+ self.assertEqual(config.get("target_version"), expected)
+
+ def test_infer_target_version(self) -> None:
+ for version, expected in [
+ ("3.6", [TargetVersion.PY36]),
+ ("3.11.0rc1", [TargetVersion.PY311]),
+ (">=3.10", [TargetVersion.PY310, TargetVersion.PY311]),
+ (">=3.10.6", [TargetVersion.PY310, TargetVersion.PY311]),
+ ("<3.6", [TargetVersion.PY33, TargetVersion.PY34, TargetVersion.PY35]),
+ (">3.7,<3.10", [TargetVersion.PY38, TargetVersion.PY39]),
+ (">3.7,!=3.8,!=3.9", [TargetVersion.PY310, TargetVersion.PY311]),
+ (
+ "> 3.9.4, != 3.10.3",
+ [TargetVersion.PY39, TargetVersion.PY310, TargetVersion.PY311],
+ ),
+ (
+ "!=3.3,!=3.4",
+ [
+ TargetVersion.PY35,
+ TargetVersion.PY36,
+ TargetVersion.PY37,
+ TargetVersion.PY38,
+ TargetVersion.PY39,
+ TargetVersion.PY310,
+ TargetVersion.PY311,
+ ],
+ ),
+ (
+ "==3.*",
+ [
+ TargetVersion.PY33,
+ TargetVersion.PY34,
+ TargetVersion.PY35,
+ TargetVersion.PY36,
+ TargetVersion.PY37,
+ TargetVersion.PY38,
+ TargetVersion.PY39,
+ TargetVersion.PY310,
+ TargetVersion.PY311,
+ ],
+ ),
+ ("==3.8.*", [TargetVersion.PY38]),
+ (None, None),
+ ("", None),
+ ("invalid", None),
+ ("==invalid", None),
+ (">3.9,!=invalid", None),
+ ("3", None),
+ ("3.2", None),
+ ("2.7.18", None),
+ ("==2.7", None),
+ (">3.10,<3.11", None),
+ ]:
+ test_toml = {"project": {"requires-python": version}}
+ result = black.files.infer_target_version(test_toml)
+ self.assertEqual(result, expected)
+
def test_read_pyproject_toml(self) -> None:
test_toml_file = THIS_DIR / "test.toml"
fake_ctx = FakeContext()