Skip to content

Commit 1ebc2ce

Browse files
committed
Change fieldnames() and propertynames() to return a tuple rather than an array
Using an immutable structure makes sense since the names cannot be modified, and it avoids an allocation.
1 parent f8acac7 commit 1ebc2ce

File tree

14 files changed

+44
-36
lines changed

14 files changed

+44
-36
lines changed

NEWS.md

+4
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,9 @@ This section lists changes that do not have deprecation warnings.
420420
* The `tempname` function used to create a file on Windows but not on other
421421
platforms. It now never creates a file ([#9053]).
422422

423+
* The `fieldnames` and `propertynames` functions now return a tuple rather than
424+
an array ([#25725]).
425+
423426
Library improvements
424427
--------------------
425428

@@ -1284,4 +1287,5 @@ Command-line option changes
12841287
[#25634]: https://github.com/JuliaLang/julia/issues/25634
12851288
[#25654]: https://github.com/JuliaLang/julia/issues/25654
12861289
[#25655]: https://github.com/JuliaLang/julia/issues/25655
1290+
[#25725]: https://github.com/JuliaLang/julia/issues/25725
12871291
[#25745]: https://github.com/JuliaLang/julia/issues/25745

base/compiler/optimize.jl

+4-2
Original file line numberDiff line numberDiff line change
@@ -2950,7 +2950,8 @@ function structinfo_constant(ctx::AllocOptContext, @nospecialize(v), vt::DataTyp
29502950
if vt <: Tuple
29512951
si = StructInfo(Vector{Any}(uninitialized, nf), Symbol[], vt, false, false)
29522952
else
2953-
si = StructInfo(Vector{Any}(uninitialized, nf), fieldnames(vt), vt, false, false)
2953+
si = StructInfo(Vector{Any}(uninitialized, nf), collect(Symbol, fieldnames(vt)),
2954+
vt, false, false)
29542955
end
29552956
for i in 1:nf
29562957
if isdefined(v, i)
@@ -2966,7 +2967,8 @@ end
29662967
structinfo_tuple(ex::Expr) = StructInfo(ex.args[2:end], Symbol[], Tuple, false, false)
29672968
function structinfo_new(ctx::AllocOptContext, ex::Expr, vt::DataType)
29682969
nf = fieldcount(vt)
2969-
si = StructInfo(Vector{Any}(uninitialized, nf), fieldnames(vt), vt, vt.mutable, true)
2970+
si = StructInfo(Vector{Any}(uninitialized, nf), collect(Symbol, fieldnames(vt)),
2971+
vt, vt.mutable, true)
29702972
ninit = length(ex.args) - 1
29712973
for i in 1:nf
29722974
if i <= ninit

base/reflection.jl

+6-8
Original file line numberDiff line numberDiff line change
@@ -145,19 +145,17 @@ fieldname(t::Type{<:Tuple}, i::Integer) =
145145
"""
146146
fieldnames(x::DataType)
147147
148-
Get an array of the fields of a `DataType`.
148+
Get a tuple with the names of the fields of a `DataType`.
149149
150150
# Examples
151151
```jldoctest
152152
julia> fieldnames(Rational)
153-
2-element Array{Symbol,1}:
154-
:num
155-
:den
153+
(:num, :den)
156154
```
157155
"""
158-
fieldnames(t::DataType) = Symbol[fieldname(t, n) for n in 1:fieldcount(t)]
156+
fieldnames(t::DataType) = ntuple(i -> fieldname(t, i), fieldcount(t))
159157
fieldnames(t::UnionAll) = fieldnames(unwrap_unionall(t))
160-
fieldnames(t::Type{<:Tuple}) = Int[n for n in 1:fieldcount(t)]
158+
fieldnames(t::Type{<:Tuple}) = ntuple(identity, fieldcount(t))
161159

162160
"""
163161
nameof(t::DataType) -> Symbol
@@ -1062,8 +1060,8 @@ max_world(m::Core.MethodInstance) = reinterpret(UInt, m.max_world)
10621060
"""
10631061
propertynames(x, private=false)
10641062
1065-
Get an array of the properties (`x.property`) of an object `x`. This
1066-
is typically the same as [`fieldnames(typeof(x))`](@ref), but types
1063+
Get a tuple or a vector of the properties (`x.property`) of an object `x`.
1064+
This is typically the same as [`fieldnames(typeof(x))`](@ref), but types
10671065
that overload [`getproperty`](@ref) should generally overload `propertynames`
10681066
as well to get the properties of an instance of the type.
10691067

base/util.jl

+1-10
Original file line numberDiff line numberDiff line change
@@ -288,16 +288,7 @@ julia> gctime
288288
0.0055765
289289
290290
julia> fieldnames(typeof(memallocs))
291-
9-element Array{Symbol,1}:
292-
:allocd
293-
:malloc
294-
:realloc
295-
:poolalloc
296-
:bigalloc
297-
:freecall
298-
:total_time
299-
:pause
300-
:full_sweep
291+
(:allocd, :malloc, :realloc, :poolalloc, :bigalloc, :freecall, :total_time, :pause, :full_sweep)
301292
302293
julia> memallocs.total_time
303294
5576500

stdlib/LinearAlgebra/src/bunchkaufman.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ function getproperty(B::BunchKaufman{T}, d::Symbol) where {T<:BlasFloat}
205205
end
206206
end
207207

208-
Base.propertynames(B::BunchKaufman, private::Bool=false) = append!([:p,:P,:L,:U,:D], private ? fieldnames(typeof(B)) : Symbol[])
208+
Base.propertynames(B::BunchKaufman, private::Bool=false) =
209+
(:p, :P, :L, :U, :D, (private ? fieldnames(typeof(B)) : ())...)
209210

210211
issuccess(B::BunchKaufman) = B.info == 0
211212

stdlib/LinearAlgebra/src/cholesky.jl

+4-2
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,8 @@ function getproperty(C::Cholesky, d::Symbol)
393393
return getfield(C, d)
394394
end
395395
end
396-
Base.propertynames(F::Cholesky, private::Bool=false) = append!([:U,:L,:UL], private ? fieldnames(typeof(F)) : Symbol[])
396+
Base.propertynames(F::Cholesky, private::Bool=false) =
397+
(:U, :L, :UL, (private ? fieldnames(typeof(F)) : ())...)
397398

398399
function getproperty(C::CholeskyPivoted{T}, d::Symbol) where T<:BlasFloat
399400
Cfactors = getfield(C, :factors)
@@ -415,7 +416,8 @@ function getproperty(C::CholeskyPivoted{T}, d::Symbol) where T<:BlasFloat
415416
return getfield(C, d)
416417
end
417418
end
418-
Base.propertynames(F::CholeskyPivoted, private::Bool=false) = append!([:U,:L,:p,:P], private ? fieldnames(typeof(F)) : Symbol[])
419+
Base.propertynames(F::CholeskyPivoted, private::Bool=false) =
420+
(:U, :L, :p, :P, (private ? fieldnames(typeof(F)) : ())...)
419421

420422
issuccess(C::Cholesky) = C.info == 0
421423

stdlib/LinearAlgebra/src/hessenberg.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ function getproperty(F::Hessenberg, d::Symbol)
6666
return getfield(F, d)
6767
end
6868

69-
Base.propertynames(F::Hessenberg, private::Bool=false) = append!([:Q,:H], private ? fieldnames(typeof(F)) : Symbol[])
69+
Base.propertynames(F::Hessenberg, private::Bool=false) =
70+
(:Q, :H, (private ? fieldnames(typeof(F)) : ())...)
7071

7172
function getindex(A::HessenbergQ, i::Integer, j::Integer)
7273
x = zeros(eltype(A), size(A, 1))

stdlib/LinearAlgebra/src/lq.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ function getproperty(F::LQ, d::Symbol)
8585
end
8686
end
8787

88-
Base.propertynames(F::LQ, private::Bool=false) = append!([:L,:Q], private ? fieldnames(typeof(F)) : Symbol[])
88+
Base.propertynames(F::LQ, private::Bool=false) =
89+
(:L, :Q, (private ? fieldnames(typeof(F)) : ())...)
8990

9091
getindex(A::LQPackedQ, i::Integer, j::Integer) =
9192
lmul!(A, setindex!(zeros(eltype(A), size(A, 2)), 1, j))[i]

stdlib/LinearAlgebra/src/lu.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ function getproperty(F::LU{T,<:StridedMatrix}, d::Symbol) where T
268268
end
269269
end
270270

271-
Base.propertynames(F::LU, private::Bool=false) = append!([:L,:U,:p,:P], private ? fieldnames(typeof(F)) : Symbol[])
271+
Base.propertynames(F::LU, private::Bool=false) =
272+
(:L, :U, :p, :P, (private ? fieldnames(typeof(F)) : ())...)
272273

273274
issuccess(F::LU) = F.info == 0
274275

stdlib/LinearAlgebra/src/qr.jl

+5-2
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,9 @@ function getproperty(F::QRCompactWY, d::Symbol)
454454
getfield(F, d)
455455
end
456456
end
457-
Base.propertynames(F::Union{QR,QRCompactWY}, private::Bool=false) = append!([:R,:Q], private ? fieldnames(typeof(F)) : Symbol[])
457+
Base.propertynames(F::Union{QR,QRCompactWY}, private::Bool=false) =
458+
(:R, :Q, (private ? fieldnames(typeof(F)) : ())...)
459+
458460
function getproperty(F::QRPivoted{T}, d::Symbol) where T
459461
m, n = size(F)
460462
if d == :R
@@ -475,7 +477,8 @@ function getproperty(F::QRPivoted{T}, d::Symbol) where T
475477
getfield(F, d)
476478
end
477479
end
478-
Base.propertynames(F::QRPivoted, private::Bool=false) = append!([:R,:Q,:p,:P], private ? fieldnames(typeof(F)) : Symbol[])
480+
Base.propertynames(F::QRPivoted, private::Bool=false) =
481+
(:R, :Q, :p, :P, (private ? fieldnames(typeof(F)) : ())...)
479482

480483
abstract type AbstractQ{T} <: AbstractMatrix{T} end
481484

stdlib/LinearAlgebra/src/schur.jl

+4-2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ function getproperty(F::Schur, d::Symbol)
7777
end
7878
end
7979

80-
Base.propertynames(F::Schur) = append!([:Schur,:vectors], fieldnames(typeof(F)))
80+
Base.propertynames(F::Schur) =
81+
(:Schur, :vectors, fieldnames(typeof(F))...)
8182

8283
function show(io::IO, mime::MIME{Symbol("text/plain")}, F::Schur)
8384
println(io, summary(F))
@@ -280,7 +281,8 @@ function getproperty(F::GeneralizedSchur, d::Symbol)
280281
end
281282
end
282283

283-
Base.propertynames(F::GeneralizedSchur) = append!([:values,:left,:right], fieldnames(typeof(F)))
284+
Base.propertynames(F::GeneralizedSchur) =
285+
(:values, :left, :right, fieldnames(typeof(F))...)
284286

285287
"""
286288
schur(A::StridedMatrix, B::StridedMatrix) -> S::StridedMatrix, T::StridedMatrix, Q::StridedMatrix, Z::StridedMatrix, α::Vector, β::Vector

stdlib/LinearAlgebra/src/svd.jl

+4-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ function getproperty(F::SVD, d::Symbol)
186186
end
187187
end
188188

189-
Base.propertynames(F::SVD, private::Bool=false) = private ? append!([:V], fieldnames(typeof(F))) : [:U,:S,:V,:Vt]
189+
Base.propertynames(F::SVD, private::Bool=false) =
190+
private ? (:V, fieldnames(typeof(F))...) : (:U, :S, :V, :Vt)
190191

191192
"""
192193
svdvals!(A)
@@ -463,7 +464,8 @@ svd(x::Number, y::Number) = first.(svd(fill(x, 1, 1), fill(y, 1, 1)))
463464
end
464465
end
465466

466-
Base.propertynames(F::GeneralizedSVD) = append!([:alpha,:beta,:vals,:S,:D1,:D2,:R0], fieldnames(typeof(F)))
467+
Base.propertynames(F::GeneralizedSVD) =
468+
(:alpha, :beta, :vals, :S, :D1, :D2, :R0, fieldnames(typeof(F))...)
467469

468470
"""
469471
svdvals!(A, B)

stdlib/LinearAlgebra/test/lu.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ U factor:
266266
end
267267

268268
@testset "propertynames" begin
269-
names = sort!(string.(Base.propertynames(lufact(rand(3,3)))))
269+
names = sort!(collect(string.(Base.propertynames(lufact(rand(3,3))))))
270270
@test names == ["L", "P", "U", "p"]
271-
allnames = sort!(string.(Base.propertynames(lufact(rand(3,3)), true)))
271+
allnames = sort!(collect(string.(Base.propertynames(lufact(rand(3,3)), true))))
272272
@test allnames == ["L", "P", "U", "factors", "info", "ipiv", "p"]
273273
end
274274

test/reflection.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ mutable struct TLayout
218218
z::Int32
219219
end
220220
tlayout = TLayout(5,7,11)
221-
@test fieldnames(TLayout) == [:x, :y, :z] == Base.propertynames(tlayout)
221+
@test fieldnames(TLayout) == (:x, :y, :z) == Base.propertynames(tlayout)
222222
@test [(fieldoffset(TLayout,i), fieldname(TLayout,i), fieldtype(TLayout,i)) for i = 1:fieldcount(TLayout)] ==
223223
[(0, :x, Int8), (2, :y, Int16), (4, :z, Int32)]
224224
@test_throws BoundsError fieldtype(TLayout, 0)
@@ -232,7 +232,7 @@ tlayout = TLayout(5,7,11)
232232
@test fieldtype(Tuple{Vararg{Int8}}, 10) === Int8
233233
@test_throws BoundsError fieldtype(Tuple{Vararg{Int8}}, 0)
234234

235-
@test fieldnames(NTuple{3, Int}) == [fieldname(NTuple{3, Int}, i) for i = 1:3] == [1, 2, 3]
235+
@test fieldnames(NTuple{3, Int}) == ntuple(i -> fieldname(NTuple{3, Int}, i), 3) == (1, 2, 3)
236236
@test_throws BoundsError fieldname(NTuple{3, Int}, 0)
237237
@test_throws BoundsError fieldname(NTuple{3, Int}, 4)
238238

0 commit comments

Comments
 (0)