From 597328b1ae1ad89c609dcf4f7f9821bc0846c154 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:30:29 +0000 Subject: [PATCH 1/3] Initial plan From 680989a8e90b334e930b64912b3d933183637865 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Apr 2026 19:33:17 +0000 Subject: [PATCH 2/3] Add --skip-pylint to apistub cmds when --md is passed, add tests Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-python/sessions/e76821d9-4504-4627-9352-c4538aa79e9f Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> --- eng/tools/azure-sdk-tools/azpysdk/apistub.py | 2 + .../azure-sdk-tools/tests/test_apistub.py | 70 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/eng/tools/azure-sdk-tools/azpysdk/apistub.py b/eng/tools/azure-sdk-tools/azpysdk/apistub.py index 0a023dd7c4ba..c2a1d077c084 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/apistub.py +++ b/eng/tools/azure-sdk-tools/azpysdk/apistub.py @@ -148,6 +148,8 @@ def run(self, args: argparse.Namespace) -> int: cmds.extend(["--out-path", out_token_path]) if cross_language_mapping_path: cmds.extend(["--mapping-path", cross_language_mapping_path]) + if getattr(args, "generate_md", False): + cmds.append("--skip-pylint") logger.info("Running apistub {}.".format(cmds)) diff --git a/eng/tools/azure-sdk-tools/tests/test_apistub.py b/eng/tools/azure-sdk-tools/tests/test_apistub.py index 209183bf89e8..138520a90e2e 100644 --- a/eng/tools/azure-sdk-tools/tests/test_apistub.py +++ b/eng/tools/azure-sdk-tools/tests/test_apistub.py @@ -187,3 +187,73 @@ def fake_pwsh(cmd, **kwargs): assert cmds[out_idx + 1] == os.path.abspath(staging) assert os.path.exists(os.path.join(staging, "api.md")) assert os.path.exists(os.path.join(staging, "azure-core_python.json")) + + @patch( + "azpysdk.apistub.REPO_ROOT", os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..", "..")) + ) + @patch("azpysdk.apistub.PYTHON_VERSION_LIMIT", (99, 99)) + @patch("azpysdk.apistub.get_cross_language_mapping_path", return_value=None) + @patch("azpysdk.apistub.get_package_wheel_path", return_value="/fake/pkg.whl") + @patch("azpysdk.apistub.create_package_and_install") + @patch("azpysdk.apistub.install_into_venv") + @patch("azpysdk.apistub.set_envvar_defaults") + def test_generate_md_adds_skip_pylint(self, _env, _install, _create, _get_whl, _get_mapping, tmp_path, monkeypatch): + """When --md is passed (generate_md=True), --skip-pylint must be in the cmds.""" + monkeypatch.chdir(os.getcwd()) + stub = apistub() + staging = str(tmp_path / "staging") + os.makedirs(staging, exist_ok=True) + fake_parsed = MagicMock() + fake_parsed.folder = str(tmp_path) + fake_parsed.name = "azure-core" + + captured_cmds = [] + + def fake_apistub_run(exe, cmds, **kwargs): + captured_cmds.append(cmds) + + with patch.object(stub, "get_targeted_directories", return_value=[fake_parsed]), patch.object( + stub, "get_executable", return_value=(sys.executable, staging) + ), patch.object(stub, "install_dev_reqs"), patch.object(stub, "pip_freeze"), patch.object( + stub, "run_venv_command", side_effect=fake_apistub_run + ): + stub.run(self._make_args(generate_md=True)) + + assert len(captured_cmds) == 1 + assert "--skip-pylint" in captured_cmds[0] + + @patch( + "azpysdk.apistub.REPO_ROOT", os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..", "..")) + ) + @patch("azpysdk.apistub.PYTHON_VERSION_LIMIT", (99, 99)) + @patch("azpysdk.apistub.get_cross_language_mapping_path", return_value=None) + @patch("azpysdk.apistub.get_package_wheel_path", return_value="/fake/pkg.whl") + @patch("azpysdk.apistub.create_package_and_install") + @patch("azpysdk.apistub.install_into_venv") + @patch("azpysdk.apistub.set_envvar_defaults") + def test_no_generate_md_omits_skip_pylint( + self, _env, _install, _create, _get_whl, _get_mapping, tmp_path, monkeypatch + ): + """When --md is not passed (generate_md=False), --skip-pylint must not be in the cmds.""" + monkeypatch.chdir(os.getcwd()) + stub = apistub() + staging = str(tmp_path / "staging") + os.makedirs(staging, exist_ok=True) + fake_parsed = MagicMock() + fake_parsed.folder = str(tmp_path) + fake_parsed.name = "azure-core" + + captured_cmds = [] + + def fake_apistub_run(exe, cmds, **kwargs): + captured_cmds.append(cmds) + + with patch.object(stub, "get_targeted_directories", return_value=[fake_parsed]), patch.object( + stub, "get_executable", return_value=(sys.executable, staging) + ), patch.object(stub, "install_dev_reqs"), patch.object(stub, "pip_freeze"), patch.object( + stub, "run_venv_command", side_effect=fake_apistub_run + ): + stub.run(self._make_args(generate_md=False)) + + assert len(captured_cmds) == 1 + assert "--skip-pylint" not in captured_cmds[0] From 6c070ca67ddfeef06b62fa2bddd540e04a1650a6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 6 Apr 2026 20:02:52 +0000 Subject: [PATCH 3/3] Make test_generate_md_adds_skip_pylint hermetic by patching subprocess.run and creating token JSON Agent-Logs-Url: https://github.com/Azure/azure-sdk-for-python/sessions/6aaa6910-2dab-4716-a109-89bc72d2c96e Co-authored-by: swathipil <76007337+swathipil@users.noreply.github.com> --- eng/tools/azure-sdk-tools/tests/test_apistub.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/eng/tools/azure-sdk-tools/tests/test_apistub.py b/eng/tools/azure-sdk-tools/tests/test_apistub.py index 138520a90e2e..85a60a407794 100644 --- a/eng/tools/azure-sdk-tools/tests/test_apistub.py +++ b/eng/tools/azure-sdk-tools/tests/test_apistub.py @@ -211,11 +211,21 @@ def test_generate_md_adds_skip_pylint(self, _env, _install, _create, _get_whl, _ def fake_apistub_run(exe, cmds, **kwargs): captured_cmds.append(cmds) + # Create the token JSON so the markdown generation branch can proceed + out_idx = cmds.index("--out-path") + out_dir = cmds[out_idx + 1] + os.makedirs(out_dir, exist_ok=True) + open(os.path.join(out_dir, "azure-core_python.json"), "w").close() + + def fake_pwsh(cmd, **kwargs): + return MagicMock(returncode=0, stdout=None) with patch.object(stub, "get_targeted_directories", return_value=[fake_parsed]), patch.object( stub, "get_executable", return_value=(sys.executable, staging) ), patch.object(stub, "install_dev_reqs"), patch.object(stub, "pip_freeze"), patch.object( stub, "run_venv_command", side_effect=fake_apistub_run + ), patch( + "azpysdk.apistub.run", side_effect=fake_pwsh ): stub.run(self._make_args(generate_md=True))