Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Fixed

- Fix `WithInstrumentationAttributes` options in `go.opentelemetry.io/otel/trace`, `go.opentelemetry.io/otel/metric`, and `go.opentelemetry.io/otel/log` to properly merge attributes when passed multiple times instead of replacing them. Attributes with duplicate keys will use the last value passed. (#7300)
- The equality of `attribute.Set` when using the `Equal` method is not affected by the user overriding the empty set pointed to by `attribute.EmptySet` in `go.opentelemetry.io/otel/attribute`. (#7357)

### Removed

Expand Down
28 changes: 18 additions & 10 deletions attribute/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,18 @@ var (
// keyValueType is used in computeDistinctReflect.
keyValueType = reflect.TypeOf(KeyValue{})

// emptySet is returned for empty attribute sets.
emptySet = &Set{
// userDefinedEmptySet is an empty set. It was mistakenly exposed to users
// as something they can assign to, so it must remain addressable and
// mutable.
//
// This is kept for backwards compatibility, but should not be used in new code.
userDefinedEmptySet = &Set{
equivalent: Distinct{
iface: [0]KeyValue{},
},
}

emptySet = Set{
equivalent: Distinct{
iface: [0]KeyValue{},
},
Expand All @@ -62,7 +72,11 @@ var (
//
// This is a convenience provided for optimized calling utility.
func EmptySet() *Set {
return emptySet
// Continue to return the pointer to the user-defined empty set for
// backwards-compatibility.
//
// New code should not use this, instead use emptySet.
return userDefinedEmptySet
}

// reflectValue abbreviates reflect.ValueOf(d).
Expand Down Expand Up @@ -169,12 +183,6 @@ func (l *Set) Encoded(encoder Encoder) string {
return encoder.Encode(l.Iter())
}

func empty() Set {
return Set{
equivalent: emptySet.equivalent,
}
}

// NewSet returns a new Set. See the documentation for
// NewSetWithSortableFiltered for more details.
//
Expand Down Expand Up @@ -204,7 +212,7 @@ func NewSetWithSortable(kvs []KeyValue, _ *Sortable) Set {
func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
// Check for empty set.
if len(kvs) == 0 {
return empty(), nil
return emptySet, nil
}

// Stable sort so the following de-duplication can implement
Expand Down
11 changes: 11 additions & 0 deletions attribute/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,17 @@ func TestMarshalJSON(t *testing.T) {
}
}

func TestSetEqualsEmpty(t *testing.T) {
e := attribute.EmptySet()
empty := *e

alt := attribute.NewSet(attribute.String("A", "B"))
*e = alt

var s attribute.Set
assert.Truef(t, s.Equals(&empty), "expected %v to equal empty set %v", s, attribute.EmptySet())
}

type simpleStringer struct {
val string
}
Expand Down
Loading