Skip to content

[Python] Move 'python' outside of experimental - #3540

Merged
pietern merged 14 commits into
mainfrom
python-non-experimental
Oct 27, 2025
Merged

[Python] Move 'python' outside of experimental#3540
pietern merged 14 commits into
mainfrom
python-non-experimental

Conversation

@kanterov

Copy link
Copy Markdown
Collaborator

Changes

Move python outside of the experimental section.

The change is backward-compatible and forward-compatible. If CLI is using a newer or older version of databricks-bundles, it will continue to work. It's implemented by copying the content of python into experimental.python. If we don't offer compatibility, there is a risk that previously deployed resources will be erased because we wouldn't be able to load resources.

See also #3539

Why

Python support for Databricks Asset Bundles is graduating from the experimental status.

Tests

Acceptance tests check that previous databricks-bundles versions continue to work.

@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Run: 17406397515

Env✅​pass🔄​flaky🙈​skip
✅​aws linux308511
🔄​aws windows3063510
Test Nameaws windows
TestAccept🔄​flaky
TestAccept/bundle/templates/default-python/integration_classic🔄​flaky
TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_CLI_DEPLOYMENT=terraform/UV_PYTHON=3.13🔄​flaky

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Sep 2, 2025

Copy link
Copy Markdown
Collaborator

Run: 18834140817

Env❌​FAIL🟨​KNOWN🔄​flaky💚​RECOVERED🙈​SKIP✅​pass🙈​skip
💚​aws linux11319583
💚​aws windows11320582
💚​aws-ucws linux11440478
💚​aws-ucws windows11441477
💚​azure linux11319582
💚​azure windows11320581
❌​azure-ucws linux111437477
❌​azure-ucws windows111438476
🔄​gcp linux1111307584
🔄​gcp windows411315583
18 failing tests:
Test Nameaws linuxaws windowsaws-ucws linuxaws-ucws windowsazure linuxazure windowsazure-ucws linuxazure-ucws windowsgcp linuxgcp windows
TestAccept💚​R💚​R💚​R💚​R💚​R💚​R🟨​K🟨​K💚​R💚​R
TestAccept/bundle/deploy/files/no-snapshot-sync✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
TestAccept/bundle/deploy/files/no-snapshot-sync/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
TestAccept/bundle/destroy/jobs-and-pipeline✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
TestAccept/bundle/destroy/jobs-and-pipeline/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
TestAccept/bundle/local_state_staleness✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
TestAccept/bundle/local_state_staleness/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
TestAccept/bundle/resources/experiments/basic✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
TestAccept/bundle/resources/experiments/basic/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
TestAccept/bundle/resources/synced_database_tables/basic🙈​s🙈​s✅​p✅​p🙈​s🙈​s❌​F❌​F🙈​s🙈​s
TestAccept/bundle/run/app-with-job🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct-exp/DLT=no/NBOOK=no/PY=no✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct-exp/DLT=no/NBOOK=yes/PY=no✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct-exp/DLT=no/NBOOK=yes/PY=yes✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=yes/NBOOK=yes/PY=no✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f
TestAccept/bundle/templates/default-python/combinations/serverless✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
TestAccept/bundle/templates/default-python/integration_classic✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_BUNDLE_ENGINE=terraform/UV_PYTHON=3.10✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p

