This is an automated email from the ASF dual-hosted git repository.
shahar1 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 29f48b532e5 Stop defaulting PsrpOperator task_id to cmdlet (#73036)
29f48b532e5 is described below
commit 29f48b532e5d97348a3b837b0125bdcf14e03792
Author: Shahar Epstein <[email protected]>
AuthorDate: Sat Sep 12 20:33:19 2026 +0300
Stop defaulting PsrpOperator task_id to cmdlet (#73036)
cmdlet is a template field, rendered after the constructor runs, so
deriving task_id from it in __init__ read the un-rendered Jinja value.
It was the last construction-time read keeping PsrpOperator on the
validate-operators-init exemption list, and it cannot move to execute()
because task_id must exist before BaseOperator is initialised.
PR #70347 deliberately kept the default because dropping it changes task
identity for Dags that relied on it; this is the separate follow-up it
deferred. Users keep the same task_id by passing it explicitly with the
cmdlet name, as the changelog note describes.
related: #70296
Generated-by: Claude Fable 5.1
---
providers/microsoft/psrp/docs/changelog.rst | 11 +++++++++++
.../src/airflow/providers/microsoft/psrp/operators/psrp.py | 6 +-----
.../psrp/tests/unit/microsoft/psrp/operators/test_psrp.py | 10 +++++-----
scripts/ci/prek/validate_operators_init_exemptions.txt | 1 -
4 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/providers/microsoft/psrp/docs/changelog.rst
b/providers/microsoft/psrp/docs/changelog.rst
index f7500957095..6bf7afbe37b 100644
--- a/providers/microsoft/psrp/docs/changelog.rst
+++ b/providers/microsoft/psrp/docs/changelog.rst
@@ -27,6 +27,17 @@
Changelog
---------
+Breaking changes
+~~~~~~~~~~~~~~~~
+
+* ``Stop defaulting PsrpOperator task_id to cmdlet``
+
+ ``PsrpOperator`` no longer uses ``cmdlet`` as the default ``task_id``;
``task_id`` is now required, as
+ on every other operator. ``cmdlet`` is a template field rendered after the
constructor runs, so the
+ default read the un-rendered value. To keep the existing task identity
(history, logs, XComs), pass
+ ``task_id`` explicitly with the same value as ``cmdlet``, for example
+ ``PsrpOperator(task_id="Get-Process", cmdlet="Get-Process",
psrp_conn_id="psrp_default")``.
+
3.2.7
.....
diff --git
a/providers/microsoft/psrp/src/airflow/providers/microsoft/psrp/operators/psrp.py
b/providers/microsoft/psrp/src/airflow/providers/microsoft/psrp/operators/psrp.py
index 673c99f4a37..173979abc79 100644
---
a/providers/microsoft/psrp/src/airflow/providers/microsoft/psrp/operators/psrp.py
+++
b/providers/microsoft/psrp/src/airflow/providers/microsoft/psrp/operators/psrp.py
@@ -55,9 +55,7 @@ class PsrpOperator(BaseOperator):
:param psrp_conn_id: connection id
:param command: command to execute on remote host. (templated)
:param powershell: powershell to execute on remote host. (templated)
- :param cmdlet:
- cmdlet to execute on remote host (templated). Also used as the default
- value for `task_id`.
+ :param cmdlet: cmdlet to execute on remote host (templated).
:param arguments:
When using the `cmdlet` or `powershell` option, use `arguments` to
provide arguments (templated).
@@ -112,8 +110,6 @@ class PsrpOperator(BaseOperator):
raise ValueError("Arguments only allowed with 'powershell' or
'cmdlet'")
if parameters is not None and powershell is None and cmdlet is None:
raise ValueError("Parameters only allowed with 'powershell' or
'cmdlet'")
- if cmdlet:
- kwargs.setdefault("task_id", cmdlet)
super().__init__(**kwargs)
self.conn_id = psrp_conn_id
self.command = command
diff --git
a/providers/microsoft/psrp/tests/unit/microsoft/psrp/operators/test_psrp.py
b/providers/microsoft/psrp/tests/unit/microsoft/psrp/operators/test_psrp.py
index 92039ec6f56..35000f93503 100644
--- a/providers/microsoft/psrp/tests/unit/microsoft/psrp/operators/test_psrp.py
+++ b/providers/microsoft/psrp/tests/unit/microsoft/psrp/operators/test_psrp.py
@@ -68,9 +68,9 @@ class TestPsrpOperator:
def test_empty_option_counts_as_provided(self, kwargs):
PsrpOperator(task_id="test_task_id", psrp_conn_id=CONNECTION_ID,
**kwargs)
- def test_cmdlet_task_id_default(self):
- operator = PsrpOperator(cmdlet="Invoke-Foo",
psrp_conn_id=CONNECTION_ID)
- assert operator.task_id == "Invoke-Foo"
+ def test_cmdlet_requires_explicit_task_id(self):
+ with pytest.raises(TypeError, match="task_id"):
+ PsrpOperator(cmdlet="Invoke-Foo", psrp_conn_id=CONNECTION_ID)
@patch(f"{PsrpOperator.__module__}.PsrpHook")
def test_command_rendering_to_empty_dispatches_as_command(self, hook_impl):
@@ -152,14 +152,14 @@ class TestPsrpOperator:
assert ps.mock_calls == expected_ps_calls
def test_securestring_sandboxed(self):
- op = PsrpOperator(psrp_conn_id=CONNECTION_ID, cmdlet="test")
+ op = PsrpOperator(task_id="test", psrp_conn_id=CONNECTION_ID,
cmdlet="test")
template = op.get_template_env().from_string("{{ 'foo' | securestring
}}")
with pytest.raises(AirflowException):
template.render()
@patch.object(BaseOperator, "get_template_env")
def test_securestring_native(self, get_template_env):
- op = PsrpOperator(psrp_conn_id=CONNECTION_ID, cmdlet="test")
+ op = PsrpOperator(task_id="test", psrp_conn_id=CONNECTION_ID,
cmdlet="test")
get_template_env.return_value = NativeEnvironment()
template = op.get_template_env().from_string("{{ 'foo' | securestring
}}")
rendered = template.render()
diff --git a/scripts/ci/prek/validate_operators_init_exemptions.txt
b/scripts/ci/prek/validate_operators_init_exemptions.txt
index bbb80b5fec7..70027a176dd 100644
--- a/scripts/ci/prek/validate_operators_init_exemptions.txt
+++ b/scripts/ci/prek/validate_operators_init_exemptions.txt
@@ -16,4 +16,3 @@
providers/google/src/airflow/providers/google/cloud/operators/functions.py::Clou
providers/google/src/airflow/providers/google/cloud/operators/gcs.py::GCSFileTransformOperator
providers/google/src/airflow/providers/google/cloud/sensors/bigquery_dts.py::BigQueryDataTransferServiceTransferRunSensor
providers/google/src/airflow/providers/google/cloud/sensors/cloud_composer.py::CloudComposerExternalTaskSensor
-providers/microsoft/psrp/src/airflow/providers/microsoft/psrp/operators/psrp.py::PsrpOperator