From da577e082162af7e9d2f45f83eb6804d141b9213 Mon Sep 17 00:00:00 2001 From: Tony Meyer Date: Fri, 19 Dec 2025 11:18:41 +1300 Subject: [PATCH 1/2] fix: correct the value of additional_parameters in Juju 4. --- ops/charm.py | 6 +++++- test/test_charm.py | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ops/charm.py b/ops/charm.py index a5b155905..8225ea7c2 100644 --- a/ops/charm.py +++ b/ops/charm.py @@ -19,6 +19,7 @@ import dataclasses import enum import logging +import os import pathlib import warnings from collections.abc import Mapping @@ -45,6 +46,7 @@ Object, ObjectEvents, ) +from .jujuversion import JujuVersion if TYPE_CHECKING: from typing_extensions import Required @@ -2209,7 +2211,9 @@ def __init__(self, name: str, raw: dict[str, Any] | None = None): self.description = raw.get('description', '') self.parameters = raw.get('params', {}) # {: } self.required = raw.get('required', []) # [, ...] - self.additional_properties = raw.get('additionalProperties', True) + # The default in Juju 4 is False. The default in earlier Juju versions is True. + juju_version = JujuVersion(os.environ.get('JUJU_VERSION', '0.0.0')) + self.additional_properties = raw.get('additionalProperties', juju_version < '4.0.0') @dataclasses.dataclass(frozen=True) diff --git a/test/test_charm.py b/test/test_charm.py index 0bb24141c..b6e52f6bd 100644 --- a/test/test_charm.py +++ b/test/test_charm.py @@ -644,6 +644,18 @@ def test_actions_from_charm_root(): assert meta.actions['foo'].description == 'foos the bar' +@pytest.mark.parametrize( + 'juju_version,additional_properties', + [('2.9', True), ('3.6.12', True), ('4.0.0', False), ('4.1', False)], +) +def test_actions_additional_properties( + monkeypatch: pytest.MonkeyPatch, juju_version: str, additional_properties: bool +): + monkeypatch.setenv('JUJU_VERSION', juju_version) + action = ops.ActionMeta('foo', {}) + assert action.additional_properties == additional_properties + + def _setup_test_action(fake_script: FakeScript): fake_script.write('action-get', """echo '{"foo-name": "name", "silent": true}'""") fake_script.write('action-set', '') From 19a6902942940c08254cfbea90f8fce28255080f Mon Sep 17 00:00:00 2001 From: Tony Meyer Date: Fri, 19 Dec 2025 18:43:00 +1300 Subject: [PATCH 2/2] Add tests for missing envvar and both explicit values. --- test/test_charm.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/test/test_charm.py b/test/test_charm.py index b6e52f6bd..464abce4d 100644 --- a/test/test_charm.py +++ b/test/test_charm.py @@ -627,11 +627,17 @@ def test_config_from_raw(): assert meta.config['sssh'].description == 'a user secret' -def test_actions_from_charm_root(): +@pytest.mark.parametrize('additional_properties', [False, True]) +def test_actions_from_charm_root(additional_properties: bool): with tempfile.TemporaryDirectory() as d: td = pathlib.Path(d) (td / 'actions.yaml').write_text( - yaml.safe_dump({'foo': {'description': 'foos the bar', 'additionalProperties': False}}) + yaml.safe_dump({ + 'foo': { + 'description': 'foos the bar', + 'additionalProperties': additional_properties, + } + }) ) (td / 'metadata.yaml').write_text( yaml.safe_dump({'name': 'bob', 'requires': {'foo': {'interface': 'bar'}}}) @@ -640,18 +646,21 @@ def test_actions_from_charm_root(): meta = ops.CharmMeta.from_charm_root(td) assert meta.name == 'bob' assert meta.requires['foo'].interface_name == 'bar' - assert not meta.actions['foo'].additional_properties + assert meta.actions['foo'].additional_properties == additional_properties assert meta.actions['foo'].description == 'foos the bar' @pytest.mark.parametrize( 'juju_version,additional_properties', - [('2.9', True), ('3.6.12', True), ('4.0.0', False), ('4.1', False)], + [('2.9', True), ('3.6.12', True), ('4.0.0', False), ('4.1', False), (None, True)], ) def test_actions_additional_properties( - monkeypatch: pytest.MonkeyPatch, juju_version: str, additional_properties: bool + monkeypatch: pytest.MonkeyPatch, juju_version: str | None, additional_properties: bool ): - monkeypatch.setenv('JUJU_VERSION', juju_version) + if juju_version is None: + monkeypatch.delenv('JUJU_VERSION', raising=False) + else: + monkeypatch.setenv('JUJU_VERSION', juju_version) action = ops.ActionMeta('foo', {}) assert action.additional_properties == additional_properties