Jira (PUP-11505) Unexpected results using stdlib's to_yaml with data containing repeated variables

7 views
Skip to first unread message

Alexander Fisher (Jira)

unread,
Apr 12, 2022, 12:24:02 PM4/12/22
to puppe...@googlegroups.com
Alexander Fisher created an issue
 
Puppet / Bug PUP-11505
Unexpected results using stdlib's to_yaml with data containing repeated variables
Issue Type: Bug Bug
Assignee: Unassigned
Created: 2022/04/12 9:23 AM
Priority: Normal Normal
Reporter: Alexander Fisher

Puppet Version: 6/7
**

I wasn't sure where to file this, but I encountered some unexpected behaviour today.

Given the following puppet code

$array = [  'one',  'two',  'three']
 
notice(
  {
    'foo'      => $array,
    'bar'      => $array,
    'foobar' => $array,
  }.to_yaml
)
 
# These `flatten`s look superfluous, but aren't
 
notice(
  {
    'foo'      => $array.flatten,
    'bar'      => $array.flatten,
    'foobar' => $array.flatten,
  }.to_yaml
) 

I'd expect to notice the same YAML being output.  Instead, in the version where I don't, (seemingly randomly call `flatten`), I get yaml with anchors (which I happen not to like).

ie 

❯ puppet apply -t test.pp
Info: Loading facts
Notice: Scope(Class[main]): ---
foo: &1
- one
- two
- three
bar: *1
foobar: *1
 
Notice: Scope(Class[main]): ---
foo:
- one
- two
- three
bar:
- one
- two
- three
foobar:
- one
- two
- three

Whilst I understand that there's an issue with values being passed to the to_yaml function by reference and `flatten` gets around this by creating 3 new objects, I don't feel this meets the https://en.wikipedia.org/wiki/Principle_of_least_astonishment test.

I don't think it's documented anywhere that puppet variables can act this way with functions.

Add Comment Add Comment
 
This message was sent by Atlassian Jira (v8.20.2#820002-sha1:829506d)
Atlassian logo

Alexander Fisher (Jira)

unread,
Apr 12, 2022, 12:25:03 PM4/12/22
to puppe...@googlegroups.com
Alexander Fisher updated an issue
Change By: Alexander Fisher
*Puppet Version: 6/7*
**

I wasn't sure where to file this, but I encountered some unexpected behaviour today.

Given the following puppet code
{code:puppet}$array = [  'one',  'two',  'three']


notice(
  {
    'foo'      => $array,
    'bar'      => $array,
    'foobar' => $array,
  }.to_yaml
)

# These `flatten`s look superfluous, but aren't

notice(
  {
    'foo'      => $array.flatten,
    'bar'      => $array.flatten,
    'foobar' => $array.flatten,
  }.to_yaml
) {code}

I'd expect to notice the same YAML being output.  Instead, in the version where I don't, (seemingly randomly call `flatten`), I get yaml with anchors (which I happen not to like).

ie 
{noformat}❯ puppet apply -t test.pp

Info: Loading facts
Notice: Scope(Class[main]): ---
foo: &1
- one
- two
- three
bar: *1
foobar: *1

Notice: Scope(Class[main]): ---
foo:
- one
- two
- three
bar:
- one
- two
- three
foobar:
- one
- two
- three
{noformat}

Whilst I understand that there's an issue with values being passed to the to_yaml function by reference and `flatten` gets around this by creating 3 new objects, I don't feel this meets the [https://en.wikipedia.org/wiki/Principle_of_least_astonishment] test.

I don't think it's documented anywhere that _puppet_ variables can act this way with functions.

Alexander Fisher (Jira)

unread,
Apr 12, 2022, 12:31:03 PM4/12/22
to puppe...@googlegroups.com

Josh Cooper (Jira)

unread,
Apr 12, 2022, 5:11:02 PM4/12/22
to puppe...@googlegroups.com
Josh Cooper commented on Bug PUP-11505
 
Re: Unexpected results using stdlib's to_yaml with data containing repeated variables

Technically, puppet is behaving correctly. The same array object is referenced in multiple times and to_yaml produced valid YAML, preserving the fact that the same array object was emitted 3 times. Some yaml bindings allow the behavior to be altered, such PyYAML's ignore_aliases https://github.com/yaml/pyyaml/blob/8cdff2c80573b8be8e8ad28929264a913a63aa33/lib/yaml/representer.py#L131 This post goes into more detail: https://ttl255.com/yaml-anchors-and-aliases-and-how-to-disable-them/ The other option is to deep clone the object, which flatten is effectively doing, but only the caller really knows if the object can be deep cloned.

Reply all
Reply to author
Forward
0 new messages