[EnvMatrix]
DATABRICKS_CLI_DEPLOYMENT = ["terraform", "direct-exp"]
UV_ARGS = ["--with databricks-bundles==0.7.3", "--with-requirements requirements-latest.txt --no-cache"]
UV_ARGS = ["--with databricks-bundles==0.266.0", "--with-requirements requirements-latest.txt --no-cache"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional to test only 0.266.0? What about the most recent release or main?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need some version from the past, and it was selected to be 0.266.0. It doesn't have to be the latest release. We just need to select a version that users might pin.

The second case for UV_ARGS is testing against the latest version from main

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to test past version -- please add a comment that this is intentional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does UV_ARGS="--with-requirements requirements-latest.txt --no-cache" results in testing the python package from the current branch or latest release from PyPI. Please add a comment as well, it's not clear.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 , I've clarified. It's using the same commit as acceptance tests

// don't execute for phases for 'pydabs' section
if phase == PythonMutatorPhaseLoadResources || phase == PythonMutatorPhaseApplyMutators {
if experimentalPythonEnabled && pythonEnabled {
if !reflect.DeepEqual(experimental.Python, b.Config.Python) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why reflect.Equal? Why not require users specify this once?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see below that this is to make python package work but IMO we should separate what we require from users and what we send to Python. E.g. we can have validator that requires that only one is present but then duplicate and send both to Python.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first time we call "getOpts", only 1 property can be specified. The second time, we call "getOpts" on the mutated bundle that contains both options specified after we have called applyBackwardsCompatibilityFixes, so we need to allow this case as well.

Here, we call applyBackwardsCompatibilityFixes before getOpts, so even the first time, we expect both options to be set.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we call it twice? cannot we remember the output from the first call?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our mutators are intended to be stateless, so we can't remember. And we call Python mutator twice in the mutator pipeline

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our mutators are intended to be stateless, so we can't remember. And we call Python mutator twice in the mutator pipeline

You can certainly have a field on *Bundle to track state relevant for you. Especially if it saves work and simplifies code.

@kanterovkanterovSep 8, 2025

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I just don't see a problem. If we want the bundle spec to be stable, we should allow specifying both properties during the transition period.

mutators:
- "mutators:add_task_1"
- "mutators:add_task_2"
python:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to have acceptance tests for new functionality:

  • only experimental.python is provided
  • both are provided and equal
  • both are provided and not equal

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 , added in the latest commit

github-merge-queueBot pushed a commit that referenced this pull request Sep 8, 2025
## Changes
Support reading both `python` and `experimental.python` configs. If both
are set, their value should be equivalent.
After we introduce the `python` section into the CLI, it has to keep
setting both `python` and `experimental.python` into the payload for
backward compatibility. After that, Python code can start erroring out
if `experimental/python` is set but not `python` because it means that
users have an outdated CLI version.
See also #3540
## Why
It's a step toward graduating `python` outside the `experimental`
section.
## Tests
Unit tests and existing acceptance tests
@kanterov
kanterovforce-pushed the python-non-experimental branch from d77a490 to f751173CompareSeptember 8, 2025 13:49
@kanterov
kanterovforce-pushed the python-non-experimental branch from 8fe901c to 32adbe7CompareOctober 24, 2025 13:01
@kanterov
kanterov enabled auto-merge October 27, 2025 10:06
@kanterov
kanterov disabled auto-merge October 27, 2025 10:29
@pietern
pietern merged commit 6f8e2b0 into mainOct 27, 2025
18 of 19 checks passed
@pietern
pietern deleted the python-non-experimental branch October 27, 2025 13:58
deco-sdk-taggingBot added a commit that referenced this pull request Oct 29, 2025
## Release v0.275.0
### Notable Changes
* Python support for Databricks Asset Bundles is now generally available.
### CLI
* Remove `inplace` mode for the `--progress-format` flag ([#3811](#3811))
* Remove `json` mode for the `--progress-format` flag ([#3812](#3812))
* Deprecate the `--progress-format` flag ([#3819](#3819))
### Bundles
* Add support for `--bind` flag in `bundle generate` ([#3782](#3782))
* Add `pydabs` template replacing `experimental-jobs-as-code` template ([#3806](#3806))
* You can now use the top-level `python` section instead of `experimental/python` ([#3540](#3540))
denik pushed a commit that referenced this pull request May 20, 2026
## Changes
Support reading both `python` and `experimental.python` configs. If both
are set, their value should be equivalent.
After we introduce the `python` section into the CLI, it has to keep
setting both `python` and `experimental.python` into the payload for
backward compatibility. After that, Python code can start erroring out
if `experimental/python` is set but not `python` because it means that
users have an outdated CLI version.
See also #3540
## Why
It's a step toward graduating `python` outside the `experimental`
section.
## Tests
Unit tests and existing acceptance tests
denik pushed a commit that referenced this pull request May 20, 2026
## Changes
Move `python` outside of the `experimental` section. The change is backward-compatible and forward-compatible. If CLI is
using a newer or older version of `databricks-bundles,` it will continue
to work. It's implemented by copying the content of `python` into
`experimental.python`. If we don't offer compatibility, there is a risk
that previously deployed resources will be erased because we wouldn't be
able to load resources.
See also #3539
## Why
Python support for Databricks Asset Bundles is graduating from the
experimental status.
## Tests
Acceptance tests check that previous `databricks-bundles` versions
continue to work.
denik pushed a commit that referenced this pull request May 20, 2026
## Release v0.275.0
### Notable Changes
* Python support for Databricks Asset Bundles is now generally available.
### CLI
* Remove `inplace` mode for the `--progress-format` flag ([#3811](#3811))
* Remove `json` mode for the `--progress-format` flag ([#3812](#3812))
* Deprecate the `--progress-format` flag ([#3819](#3819))
### Bundles
* Add support for `--bind` flag in `bundle generate` ([#3782](#3782))
* Add `pydabs` template replacing `experimental-jobs-as-code` template ([#3806](#3806))
* You can now use the top-level `python` section instead of `experimental/python` ([#3540](#3540))
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@kanterov@eng-dev-ecosystem-bot@denik@pietern