From 1024fd43320251f216c8c6b651ea1554f89780fa Mon Sep 17 00:00:00 2001 From: Ian Date: Thu, 15 Oct 2020 11:31:28 -0400 Subject: [PATCH 1/5] add options for varinfo to show all and imported, and sort by size --- .../InteractiveUtils/src/InteractiveUtils.jl | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/stdlib/InteractiveUtils/src/InteractiveUtils.jl b/stdlib/InteractiveUtils/src/InteractiveUtils.jl index af9e720112e33..22a0488ddbdd3 100644 --- a/stdlib/InteractiveUtils/src/InteractiveUtils.jl +++ b/stdlib/InteractiveUtils/src/InteractiveUtils.jl @@ -21,27 +21,36 @@ include("macros.jl") include("clipboard.jl") """ - varinfo(m::Module=Main, pattern::Regex=r"") + varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported::Bool = false, sort_size::Bool = false) Return a markdown table giving information about exported global variables in a module, optionally restricted to those matching `pattern`. The memory consumption estimate is an approximate lower bound on the size of the internal structure of the object. + +- `all` : also list non-exported objects defined in the module, deprecated objects, and compiler-generated objects. +- `imported` : also list objects explicitly imported from other modules. +- `sort_size` : sort results by their size, in descending order """ -function varinfo(m::Module=Main, pattern::Regex=r"") +function varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported::Bool = false, sort_size::Bool = false) rows = Any[ let value = getfield(m, v) Any[string(v), (value===Base || value===Main || value===Core ? "" : format_bytes(summarysize(value))), - summary(value)] + summary(value), + summarysize(value)] end - for v in sort!(names(m)) if isdefined(m, v) && occursin(pattern, string(v)) ] - + for v in sort!(names(m, all = all, imported = imported)) if isdefined(m, v) && occursin(pattern, string(v)) ] + if sort_size + sizes = map(r->r[4], rows) + p = sortperm(sizes, rev=true) + rows = rows[p] + end pushfirst!(rows, Any["name", "size", "summary"]) - return Markdown.MD(Any[Markdown.Table(rows, Symbol[:l, :r, :l])]) + return Markdown.MD(Any[Markdown.Table(map(r->r[1:3], rows), Symbol[:l, :r, :l])]) end -varinfo(pat::Regex) = varinfo(Main, pat) +varinfo(pat::Regex; kwargs...) = varinfo(Main, pat, kwargs...) """ versioninfo(io::IO=stdout; verbose::Bool=false) From d05721e15c54d278968f33665ddcbde817f532be Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 16 Oct 2020 17:54:38 -0400 Subject: [PATCH 2/5] extend varinfo tests --- stdlib/InteractiveUtils/test/runtests.jl | 26 +++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/stdlib/InteractiveUtils/test/runtests.jl b/stdlib/InteractiveUtils/test/runtests.jl index 04d0e7afebc20..db700be8fa8d0 100644 --- a/stdlib/InteractiveUtils/test/runtests.jl +++ b/stdlib/InteractiveUtils/test/runtests.jl @@ -153,15 +153,35 @@ mktemp() do f, io end module _test_varinfo_ -export x -x = 1.0 +import Test: @test +export exported +exported = 1.0 +not_exp = 1.0 +z_larger = Vector{Float64}(undef, 3) +a_smaller = Vector{Float64}(undef, 2) end @test repr(varinfo(Main, r"^$")) == """ | name | size | summary | |:---- | ----:|:------- | """ let v = repr(varinfo(_test_varinfo_)) - @test occursin("| x | 8 bytes | Float64 |", v) + @test occursin("| exported | 8 bytes | Float64 |", v) + @test !occursin("not_exp", v) + @test !occursin("@test", v) +end +let v = repr(varinfo(_test_varinfo_, all = true)) + @test occursin("exported", v) + @test occursin("not_exp", v) + @test !occursin("@test", v) + @test findfirst("a_smaller", v)[1] < findfirst("z_larger", v)[1] # check for alphabetical +end +let v = repr(varinfo(_test_varinfo_, imported = true)) + @test occursin("exported", v) + @test !occursin("not_exp", v) + @test occursin("@test", v) +end +let v = repr(varinfo(_test_varinfo_, all=true, sort_size = true)) + @test findfirst("z_larger", v)[1] < findfirst("a_smaller", v)[1] # check for size order end # Issue 14173 From 126ebc7fae3310412de2406d4d1a6bb742a70ebf Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 19 Oct 2020 14:13:16 -0400 Subject: [PATCH 3/5] better sort --- stdlib/InteractiveUtils/src/InteractiveUtils.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/stdlib/InteractiveUtils/src/InteractiveUtils.jl b/stdlib/InteractiveUtils/src/InteractiveUtils.jl index 22a0488ddbdd3..5150027cef027 100644 --- a/stdlib/InteractiveUtils/src/InteractiveUtils.jl +++ b/stdlib/InteractiveUtils/src/InteractiveUtils.jl @@ -42,9 +42,7 @@ function varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported end for v in sort!(names(m, all = all, imported = imported)) if isdefined(m, v) && occursin(pattern, string(v)) ] if sort_size - sizes = map(r->r[4], rows) - p = sortperm(sizes, rev=true) - rows = rows[p] + rows = sort!(rows, by=r->r[4], rev=true) end pushfirst!(rows, Any["name", "size", "summary"]) From 003e88a745129b76886c0bed348caf29e1627ef2 Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 19 Oct 2020 18:55:35 -0400 Subject: [PATCH 4/5] switch to `sortby` with colnames --- stdlib/InteractiveUtils/src/InteractiveUtils.jl | 13 ++++++++----- stdlib/InteractiveUtils/test/runtests.jl | 5 ++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/stdlib/InteractiveUtils/src/InteractiveUtils.jl b/stdlib/InteractiveUtils/src/InteractiveUtils.jl index 5150027cef027..039432be97964 100644 --- a/stdlib/InteractiveUtils/src/InteractiveUtils.jl +++ b/stdlib/InteractiveUtils/src/InteractiveUtils.jl @@ -21,7 +21,7 @@ include("macros.jl") include("clipboard.jl") """ - varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported::Bool = false, sort_size::Bool = false) + varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported::Bool = false, sortby::Symbol = :name) Return a markdown table giving information about exported global variables in a module, optionally restricted to those matching `pattern`. @@ -30,9 +30,10 @@ The memory consumption estimate is an approximate lower bound on the size of the - `all` : also list non-exported objects defined in the module, deprecated objects, and compiler-generated objects. - `imported` : also list objects explicitly imported from other modules. -- `sort_size` : sort results by their size, in descending order +- `sortby` : the column to sort results by. Options are `:name` (default), `:size`, and `:summary`. """ -function varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported::Bool = false, sort_size::Bool = false) +function varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported::Bool = false, sortby::Symbol = :name) + @assert sortby in [:name, :size, :summary] "Unrecognized `sortby` value `:$sortby`. Possible options are `:name`, `:size`, and `:summary`" rows = Any[ let value = getfield(m, v) Any[string(v), @@ -41,8 +42,10 @@ function varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported summarysize(value)] end for v in sort!(names(m, all = all, imported = imported)) if isdefined(m, v) && occursin(pattern, string(v)) ] - if sort_size - rows = sort!(rows, by=r->r[4], rev=true) + if sortby != :name + col = sortby == :size ? 4 : 3 # if it's not :size, it must be :summary here + reverse = sortby == :size ? true : false + rows = sort!(rows, by=r->r[col], rev=reverse) end pushfirst!(rows, Any["name", "size", "summary"]) diff --git a/stdlib/InteractiveUtils/test/runtests.jl b/stdlib/InteractiveUtils/test/runtests.jl index db700be8fa8d0..664ff22455166 100644 --- a/stdlib/InteractiveUtils/test/runtests.jl +++ b/stdlib/InteractiveUtils/test/runtests.jl @@ -180,9 +180,12 @@ let v = repr(varinfo(_test_varinfo_, imported = true)) @test !occursin("not_exp", v) @test occursin("@test", v) end -let v = repr(varinfo(_test_varinfo_, all=true, sort_size = true)) +let v = repr(varinfo(_test_varinfo_, all = true, sortby = :size)) @test findfirst("z_larger", v)[1] < findfirst("a_smaller", v)[1] # check for size order end +let v = repr(varinfo(_test_varinfo_, sortby = :summary)) + @test findfirst("Float64", v)[1] < findfirst("Module", v)[1] # check for summary order +end # Issue 14173 module Tmp14173 From 8ec6ad2ee332cc535984ecbbd036a00a0e6b8814 Mon Sep 17 00:00:00 2001 From: Ian Date: Thu, 22 Oct 2020 02:54:33 -0400 Subject: [PATCH 5/5] add option to inspect objects from sub-modules recursively --- .../InteractiveUtils/src/InteractiveUtils.jl | 47 ++++++++++++++----- stdlib/InteractiveUtils/test/runtests.jl | 30 ++++++++---- 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/stdlib/InteractiveUtils/src/InteractiveUtils.jl b/stdlib/InteractiveUtils/src/InteractiveUtils.jl index 039432be97964..ead87cde431f0 100644 --- a/stdlib/InteractiveUtils/src/InteractiveUtils.jl +++ b/stdlib/InteractiveUtils/src/InteractiveUtils.jl @@ -30,23 +30,44 @@ The memory consumption estimate is an approximate lower bound on the size of the - `all` : also list non-exported objects defined in the module, deprecated objects, and compiler-generated objects. - `imported` : also list objects explicitly imported from other modules. +- `recursive` : recursively include objects in sub-modules, observing the same settings in each. - `sortby` : the column to sort results by. Options are `:name` (default), `:size`, and `:summary`. """ -function varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported::Bool = false, sortby::Symbol = :name) +function varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported::Bool = false, sortby::Symbol = :name, recursive::Bool = false) @assert sortby in [:name, :size, :summary] "Unrecognized `sortby` value `:$sortby`. Possible options are `:name`, `:size`, and `:summary`" - rows = - Any[ let value = getfield(m, v) - Any[string(v), - (value===Base || value===Main || value===Core ? "" : format_bytes(summarysize(value))), - summary(value), - summarysize(value)] - end - for v in sort!(names(m, all = all, imported = imported)) if isdefined(m, v) && occursin(pattern, string(v)) ] - if sortby != :name - col = sortby == :size ? 4 : 3 # if it's not :size, it must be :summary here - reverse = sortby == :size ? true : false - rows = sort!(rows, by=r->r[col], rev=reverse) + function _populate_rows(m2::Module, allrows, include_self::Bool, prep::String) + newrows = Any[ + let + value = getfield(m2, v) + ssize_str, ssize = if value===Base || value===Main || value===Core + ("", typemax(Int)) + else + ss = summarysize(value) + (format_bytes(ss), ss) + end + Any[string(prep, v), ssize_str, summary(value), ssize] + end + for v in names(m2; all, imported) + if (string(v) != split(string(m2), ".")[end] || include_self) && isdefined(m2, v) && occursin(pattern, string(v)) ] + append!(allrows, newrows) + if recursive + for row in newrows + if row[3] == "Module" && !in(split(row[1], ".")[end], [split(string(m2), ".")[end], "Base", "Main", "Core"]) + _populate_rows(getfield(m2, Symbol(split(row[1], ".")[end])), allrows, false, prep * "$(row[1]).") + end + end + end + return allrows + end + rows = _populate_rows(m, Vector{Any}[], true, "") + if sortby == :name + col, reverse = 1, false + elseif sortby == :size + col, reverse = 4, true + elseif sortby == :summary + col, reverse = 3, false end + rows = sort!(rows, by=r->r[col], rev=reverse) pushfirst!(rows, Any["name", "size", "summary"]) return Markdown.MD(Any[Markdown.Table(map(r->r[1:3], rows), Symbol[:l, :r, :l])]) diff --git a/stdlib/InteractiveUtils/test/runtests.jl b/stdlib/InteractiveUtils/test/runtests.jl index 664ff22455166..6df0670f1ddd0 100644 --- a/stdlib/InteractiveUtils/test/runtests.jl +++ b/stdlib/InteractiveUtils/test/runtests.jl @@ -153,32 +153,41 @@ mktemp() do f, io end module _test_varinfo_ +module inner_mod +inner_x = 1 +end import Test: @test -export exported -exported = 1.0 -not_exp = 1.0 +export x_exported +x_exported = 1.0 +y_not_exp = 1.0 z_larger = Vector{Float64}(undef, 3) a_smaller = Vector{Float64}(undef, 2) end + +using Test + @test repr(varinfo(Main, r"^$")) == """ | name | size | summary | |:---- | ----:|:------- | """ let v = repr(varinfo(_test_varinfo_)) - @test occursin("| exported | 8 bytes | Float64 |", v) - @test !occursin("not_exp", v) + @test occursin("| x_exported | 8 bytes | Float64 |", v) + @test !occursin("y_not_exp", v) @test !occursin("@test", v) + @test !occursin("inner_x", v) end let v = repr(varinfo(_test_varinfo_, all = true)) - @test occursin("exported", v) - @test occursin("not_exp", v) + @test occursin("x_exported", v) + @test occursin("y_not_exp", v) @test !occursin("@test", v) @test findfirst("a_smaller", v)[1] < findfirst("z_larger", v)[1] # check for alphabetical + @test !occursin("inner_x", v) end let v = repr(varinfo(_test_varinfo_, imported = true)) - @test occursin("exported", v) - @test !occursin("not_exp", v) + @test occursin("x_exported", v) + @test !occursin("y_not_exp", v) @test occursin("@test", v) + @test !occursin("inner_x", v) end let v = repr(varinfo(_test_varinfo_, all = true, sortby = :size)) @test findfirst("z_larger", v)[1] < findfirst("a_smaller", v)[1] # check for size order @@ -186,6 +195,9 @@ end let v = repr(varinfo(_test_varinfo_, sortby = :summary)) @test findfirst("Float64", v)[1] < findfirst("Module", v)[1] # check for summary order end +let v = repr(varinfo(_test_varinfo_, all = true, recursive = true)) + @test occursin("inner_x", v) +end # Issue 14173 module Tmp14173