diff --git a/bittensor_cli/src/commands/weights.py b/bittensor_cli/src/commands/weights.py index cc493c131..5f94b5179 100644 --- a/bittensor_cli/src/commands/weights.py +++ b/bittensor_cli/src/commands/weights.py @@ -2,7 +2,7 @@ import json import os from datetime import datetime, timedelta -from typing import TYPE_CHECKING, Optional, Sequence +from typing import TYPE_CHECKING, Iterable, Optional, Sequence from bittensor_wallet import Wallet from async_substrate_interface.errors import SubstrateRequestException @@ -29,6 +29,28 @@ # helpers and extrinsics +def _build_reveal_retry_command( + netuid: int, + uids: Iterable[int], + weights: Iterable[float], + salt: Iterable[int], +) -> str: + """Build a copy-pasteable `btcli weights reveal` command for the + retry-after-commit prompt, with comma-separated list args matching + `parse_to_list` in cli.py. + """ + uids_csv = ",".join(str(u) for u in uids) + weights_csv = ",".join(str(w) for w in weights) + salt_csv = ",".join(str(s) for s in salt) + return ( + f"btcli weights reveal " + f"--netuid {netuid} " + f"--uids {uids_csv} " + f"--weights {weights_csv} " + f"--salt {salt_csv}" + ) + + class SetWeightsExtrinsic: def __init__( self, @@ -176,7 +198,12 @@ async def _commit_reveal( if commit_success: current_time = datetime.now().astimezone().replace(microsecond=0) reveal_time = (current_time + timedelta(seconds=interval)).isoformat() - cli_retry_cmd = f"--netuid {self.netuid} --uids {weight_uids} --weights {self.weights} --reveal-using-salt {self.salt}" + cli_retry_cmd = _build_reveal_retry_command( + netuid=self.netuid, + uids=weight_uids, + weights=self.weights, + salt=self.salt, + ) # Print params to screen and notify user this is a blocking operation print_success("Weights hash committed to chain") console.print( diff --git a/tests/unit_tests/test_weights_retry_command.py b/tests/unit_tests/test_weights_retry_command.py new file mode 100644 index 000000000..b12448e8b --- /dev/null +++ b/tests/unit_tests/test_weights_retry_command.py @@ -0,0 +1,60 @@ +from bittensor_cli.src.commands.weights import _build_reveal_retry_command + + +class _NumpyArrayLikeRepr: + """Iterable whose ``str()`` mimics ``numpy.ndarray.__str__`` (space-separated, + bracketed, no commas), so we can pin the regression where the historical + code formatted ``self.weights`` via ``str(...)`` and emitted ``[0.5 0.3 0.2]`` + into the retry command. The helper iterates element-by-element, so a plain + iterable is enough to exercise the same code path without pulling numpy in + as a unit-test dependency. + """ + + def __init__(self, values): + self._values = list(values) + + def __iter__(self): + return iter(self._values) + + def __str__(self): + return "[" + " ".join(str(v) for v in self._values) + "]" + + +def test_builds_runnable_btcli_weights_reveal_command(): + """The retry message printed after `btcli weights commit` must be a + command the user can copy-paste. That means: + + - Starts with `btcli weights reveal` so it is self-contained. + - List args are comma-separated (what cli.parse_to_list expects), not + Python list repr or numpy array repr. + - The flag is `--salt`, which is the one defined on `weights reveal`. + The historical name `--reveal-using-salt` is not a real flag. + """ + cmd = _build_reveal_retry_command( + netuid=1, + uids=[1, 2, 3], + weights=_NumpyArrayLikeRepr([0.5, 0.3, 0.2]), + salt=[42, 17, 8, 234, 113, 250, 91, 180], + ) + + assert cmd.startswith("btcli weights reveal ") + assert "--netuid 1" in cmd + assert "--uids 1,2,3" in cmd + assert "--weights 0.5,0.3,0.2" in cmd + assert "--salt 42,17,8,234,113,250,91,180" in cmd + + # Regressions: never print Python list / numpy repr or the wrong flag. + assert "[" not in cmd and "]" not in cmd + assert "--reveal-using-salt" not in cmd + + +def test_handles_int_uids_int_weights_and_list_salt(): + # _set_weights_without_commit_reveal-style inputs should also format cleanly. + cmd = _build_reveal_retry_command( + netuid=7, + uids=[0], + weights=[1.0], + salt=[0], + ) + + assert cmd == ("btcli weights reveal --netuid 7 --uids 0 --weights 1.0 --salt 0")