Skip to content

Commit ddab620

Browse files
committed
Preserve null for reference default value defined as reference
Until now, a reference with a default value which is a reference that resolves to a YAML `null` value would result in a YAML string `"None"` when the resolution falls back on the default value. The cause for this is that we serialized `Value::Null` to `"None"` until now to preserve compatibility with Python's `str()` for nested reference lookups (since Python Reclass just uses `str()` to serialize nested references). This commit changes the serialization of `Value::Null` to `"null"` which is preserved as a YAML `null` when a reference default value is defined as a nested reference that resolves to YAML `null`. Conversely, any existing nested references that expect YAML `null` to be serialized as `None` will break with this change.
1 parent d2cc865 commit ddab620

4 files changed

Lines changed: 25 additions & 3 deletions

File tree

src/types/value.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,10 @@ impl Value {
484484
pub(crate) fn raw_string(&self) -> Result<String> {
485485
match self {
486486
Value::Literal(s) => Ok(s.clone()),
487-
// We serialize Null as `None` to be compatible with Python's str()
488-
Value::Null => Ok("None".to_string()),
487+
// We serialize Null as `null`. NOTE(sg): This isn't compatible with Python's str(),
488+
// but ensures that a reclass-rs reference default value which is a reference that
489+
// resolves to a Null value is preserved correctly.
490+
Value::Null => Ok("null".to_string()),
489491
// We need custom formatting for bool instead of `format!("{b}")`, so that this
490492
// function returns strings which match Python's `str()` implementation.
491493
Value::Bool(b) => match b {

src/types/value/value_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ fn test_raw_string_literal() {
301301

302302
#[test]
303303
fn test_raw_string_null() {
304-
assert_eq!(Value::Null.raw_string().unwrap(), "None".to_string());
304+
assert_eq!(Value::Null.raw_string().unwrap(), "null".to_string());
305305
}
306306

307307
#[test]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
parameters:
2+
facts:
3+
level: level
4+
data:
5+
"null": null
6+
nonestr: None
7+
bool: true
8+
num: 1.25
9+
nullref: ${data:${facts:level}::${data:null}}
10+
nulldefault: ${data:${facts:level}::~}
11+
boolref: ${data:${facts:level}::${data:bool}}
12+
numref: ${data:${facts:level}::${data:num}}
13+
nonestrref: ${data:${facts:level}::${data:nonestr}}

tests/test_inventory_reference_default_values.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,10 @@ def test_inventory_reference_default_values():
6161

6262
n11 = inv["nodes"]["n11"]["parameters"]
6363
assert n11["text"] == n11["expected"]
64+
65+
n12 = inv["nodes"]["n12"]["parameters"]
66+
assert n12["nullref"] is None
67+
assert n12["nulldefault"] is None
68+
assert n12["boolref"]
69+
assert n12["numref"] == 1.25
70+
assert n12["nonestrref"] == "None"

0 commit comments

Comments
 (0)