-
Notifications
You must be signed in to change notification settings - Fork 38.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make UnstructuredContent return contents without mutating the source #62063
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -446,20 +446,31 @@ func DeepCopyJSON(x map[string]interface{}) map[string]interface{} { | |
// DeepCopyJSONValue deep copies the passed value, assuming it is a valid JSON representation i.e. only contains | ||
// types produced by json.Unmarshal(). | ||
func DeepCopyJSONValue(x interface{}) interface{} { | ||
if x == nil { | ||
return nil | ||
} | ||
switch x := x.(type) { | ||
case map[string]interface{}: | ||
if x == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does this really exist? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, without this change (and below for completeness) the newly added check in the test (deep copy and compare) was failing. https://play.golang.org/p/KASoa2DeTnp There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will change the output - this code used to produce non-nil maps and slices for typed nils but now will produce typed nils. JSON encoding will change - typed nils as I think this change is a good one - it makes the deep copy more precise. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should never see typed nils somewhere deep inside IMO. On the toplevel maybe. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, we should not see them, but they exist. I'm fine with removing this fix from this PR if that's what you think is best. However I think that way deep copy is more correct. It just mirrors the input precisely. If there are no typed nils, we don't introduce them here. If they create a problem somewhere then the place that "spawns" them should be fixed. Or, even better, a place that does not handle them well could be made more robust. Also, I'm not sure what exactly you wanted me to compare? typed and untyped nils are both marshaled into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have we ever seen this "cannot deep copy" panic? You say that they show up. Do you know where? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Panic? Current code does not cause any panics AFAIK. Are you talking about failing test without these changes? It does not panic, it just fails because objects are not equal. They are not equal because the deep copied func TestNilUnstructuredContent(t *testing.T) {
var u Unstructured
uCopy := u.DeepCopy()
content := u.UnstructuredContent()
expContent := make(map[string]interface{})
assert.EqualValues(t, expContent, content)
assert.Equal(t, uCopy, &u)
}
|
||
// Typed nil - an interface{} that contains a type map[string]interface{} with a value of nil | ||
return x | ||
} | ||
clone := make(map[string]interface{}, len(x)) | ||
for k, v := range x { | ||
clone[k] = DeepCopyJSONValue(v) | ||
} | ||
return clone | ||
case []interface{}: | ||
if x == nil { | ||
// Typed nil - an interface{} that contains a type []interface{} with a value of nil | ||
return x | ||
} | ||
clone := make([]interface{}, len(x)) | ||
for i, v := range x { | ||
clone[i] = DeepCopyJSONValue(v) | ||
} | ||
return clone | ||
case string, int64, bool, float64, nil, encodingjson.Number: | ||
case string, int64, bool, float64, encodingjson.Number: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not keep the nil and remove the if clause above? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. My IntelliJ is complaining that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't feel strong about it. Was just curious. |
||
return x | ||
default: | ||
panic(fmt.Errorf("cannot deep copy %T", x)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you check that the actual object stays the same? Make a deep copy before and then compare afterwards.