diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 17951b9c15..d316c95d27 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -900,7 +900,8 @@ def blocks_since_last_update( call: Optional[list[int]] = self.get_hyperparameter( param_name="LastUpdate", netuid=netuid, block=block ) - assert call is not None + if call is None: + return None return None if len(call) == 0 else (block - int(call[uid])) def blocks_until_next_epoch( @@ -973,7 +974,9 @@ def bonds( return bond_map - def commit_reveal_enabled(self, netuid: int, block: Optional[int] = None) -> bool: + def commit_reveal_enabled( + self, netuid: int, block: Optional[int] = None + ) -> Optional[bool]: """Check if commit-reveal mechanism is enabled for a given subnet at a specific block. Parameters: @@ -981,7 +984,8 @@ def commit_reveal_enabled(self, netuid: int, block: Optional[int] = None) -> boo block: The block number to query. If `None`, queries the current chain head. Returns: - True if commit-reveal mechanism is enabled, False otherwise. + True if commit-reveal mechanism is enabled, False otherwise, or `None` if the subnet + does not exist. Notes: - @@ -990,10 +994,11 @@ def commit_reveal_enabled(self, netuid: int, block: Optional[int] = None) -> boo call: Optional[bool] = self.get_hyperparameter( param_name="CommitRevealWeightsEnabled", block=block, netuid=netuid ) - assert call is not None + if call is None: + return None return call - def difficulty(self, netuid: int, block: Optional[int] = None) -> int: + def difficulty(self, netuid: int, block: Optional[int] = None) -> Optional[int]: """Retrieves the 'Difficulty' hyperparameter for a specified subnet in the Bittensor network. This parameter determines the computational challenge required for neurons to participate in consensus and @@ -1016,7 +1021,8 @@ def difficulty(self, netuid: int, block: Optional[int] = None) -> int: call: Optional[int] = self.get_hyperparameter( param_name="Difficulty", netuid=netuid, block=block ) - assert call is not None + if call is None: + return None return int(call) def does_hotkey_exist(self, hotkey_ss58: str, block: Optional[int] = None) -> bool: diff --git a/mypy.ini b/mypy.ini index d38bdc7172..054851282e 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,6 +1,13 @@ [mypy] ignore_missing_imports = True ignore_errors = True +follow_imports_for_stubs = True + +[mypy-numpy.*] +follow_imports = skip + +[mypy-numpy] +follow_imports = skip [mypy-*.axon.*] ignore_errors = False diff --git a/tests/unit_tests/test_subtensor.py b/tests/unit_tests/test_subtensor.py index 4407381deb..c02cc3e8ba 100644 --- a/tests/unit_tests/test_subtensor.py +++ b/tests/unit_tests/test_subtensor.py @@ -1989,6 +1989,27 @@ def test_difficulty_success(subtensor, mocker): assert result == int(mocked_get_hyperparameter.return_value) +@pytest.mark.parametrize( + "getter,param_name,extra_kwargs", + [ + ("difficulty", "Difficulty", {}), + ("commit_reveal_enabled", "CommitRevealWeightsEnabled", {}), + ("blocks_since_last_update", "LastUpdate", {"uid": 0}), + ], +) +def test_subnet_getter_returns_none_when_subnet_missing( + subtensor, mocker, getter, param_name, extra_kwargs +): + """When the subnet/uid is absent, get_hyperparameter returns None; the getter must + return None (honouring its docstring) instead of raising AssertionError.""" + mocker.patch.object(subtensor, "get_hyperparameter", return_value=None) + mocker.patch.object(subtensor, "get_current_block", return_value=1) + + result = getattr(subtensor, getter)(netuid=999, block=1, **extra_kwargs) + + assert result is None + + def test_recycle_success(subtensor, mocker): """Tests recycle method with successfully result.""" # Preps