From 234ac174f7916abefd5aa34e262141a85e30f3c3 Mon Sep 17 00:00:00 2001 From: yliao Date: Fri, 22 May 2026 03:58:42 +0000 Subject: [PATCH 01/14] updated scripts and README to use kubernetes.aio --- setup-asyncio.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup-asyncio.py b/setup-asyncio.py index aef2b09be7..ecad9d520a 100644 --- a/setup-asyncio.py +++ b/setup-asyncio.py @@ -16,9 +16,9 @@ # Do not edit these constants. They will be updated automatically # by scripts/update-client.sh. -CLIENT_VERSION = "36.0.2" +CLIENT_VERSION = "36.0.0+snapshot" PACKAGE_NAME = "kubernetes.aio" -DEVELOPMENT_STATUS = "5 - Production/Stable" +DEVELOPMENT_STATUS = "3 - Alpha" # To install the library, run the following # From 386bf0355d0f3df5a9aa260a68f1c3ef8cf62319 Mon Sep 17 00:00:00 2001 From: yliao Date: Fri, 29 May 2026 20:12:34 +0000 Subject: [PATCH 02/14] apply hotfix for bearer-token fallback in Configuration.auth_settings --- scripts/apply-hotfixes.sh | 11 +++++++++++ scripts/release.sh | 7 ++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/apply-hotfixes.sh b/scripts/apply-hotfixes.sh index 56cffde1fc..fde634e63c 100755 --- a/scripts/apply-hotfixes.sh +++ b/scripts/apply-hotfixes.sh @@ -89,4 +89,15 @@ else exit 1 fi; +# Patching commit for bearer-token fallback in Configuration.auth_settings +git cherry-pick -n 5621a4c2cf5cc278e8f45ce759ce44c057f1dbe2 +if [ $? -eq 0 ] +then + echo Successfully patched changes for bearer-token fallback in Configuration.auth_settings +else + echo Failed to patch changes for bearer-token fallback in Configuration.auth_settings + git restore --staged . + exit 1 +fi; + git commit -m "Apply hotfixes" diff --git a/scripts/release.sh b/scripts/release.sh index adb8e4310b..4a6be4a0e2 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -207,6 +207,10 @@ git diff-index --quiet --cached HEAD || git commit -am "update changelog" # Re-generate the client scripts/update-client.sh + +# Re-generate the asyncio client +scripts/update-client-asyncio.sh + # Apply hotfixes rm -r kubernetes/test/ git add . @@ -223,9 +227,6 @@ if [[ -n "$(git diff kubernetes/client/api/custom_objects_api.py)" ]]; then git commit -m "generated client change for custom_objects" fi -# Re-generate the asyncio client -scripts/update-client-asyncio.sh - # Check if there is any API change, then commit git add kubernetes/docs kubernetes/client/api/ kubernetes/client/models/ kubernetes/swagger.json.unprocessed scripts/swagger.json git add kubernetes/aio/docs kubernetes/aio/client/api/ kubernetes/aio/client/models/ kubernetes/aio/swagger.json.unprocessed From 73bfff76edb13e65929918bf574b7ae22bc19ba4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 03:02:21 +0000 Subject: [PATCH 03/14] Bump actions/setup-python from 6.2.0 to 6.3.0 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6.2.0 to 6.3.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/a309ff8b426b58ec0e2a45f0f869d46889d02405...ece7cb06caefa5fff74198d8649806c4678c61a1) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/e2e-master.yaml | 2 +- .github/workflows/e2e-release-35.0.yaml | 2 +- .github/workflows/test.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e-master.yaml b/.github/workflows/e2e-master.yaml index caa24a62b6..ca2b1ff41d 100644 --- a/.github/workflows/e2e-master.yaml +++ b/.github/workflows/e2e-master.yaml @@ -30,7 +30,7 @@ jobs: # as we sync with Kubernetes upstream config: .github/workflows/kind-configs/cluster-1.35.yaml - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/.github/workflows/e2e-release-35.0.yaml b/.github/workflows/e2e-release-35.0.yaml index 44c0fc5862..e1fc723732 100644 --- a/.github/workflows/e2e-release-35.0.yaml +++ b/.github/workflows/e2e-release-35.0.yaml @@ -30,7 +30,7 @@ jobs: # as we sync with Kubernetes upstream config: .github/workflows/kind-configs/cluster-1.35.yaml - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index cbeeebbcee..c24b975d52 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -17,7 +17,7 @@ jobs: with: submodules: true - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 with: python-version: ${{ matrix.python-version }} - name: Install dependencies From c887428d3a52c5b648badcc51f8bee3a1de53e64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 03:02:15 +0000 Subject: [PATCH 04/14] Bump actions/checkout from 6.0.2 to 7.0.0 Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 7.0.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/deploy-wiki.yaml | 2 +- .github/workflows/e2e-master.yaml | 2 +- .github/workflows/e2e-release-35.0.yaml | 2 +- .github/workflows/test.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy-wiki.yaml b/.github/workflows/deploy-wiki.yaml index b7d9464683..88b7150132 100644 --- a/.github/workflows/deploy-wiki.yaml +++ b/.github/workflows/deploy-wiki.yaml @@ -11,7 +11,7 @@ jobs: deploy-wiki: runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: submodules: true - name: Install rsync diff --git a/.github/workflows/e2e-master.yaml b/.github/workflows/e2e-master.yaml index ca2b1ff41d..0a5850d658 100644 --- a/.github/workflows/e2e-master.yaml +++ b/.github/workflows/e2e-master.yaml @@ -15,7 +15,7 @@ jobs: matrix: python-version: ["3.10", "3.11", "3.12"] steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: submodules: true - name: Create Kind Cluster diff --git a/.github/workflows/e2e-release-35.0.yaml b/.github/workflows/e2e-release-35.0.yaml index e1fc723732..94e068e9a4 100644 --- a/.github/workflows/e2e-release-35.0.yaml +++ b/.github/workflows/e2e-release-35.0.yaml @@ -15,7 +15,7 @@ jobs: matrix: python-version: [3.10, 3.11, 3.12] steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: submodules: true - name: Create Kind Cluster diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c24b975d52..fa4a3c60bd 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -13,7 +13,7 @@ jobs: use_coverage: 'coverage' steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: submodules: true - name: Set up Python ${{ matrix.python-version }} From 1a6079eecb071daa2b3f0e2b575264b699f8a1e7 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 20 Jun 2026 15:32:17 -0400 Subject: [PATCH 05/14] Fix Watch follow parameter detection The generated client now emits parameter names and types on separate lines. Watch still searches for the old combined line, so it sends watch=True to pod log methods and the generated client rejects the unexpected keyword. Match the current generated format and update the fixture that covers log streaming. --- kubernetes/base/watch/watch.py | 2 +- kubernetes/base/watch/watch_test.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/kubernetes/base/watch/watch.py b/kubernetes/base/watch/watch.py index 0e39e191a9..2eda0b34f4 100644 --- a/kubernetes/base/watch/watch.py +++ b/kubernetes/base/watch/watch.py @@ -19,7 +19,7 @@ from kubernetes import client PYDOC_RETURN_LABEL = ":rtype:" -PYDOC_FOLLOW_PARAM = ":param bool follow:" +PYDOC_FOLLOW_PARAM = ":param follow:" # Removing this suffix from return type name should give us event's object # type. e.g., if list_namespaces() returns "NamespaceList" type, diff --git a/kubernetes/base/watch/watch_test.py b/kubernetes/base/watch/watch_test.py index 07869095b6..00f855b0d0 100644 --- a/kubernetes/base/watch/watch_test.py +++ b/kubernetes/base/watch/watch_test.py @@ -204,7 +204,8 @@ def test_watch_for_follow(self): fake_api = Mock() fake_api.read_namespaced_pod_log = Mock(return_value=fake_resp) - fake_api.read_namespaced_pod_log.__doc__ = ':param bool follow:\n:rtype: str' + fake_api.read_namespaced_pod_log.__doc__ = ( + ':param follow:\n:type follow: bool\n:rtype: str') w = Watch() count = 1 From 675392c2f8e38afaa15a8c355bbb1cc312bc381a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 03:02:19 +0000 Subject: [PATCH 06/14] Bump codecov/codecov-action from 6.0.1 to 7.0.0 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 6.0.1 to 7.0.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/e79a6962e0d4c0c17b229090214935d2e33f8354...fb8b3582c8e4def4969c97caa2f19720cb33a72f) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index fa4a3c60bd..e7e0040c0d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -45,7 +45,7 @@ jobs: - name: Upload coverage to Codecov if: "matrix.use_coverage" - uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f with: fail_ci_if_error: false verbose: true From bb887bba3840321c496509876ac924edb6570cc7 Mon Sep 17 00:00:00 2001 From: Artem Muterko Date: Fri, 3 Jul 2026 15:35:27 +0200 Subject: [PATCH 07/14] Fix leader election worker thread not running as daemon Signed-off-by: Artem Muterko --- .../base/leaderelection/leaderelection.py | 3 +- .../leaderelection/leaderelection_test.py | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/kubernetes/base/leaderelection/leaderelection.py b/kubernetes/base/leaderelection/leaderelection.py index 4fff8d0790..ea20f0a570 100644 --- a/kubernetes/base/leaderelection/leaderelection.py +++ b/kubernetes/base/leaderelection/leaderelection.py @@ -55,8 +55,7 @@ def run(self): logger.info("{} successfully acquired lease".format(self.election_config.lock.identity)) # Start leading and call OnStartedLeading() - threading.daemon = True - threading.Thread(target=self.election_config.onstarted_leading).start() + threading.Thread(target=self.election_config.onstarted_leading, daemon=True).start() self.renew_loop() diff --git a/kubernetes/base/leaderelection/leaderelection_test.py b/kubernetes/base/leaderelection/leaderelection_test.py index 9fb6d9bcf4..0cbcf00c88 100644 --- a/kubernetes/base/leaderelection/leaderelection_test.py +++ b/kubernetes/base/leaderelection/leaderelection_test.py @@ -22,6 +22,7 @@ import json import time import pytest +from unittest.mock import patch thread_lock = threading.RLock() @@ -194,6 +195,33 @@ def on_stopped_leading(): self.assert_history(leadership_history, ["get leadership", "start leading", "stop leading"]) + def test_onstarted_leading_runs_in_daemon_thread(self): + captured = {} + real_thread = threading.Thread + + def record_thread(*args, **kwargs): + thread = real_thread(*args, **kwargs) + captured["daemon"] = thread.daemon + return thread + + started = threading.Event() + + mock_lock = MockResourceLock("mock", "mock_namespace", "mock", thread_lock, + lambda: None, lambda: None, lambda: None, None) + mock_lock.renew_count_max = 1 + + config = electionconfig.Config(lock=mock_lock, lease_duration=2, + renew_deadline=1.5, retry_period=1, + onstarted_leading=started.set, + onstopped_leading=lambda: None) + + with patch.object(leaderelection.threading, "Thread", new=record_thread): + leaderelection.LeaderElection(config).run() + + self.assertTrue(started.wait(1), "onstarted_leading callback did not run") + self.assertIn("daemon", captured) + self.assertTrue(captured["daemon"]) + def assert_history(self, history, expected): self.assertIsNotNone(expected) self.assertIsNotNone(history) From f72f9217af74dfa790ce5a3fe714659a5ef3ce29 Mon Sep 17 00:00:00 2001 From: Artem Muterko Date: Fri, 3 Jul 2026 15:35:27 +0200 Subject: [PATCH 08/14] Fix readline_channel crash and None return on default timeout Signed-off-by: Artem Muterko --- kubernetes/base/stream/ws_client.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kubernetes/base/stream/ws_client.py b/kubernetes/base/stream/ws_client.py index 3031e01560..ffdd877ef4 100644 --- a/kubernetes/base/stream/ws_client.py +++ b/kubernetes/base/stream/ws_client.py @@ -128,6 +128,7 @@ def readline_channel(self, channel, timeout=None): return b"" if self.binary else "" self.update(timeout=(timeout - time.time() + start)) + return b"" if self.binary else "" def write_channel(self, channel, data): """Write data to a channel.""" @@ -216,11 +217,15 @@ def update(self, timeout=0): if hasattr(select, "poll"): poll = select.poll() poll.register(self.sock.sock, select.POLLIN) - if timeout is not None: + if timeout is not None and timeout != float("inf"): timeout *= 1_000 # poll method uses milliseconds as the time unit + else: + timeout = None r = poll.poll(timeout) poll.unregister(self.sock.sock) else: + if timeout == float("inf"): + timeout = None r, _, _ = select.select( (self.sock.sock, ), (), (), timeout) From 33f9bf5485ccef6266d2738fae8316fdc6c9abfb Mon Sep 17 00:00:00 2001 From: Artem Muterko Date: Fri, 3 Jul 2026 16:30:36 +0200 Subject: [PATCH 09/14] Add tests for readline_channel default and expired timeout handling Signed-off-by: Artem Muterko --- kubernetes/base/stream/ws_client_test.py | 42 ++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/kubernetes/base/stream/ws_client_test.py b/kubernetes/base/stream/ws_client_test.py index 2785a831fb..80f9c692c5 100644 --- a/kubernetes/base/stream/ws_client_test.py +++ b/kubernetes/base/stream/ws_client_test.py @@ -342,6 +342,48 @@ def test_peek_channel_closed_with_leftover_data(self): self.assertEqual(data3, "") mock_update.assert_not_called() + def test_update_infinite_timeout_polls_without_overflow(self): + """Verify update maps an infinite (default) timeout to a blocking poll instead of overflowing""" + with patch.object(ws_client_module, 'create_websocket') as mock_create, \ + patch('select.poll') as mock_poll: + mock_poll.return_value.poll.return_value = [] + mock_ws = MagicMock() + mock_ws.subprotocol = V5_CHANNEL_PROTOCOL + mock_ws.connected = True + mock_ws.sock.fileno.return_value = 10 + mock_create.return_value = mock_ws + + client = WSClient(self.config_mock, "ws://test", headers=None, capture_all=True) + client.update(timeout=float("inf")) + + mock_poll.return_value.poll.assert_called_once_with(None) + + def test_readline_channel_returns_empty_string_on_expired_timeout(self): + """Verify readline_channel returns '' (not None) when a finite timeout expires""" + with patch.object(ws_client_module, 'create_websocket') as mock_create: + mock_ws = MagicMock() + mock_ws.subprotocol = V5_CHANNEL_PROTOCOL + mock_ws.connected = True + mock_create.return_value = mock_ws + + client = WSClient(self.config_mock, "ws://test", headers=None, capture_all=True, binary=False) + with patch.object(client, 'update'): + line = client.readline_channel(1, timeout=0.01) + self.assertEqual(line, "") + + def test_readline_channel_returns_empty_bytes_on_expired_timeout(self): + """Verify readline_channel returns b'' (not None) when a finite timeout expires in binary mode""" + with patch.object(ws_client_module, 'create_websocket') as mock_create: + mock_ws = MagicMock() + mock_ws.subprotocol = V5_CHANNEL_PROTOCOL + mock_ws.connected = True + mock_create.return_value = mock_ws + + client = WSClient(self.config_mock, "ws://test", headers=None, capture_all=True, binary=True) + with patch.object(client, 'update'): + line = client.readline_channel(1, timeout=0.01) + self.assertEqual(line, b"") + @pytest.fixture(scope="module") From 14ae4f0a0fe891419c59504311e3749716c60d28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 04:15:05 +0000 Subject: [PATCH 10/14] Update coverage requirement from >=4.0.3 to >=7.14.1 Updates the requirements on [coverage](https://github.com/coveragepy/coveragepy) to permit the latest version. - [Release notes](https://github.com/coveragepy/coveragepy/releases) - [Changelog](https://github.com/coveragepy/coveragepy/blob/main/CHANGES.rst) - [Commits](https://github.com/coveragepy/coveragepy/compare/coverage-4.0.3...7.14.1) --- updated-dependencies: - dependency-name: coverage dependency-version: 7.14.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-requirements.txt b/test-requirements.txt index d6ebedc182..bda4bc35fd 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,4 @@ -coverage>=4.0.3 +coverage>=7.14.1 nose>=1.3.7 pytest pytest-cov From 63dee8dad72fd77a82d6f03d49a88ee4df1e2694 Mon Sep 17 00:00:00 2001 From: Artem Muterko Date: Fri, 3 Jul 2026 15:35:27 +0200 Subject: [PATCH 11/14] Fix format_quantity precision and emit canonical decimal output Signed-off-by: Artem Muterko --- kubernetes/e2e_test/test_utils.py | 24 +++++++++++++++++++++--- kubernetes/utils/quantity.py | 6 +++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/kubernetes/e2e_test/test_utils.py b/kubernetes/e2e_test/test_utils.py index 433089efa1..a1789ae7fe 100644 --- a/kubernetes/e2e_test/test_utils.py +++ b/kubernetes/e2e_test/test_utils.py @@ -757,9 +757,11 @@ def test_format_quantity(self): "0.3Gi") # == base 1000 == - self.assertEqual(quantity.format_quantity(Decimal(0.000_000_001), "n"), "1n") - self.assertEqual(quantity.format_quantity(Decimal(0.000_001), "u"), "1u") - self.assertEqual(quantity.format_quantity(Decimal(0.001), "m"), "1m") + # Exact Decimals: float-derived Decimals (e.g. Decimal(0.001)) carry binary + # rounding error that the precise scaling surfaces into the output. + self.assertEqual(quantity.format_quantity(Decimal("0.000000001"), "n"), "1n") + self.assertEqual(quantity.format_quantity(Decimal("0.000001"), "u"), "1u") + self.assertEqual(quantity.format_quantity(Decimal("0.001"), "m"), "1m") self.assertEqual(quantity.format_quantity(Decimal(1_000), "k"), "1k") self.assertEqual(quantity.format_quantity(Decimal(1_000_000), "M"), "1M") self.assertEqual(quantity.format_quantity(Decimal(1_000_000_000), "G"), "1G") @@ -781,3 +783,19 @@ def test_format_quantity(self): ), "333k", ) + + # == milli/micro/nano keep full precision in canonical decimal form == + # Regression: these divided by a float-built Decimal and rendered in + # scientific notation (e.g. "499.9999999999999895916591441m", "1E+9"). + self.assertEqual(quantity.format_quantity(Decimal("0.5"), "m"), "500m") + self.assertEqual(quantity.format_quantity(Decimal("0.5"), "u"), "500000u") + self.assertEqual(quantity.format_quantity(Decimal("0.5"), "n"), "500000000n") + self.assertEqual(quantity.format_quantity(Decimal("1"), "m"), "1000m") + self.assertEqual(quantity.format_quantity(Decimal("1"), "n"), "1000000000n") + + # == quantize=Decimal(0) is honored, not treated as falsy == + self.assertEqual(quantity.format_quantity(Decimal("0.5006"), "m"), "500.6m") + self.assertEqual( + quantity.format_quantity(Decimal("0.5006"), "m", quantize=Decimal(0)), + "501m", + ) diff --git a/kubernetes/utils/quantity.py b/kubernetes/utils/quantity.py index 484f347193..a45026dbe6 100644 --- a/kubernetes/utils/quantity.py +++ b/kubernetes/utils/quantity.py @@ -136,7 +136,7 @@ def format_quantity(quantity_value, suffix, quantize=None) -> str: if suffix[0] not in _EXPONENTS: raise ValueError(f"{quantity_value} has unknown suffix") - different_scale = quantity_value / Decimal(base ** _EXPONENTS[suffix[0]]) - if quantize: + different_scale = quantity_value / (Decimal(base) ** _EXPONENTS[suffix[0]]) + if quantize is not None: different_scale = different_scale.quantize(quantize) - return str(different_scale) + suffix + return format(different_scale, "f") + suffix From bd7a8863337c31564abf85952ccf9ba46cb10326 Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 9 Jul 2026 23:05:18 +0000 Subject: [PATCH 12/14] update changelog with release notes from master branch --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d6713bcc6..51a1c42f7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# v36.0.3 + +Kubernetes API Version: v1.36.2 + +### Bug or Regression +- Fix Watch.stream selecting watch instead of follow when streaming pod logs. +- Start the leader election worker thread as a daemon so it does not block process shutdown. +- Fix readline_channel, readline_stdout and readline_stderr crashing with OverflowError when using the default timeout, and returning None when a timeout expires. +- Fix format_quantity returning imprecise, non-canonical values for the milli, micro and nano suffixes, and ignoring quantize=Decimal(0). + # v36.0.2 Kubernetes API Version: v1.36.1 From eedb17e9457a24d040efe15d7326df17f4efc13d Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 9 Jul 2026 23:05:18 +0000 Subject: [PATCH 13/14] update version constants for 36.0.3 release --- scripts/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/constants.py b/scripts/constants.py index 82e81a79e6..7cd5870a2b 100644 --- a/scripts/constants.py +++ b/scripts/constants.py @@ -18,7 +18,7 @@ KUBERNETES_BRANCH = "release-1.36" # client version for packaging and releasing. -CLIENT_VERSION = "36.0.2" +CLIENT_VERSION = "36.0.3" # Name of the release package PACKAGE_NAME = "kubernetes" From 0b18b057a155c297f0cefeb99a45e47597cf6d31 Mon Sep 17 00:00:00 2001 From: yliao Date: Thu, 9 Jul 2026 23:06:23 +0000 Subject: [PATCH 14/14] generated client change --- kubernetes/README.md | 2 +- kubernetes/__init__.py | 2 +- kubernetes/aio/README.md | 2 +- kubernetes/aio/__init__.py | 2 +- kubernetes/aio/client/__init__.py | 2 +- kubernetes/aio/client/api_client.py | 2 +- kubernetes/aio/client/api_client.py.orig | 2 +- kubernetes/aio/client/configuration.py | 2 +- kubernetes/aio/client/configuration.py.orig | 2 +- kubernetes/aio/setup.py | 2 +- kubernetes/client/__init__.py | 2 +- kubernetes/client/api_client.py | 2 +- kubernetes/client/configuration.py | 2 +- setup-asyncio.py | 4 ++-- setup-release.py | 2 +- setup.py | 2 +- 16 files changed, 17 insertions(+), 17 deletions(-) diff --git a/kubernetes/README.md b/kubernetes/README.md index 3a9d898799..dc63efe610 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -4,7 +4,7 @@ No description provided (generated by Openapi Generator https://github.com/opena This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - API version: release-1.36 -- Package version: 36.0.2 +- Package version: 36.0.3 - Build package: org.openapitools.codegen.languages.PythonLegacyClientCodegen ## Requirements. diff --git a/kubernetes/__init__.py b/kubernetes/__init__.py index 84f5bfaee6..bd39ab7fc2 100644 --- a/kubernetes/__init__.py +++ b/kubernetes/__init__.py @@ -14,7 +14,7 @@ __project__ = 'kubernetes' # The version is auto-updated. Please do not edit. -__version__ = "36.0.2" +__version__ = "36.0.3" from . import client from . import config diff --git a/kubernetes/aio/README.md b/kubernetes/aio/README.md index 4d739c65dc..db859d6ef1 100644 --- a/kubernetes/aio/README.md +++ b/kubernetes/aio/README.md @@ -4,7 +4,7 @@ No description provided (generated by Openapi Generator https://github.com/opena This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - API version: release-1.36 -- Package version: 36.0.2 +- Package version: 36.0.3 - Build package: org.openapitools.codegen.languages.PythonLegacyClientCodegen ## Requirements. diff --git a/kubernetes/aio/__init__.py b/kubernetes/aio/__init__.py index 5d74f97f55..d49f28286f 100644 --- a/kubernetes/aio/__init__.py +++ b/kubernetes/aio/__init__.py @@ -14,7 +14,7 @@ __project__ = "kubernetes_aio" # The version is auto-updated. Please do not edit. -__version__ = "36.0.2" +__version__ = "36.0.3" import kubernetes.aio.client as client diff --git a/kubernetes/aio/client/__init__.py b/kubernetes/aio/client/__init__.py index 5323b4bf82..2709e43db6 100644 --- a/kubernetes/aio/client/__init__.py +++ b/kubernetes/aio/client/__init__.py @@ -14,7 +14,7 @@ from __future__ import absolute_import -__version__ = "36.0.2" +__version__ = "36.0.3" # import apis into sdk package from kubernetes.aio.client.api.well_known_api import WellKnownApi diff --git a/kubernetes/aio/client/api_client.py b/kubernetes/aio/client/api_client.py index 4f18901e10..22f6067df3 100644 --- a/kubernetes/aio/client/api_client.py +++ b/kubernetes/aio/client/api_client.py @@ -78,7 +78,7 @@ def __init__(self, configuration=None, header_name=None, header_value=None, self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/36.0.2/python' + self.user_agent = 'OpenAPI-Generator/36.0.3/python' self.client_side_validation = configuration.client_side_validation async def __aenter__(self): diff --git a/kubernetes/aio/client/api_client.py.orig b/kubernetes/aio/client/api_client.py.orig index 03d1ac9757..852e23c3e9 100644 --- a/kubernetes/aio/client/api_client.py.orig +++ b/kubernetes/aio/client/api_client.py.orig @@ -78,7 +78,7 @@ class ApiClient(object): self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/36.0.2/python' + self.user_agent = 'OpenAPI-Generator/36.0.3/python' self.client_side_validation = configuration.client_side_validation async def __aenter__(self): diff --git a/kubernetes/aio/client/configuration.py b/kubernetes/aio/client/configuration.py index 13dea3c9ab..ad01a1af5e 100644 --- a/kubernetes/aio/client/configuration.py +++ b/kubernetes/aio/client/configuration.py @@ -441,7 +441,7 @@ def to_debug_report(self): "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: release-1.36\n"\ - "SDK Package Version: 36.0.2".\ + "SDK Package Version: 36.0.3".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/kubernetes/aio/client/configuration.py.orig b/kubernetes/aio/client/configuration.py.orig index 9779936845..430b817a14 100644 --- a/kubernetes/aio/client/configuration.py.orig +++ b/kubernetes/aio/client/configuration.py.orig @@ -432,7 +432,7 @@ conf = client.Configuration( "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: release-1.36\n"\ - "SDK Package Version: 36.0.2".\ + "SDK Package Version: 36.0.3".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/kubernetes/aio/setup.py b/kubernetes/aio/setup.py index 4f252c56f2..68873ea2ac 100644 --- a/kubernetes/aio/setup.py +++ b/kubernetes/aio/setup.py @@ -13,7 +13,7 @@ from setuptools import setup, find_packages # noqa: H301 NAME = "client" -VERSION = "36.0.2" +VERSION = "36.0.3" # To install the library, run the following # # python setup.py install diff --git a/kubernetes/client/__init__.py b/kubernetes/client/__init__.py index acb29a2340..8445b3b7c2 100644 --- a/kubernetes/client/__init__.py +++ b/kubernetes/client/__init__.py @@ -14,7 +14,7 @@ from __future__ import absolute_import -__version__ = "36.0.2" +__version__ = "36.0.3" # import apis into sdk package from kubernetes.client.api.well_known_api import WellKnownApi diff --git a/kubernetes/client/api_client.py b/kubernetes/client/api_client.py index 4662b9934c..1a62409c14 100644 --- a/kubernetes/client/api_client.py +++ b/kubernetes/client/api_client.py @@ -78,7 +78,7 @@ def __init__(self, configuration=None, header_name=None, header_value=None, self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/36.0.2/python' + self.user_agent = 'OpenAPI-Generator/36.0.3/python' self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/kubernetes/client/configuration.py b/kubernetes/client/configuration.py index 0797299eb1..8af8d65093 100644 --- a/kubernetes/client/configuration.py +++ b/kubernetes/client/configuration.py @@ -432,7 +432,7 @@ def to_debug_report(self): "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: release-1.36\n"\ - "SDK Package Version: 36.0.2".\ + "SDK Package Version: 36.0.3".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/setup-asyncio.py b/setup-asyncio.py index ecad9d520a..9c212e148d 100644 --- a/setup-asyncio.py +++ b/setup-asyncio.py @@ -16,9 +16,9 @@ # Do not edit these constants. They will be updated automatically # by scripts/update-client.sh. -CLIENT_VERSION = "36.0.0+snapshot" +CLIENT_VERSION = "36.0.3" PACKAGE_NAME = "kubernetes.aio" -DEVELOPMENT_STATUS = "3 - Alpha" +DEVELOPMENT_STATUS = "5 - Production/Stable" # To install the library, run the following # diff --git a/setup-release.py b/setup-release.py index 8cf710992f..13077bd2b6 100644 --- a/setup-release.py +++ b/setup-release.py @@ -16,7 +16,7 @@ # Do not edit these constants. They will be updated automatically # by scripts/update-client.sh. -CLIENT_VERSION = "36.0.2" +CLIENT_VERSION = "36.0.3" PACKAGE_NAME = "kubernetes" DEVELOPMENT_STATUS = "5 - Production/Stable" diff --git a/setup.py b/setup.py index ddd7f41e07..fa3d3a271b 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ # Do not edit these constants. They will be updated automatically # by scripts/update-client.sh. -CLIENT_VERSION = "36.0.2" +CLIENT_VERSION = "36.0.3" PACKAGE_NAME = "kubernetes" DEVELOPMENT_STATUS = "5 - Production/Stable"