Skip to content

Restore submodule access through the deprecated kubernetes.client.apis package - #2727

Merged
kubernetes-prow[bot] merged 1 commit into
kubernetes-client:masterfrom
yurnov:fix-apis-alias-submodules
Oct 8, 2026
Merged

kubernetes-prow[bot] merged 1 commit into
kubernetes-client:masterfrom
yurnov:fix-apis-alias-submodules

Conversation

@yurnov

@yurnov yurnov commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

/kind bug
/kind regression

What this PR does / why we need it:

Since v37.0.0, from kubernetes.client.apis import core_v1_api raises ImportError, which breaks code that still uses the deprecated alias, for example k8s_exec in ansible-collections/kubernetes.core#1273. The alias star-imports kubernetes.client.api, which now defines __all__ with class names only and loads its submodules lazily (#2631, #2652), so the submodule names are no longer re-exported. This adds a module-level __getattr__ (PEP 562) to the alias that resolves submodule names on demand, plus a regression test.

Which issue(s) this PR fixes:

Fixes #2726

Special notes for your reviewer:

  • The alias is hand-written, so the fix survives regeneration: client/apis/__init__.py is not listed in [kubernetes/.openapi-generator/FILES][files], and gen only removes client/api, client/models and docs before generating ([CLEANUP_DIRS][cleanup], [removed one by one with rm -rf][rm]). The file hasn't changed since 2019 and was kept through the v7.24.0 and v7.25.0 regenerations. The new test sits next to the other hand-written tests in kubernetes/test/.
  • Why __getattr__ rather than binding every submodule into the alias namespace with a pkgutil.iter_modules() loop: it is what the issue proposed, it keeps the change small, and type checkers can see it. With this change mypy resolves from kubernetes.client.apis import core_v1_api to ModuleType. On master it reports attr-defined, and dynamically bound names would still get that error.
  • Unknown names raise AttributeError, so from ... import raises ImportError and hasattr() returns False. A ModuleNotFoundError for any other module, such as a missing dependency inside an API module, propagates unchanged. Private and non-identifier names are rejected without an import attempt, so probes like __wrapped__ or the __all__ lookup of a star import don't try to import anything.
  • Remaining differences from 36.x: from kubernetes.client.apis import * does not export the submodule names, and dir(kubernetes.client.apis) does not list them. I left those as they are for a deprecated alias. Dotted imports (import kubernetes.client.apis.core_v1_api) didn't work in 36.x either.
  • Importing the alias costs the same as before. Its star import already loads every API submodule through the lazy __getattr__ of kubernetes.client.api.
  • The new test fails on master (test_from_import_submodule, all 66 subtests of test_every_api_submodule_is_reachable, and the two tests for the new guards) and passes with the fix. Other unit test results are the same as on master. Tested on Python 3.10, 3.12 and 3.14.
  • Could this be cherry-picked to release-37.0 for a 37.0.1? The commit applies cleanly there, and the new test passes on it.

AI Disclosure
Parts of this PR (including complete unit tests) were generated using Anthropic Sonnet 5.5. All generated code has been manually reviewed, tested, and verified for accuracy.

Does this PR introduce a user-facing change?

Fixed importing API submodules such as `core_v1_api` from the deprecated `kubernetes.client.apis` package, which raised `ImportError` since v37.0.0.

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:

N/A

kubernetes.client.api now defines __all__ with class names only and
loads its submodules lazily, so the deprecated alias's star import no
longer brings in names such as core_v1_api and
"from kubernetes.client.apis import core_v1_api" raises ImportError.

Resolve submodule names on demand with a module-level __getattr__. The
alias is hand-written and outside the generated tree, so the fix
survives regeneration.
@kubernetes-prow kubernetes-prow Bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. kind/bug Categorizes issue or PR as related to a bug. kind/regression Categorizes issue or PR as related to a regression from a prior release. labels Oct 8, 2026
@kubernetes-prow
kubernetes-prow Bot requested review from roycaihw and yliaog October 8, 2026 17:11
@kubernetes-prow kubernetes-prow Bot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Oct 8, 2026
@yliaog

yliaog commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

/lgtm
/approve

@kubernetes-prow kubernetes-prow Bot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 8, 2026
@kubernetes-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: yliaog, yurnov

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubernetes-prow kubernetes-prow Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 8, 2026
@kubernetes-prow
kubernetes-prow Bot merged commit ffba441 into kubernetes-client:master Oct 8, 2026
10 checks passed
@yurnov

yurnov commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @yliaog for the review. Can I request to cherry-pick it to the release-37 branch and plan a patch release, i.e., 37.0.1?

@yliaog

yliaog commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Yes, that will done later today or early tomorrow.

@yurnov
yurnov deleted the fix-apis-alias-submodules branch October 8, 2026 18:51
yurnov added a commit to yurnov/ansible-for-kubernetes-demo that referenced this pull request Oct 9, 2026
Follow-up to #9 (#8).

kubernetes Python client 37.0.1 fixes importing API submodules such as `core_v1_api` from the deprecated `kubernetes.client.apis` package (kubernetes-client/python#2727, [changelog](https://github.com/kubernetes-client/python/blob/release-37.0/CHANGELOG.md#v3701)). That is what broke `k8s_exec` in playbook 03.

`requirements.txt` now excludes only the broken release: `kubernetes>=24.2.0,!=37.0.0`. Unlike the `<37.0.0` pin, this does not hold the canary back, so other 37.x breakage is no longer hidden and the exclusion can stay.

The collection-side fix, ansible-collections/kubernetes.core#1274, is still open. The demo no longer depends on it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. kind/regression Categorizes issue or PR as related to a regression from a prior release. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

37.0.0: from kubernetes.client.apis import core_v1_api raises ImportError

2 participants