From 0ce2590568db3b31ed79d4e6b56353574db5347b Mon Sep 17 00:00:00 2001 From: Sandwich Date: Mon, 5 Oct 2026 19:25:02 +0200 Subject: [PATCH] fix(validation): accept an empty string as the unset value of an int --- plugins/action/validate_inputs.py | 5 +++-- tests/inputs/inputs_fixtures.yml | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/action/validate_inputs.py b/plugins/action/validate_inputs.py index d39ab25..20457e0 100644 --- a/plugins/action/validate_inputs.py +++ b/plugins/action/validate_inputs.py @@ -20,10 +20,11 @@ SPEC_KEYS = {"type", "required", "default", "choices", "elements", "options", "d UNRESOLVED = object() # Numbers pass where a string is declared and digit strings where an int is: the roles read those -# through `| string` and `| int` unchanged. A string posing as a list, bool or dict never passes. +# through `| string` and `| int` unchanged. An empty string is the contract's unset int, as in +# `system.vlan: ""`. A string posing as a list, bool or dict never passes. TYPES = { "str": lambda v: isinstance(v, (str, int, float, EncryptedString)) and not isinstance(v, bool), - "int": lambda v: (isinstance(v, int) and not isinstance(v, bool)) or (isinstance(v, str) and v.isdigit()), + "int": lambda v: (isinstance(v, int) and not isinstance(v, bool)) or (isinstance(v, str) and (v == "" or v.isdigit())), "float": lambda v: isinstance(v, (int, float)) and not isinstance(v, bool), "bool": lambda v: isinstance(v, bool), "list": lambda v: isinstance(v, list), diff --git a/tests/inputs/inputs_fixtures.yml b/tests/inputs/inputs_fixtures.yml index eabc8e7..14f7fba 100644 --- a/tests/inputs/inputs_fixtures.yml +++ b/tests/inputs/inputs_fixtures.yml @@ -16,6 +16,12 @@ inputs_fixtures: retired: ~ expect: [] + - name: empty-int-is-unset + value: + name: web01 + count: "" + expect: [] + - name: list-for-dict value: name: web01