diff --git a/CHANGELOG.md b/CHANGELOG.md index 670652c4..3955961b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `cloudsmith credential-helper install` and `uninstall` no longer rewrite a config file when they make no change to its data. Previously, the CLI always rewrote a file in a different formatting, such as the tab-indented `config.json` that Docker writes. The command also made a `.bak` copy and reported changes that it did not make. - When the API host name or the proxy host name does not exist, for example because of a typo in `--api-host`, commands now fail immediately. Previously, they retried for approximately 62 seconds without output. The CLI still retries a DNS failure that the operating system reports as temporary. - When the CLI waits before it retries a failed connection or a 5xx response, it now writes `Request failed: retrying in N second(s) ...` to stderr. Previously, it waited without output. +- `cloudsmith check rates` no longer stops with `TypeError` when the API does not give a value for an interval, limit, remaining count, reset time or throttled status. The command now shows `None` for that value. ## [1.30.0] - 2026-10-22 diff --git a/cloudsmith_cli/core/ratelimits.py b/cloudsmith_cli/core/ratelimits.py index 78ac9722..38a5b892 100644 --- a/cloudsmith_cli/core/ratelimits.py +++ b/cloudsmith_cli/core/ratelimits.py @@ -26,17 +26,17 @@ def from_dict(cls, data): """Create RateLimitsInfo from a dictionary.""" info = RateLimitsInfo() - if "interval" in data: + if data.get("interval") is not None: info.interval = float(data["interval"]) - if "limit" in data: + if data.get("limit") is not None: info.limit = int(data["limit"]) - if "remaining" in data: + if data.get("remaining") is not None: info.remaining = int(data["remaining"]) - if "reset" in data: + if data.get("reset") is not None: info.reset = datetime.datetime.fromtimestamp( int(data["reset"]), tz=datetime.UTC ) - if "throttled" in data: + if data.get("throttled") is not None: info.throttled = bool(data["throttled"]) else: info.throttled = info.remaining == 0 diff --git a/cloudsmith_cli/core/tests/test_ratelimits.py b/cloudsmith_cli/core/tests/test_ratelimits.py new file mode 100644 index 00000000..ec62a9dc --- /dev/null +++ b/cloudsmith_cli/core/tests/test_ratelimits.py @@ -0,0 +1,19 @@ +from ..ratelimits import RateLimitsInfo + + +def test_from_dict_treats_null_values_as_missing(): + info = RateLimitsInfo.from_dict( + { + "interval": None, + "limit": None, + "remaining": None, + "reset": None, + "throttled": None, + } + ) + + assert info.interval is None + assert info.limit is None + assert info.remaining is None + assert info.reset is None + assert info.throttled is False