Skip to content

Commit

Permalink
deprecate whos to varinfo returning a markdown table. fixes #12131.
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Nov 20, 2017
1 parent ec8bc83 commit 6af5016
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 70 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,9 @@ Deprecated or removed
* Using Bool values directly as indices is now deprecated and will be an error in the future. Convert
them to `Int` before indexing if you intend to access index `1` for `true` and `0` for `false`.

* `whos` has been renamed `varinfo`, and now returns a markdown table instead of printing
output ([#12131]).

* `writecsv(io, a; opts...)` has been deprecated in favor of
`writedlm(io, a, ','; opts...)` ([#23529]).

Expand Down
8 changes: 8 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1927,6 +1927,14 @@ end
nothing
end

@deprecate whos(io::IO, m::Module, pat::Regex) show(io, varinfo(m, pat))
@deprecate whos(io::IO, m::Module) show(io, varinfo(m))
@deprecate whos(io::IO) show(io, varinfo())
@deprecate whos(m::Module, pat::Regex) varinfo(m, pat)
@deprecate whos(m::Module) varinfo(m)
@deprecate whos(pat::Regex) varinfo(pat)
@deprecate whos() varinfo()

# indexing with A[true] will throw an argument error in the future
function to_index(i::Bool)
depwarn("indexing with Bool values is deprecated. Convert the index to an integer first with `Int(i)`.", (:getindex, :setindex!, :view))
Expand Down
2 changes: 1 addition & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -953,9 +953,9 @@ export
module_name,
module_parent,
names,
varinfo,
versioninfo,
which,
whos,
workspace,
@isdefined,

Expand Down
60 changes: 15 additions & 45 deletions base/interactiveutil.jl
Original file line number Diff line number Diff line change
Expand Up @@ -731,54 +731,24 @@ end


"""
whos(io::IO=STDOUT, m::Module=Main, pattern::Regex=r"")
varinfo(m::Module=Main, pattern::Regex=r"")
Print information about exported global variables in a module, optionally restricted to those matching `pattern`.
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.
"""
function whos(io::IO=STDOUT, m::Module=Main, pattern::Regex=r"")
maxline = displaysize(io)[2]
line = zeros(UInt8, maxline)
head = PipeBuffer(maxline + 1)
for v in sort!(names(m))
s = string(v)
if isdefined(m, v) && ismatch(pattern, s)
value = getfield(m, v)
@printf head "%30s " s
try
if value (Base, Main, Core)
print(head, " ")
else
bytes = summarysize(value)
if bytes < 10_000
@printf(head, "%6d bytes ", bytes)
else
@printf(head, "%6d KB ", bytes ÷ (1024))
end
end
print(head, summary(value))
catch e
print(head, "#=ERROR: unable to show value=#")
end
newline = search(head, UInt8('\n')) - 1
if newline < 0
newline = nb_available(head)
end
if newline > maxline
newline = maxline - 1 # make space for ...
end
line = resize!(line, newline)
line = read!(head, line)
function varinfo(m::Module=Main, pattern::Regex=r"")
rows =
Any[ let value = getfield(m, v)
Any[string(v),
(value (Base, Main, Core) ? "" : format_bytes(summarysize(value))),
summary(value)]
end
for v in sort!(names(m)) if isdefined(m, v) && ismatch(pattern, string(v)) ]

write(io, line)
if nb_available(head) > 0 # more to read? replace with ...
print(io, '\u2026') # hdots
end
println(io)
seekend(head) # skip the rest of the text
end
end
unshift!(rows, Any["name", "size", "summary"])

return Markdown.MD(Any[Markdown.Table(rows, Symbol[:l, :r, :l])])
end
whos(m::Module, pat::Regex=r"") = whos(STDOUT, m, pat)
whos(pat::Regex) = whos(STDOUT, Main, pat)
varinfo(pat::Regex) = varinfo(Main, pat)
16 changes: 10 additions & 6 deletions base/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,25 @@ function padded_nonzero_print(value,str)
end
end

function format_bytes(bytes)
bytes, mb = prettyprint_getunits(bytes, length(_mem_units), Int64(1024))
if mb == 1
@sprintf("%d %s%s", bytes, _mem_units[mb], bytes==1 ? "" : "s")
else
@sprintf("%.3f %s", bytes, _mem_units[mb])
end
end

function time_print(elapsedtime, bytes, gctime, allocs)
@printf("%10.6f seconds", elapsedtime/1e9)
if bytes != 0 || allocs != 0
bytes, mb = prettyprint_getunits(bytes, length(_mem_units), Int64(1024))
allocs, ma = prettyprint_getunits(allocs, length(_cnt_units), Int64(1000))
if ma == 1
@printf(" (%d%s allocation%s: ", allocs, _cnt_units[ma], allocs==1 ? "" : "s")
else
@printf(" (%.2f%s allocations: ", allocs, _cnt_units[ma])
end
if mb == 1
@printf("%d %s%s", bytes, _mem_units[mb], bytes==1 ? "" : "s")
else
@printf("%.3f %s", bytes, _mem_units[mb])
end
print(format_bytes(bytes))
if gctime > 0
@printf(", %.2f%% gc time", 100*gctime/elapsedtime)
end
Expand Down
11 changes: 6 additions & 5 deletions doc/src/manual/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -567,11 +567,12 @@ julia> remotecall_fetch(()->gvar_self, 2)
"Node1"
julia> remotecall_fetch(whos, 2)
From worker 2: Base 41762 KB Module
From worker 2: Core 27337 KB Module
From worker 2: Foo 2477 bytes Module
From worker 2: Main 46191 KB Module
From worker 2: gvar_self 13 bytes String
name size summary
––––––––– –––––––– –––––––
Base Module
Core Module
Main Module
gvar_self 13 bytes String
```

This does not apply to `function` or `type` declarations. However, anonymous functions bound to global
Expand Down
2 changes: 1 addition & 1 deletion doc/src/manual/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ end
There are three important standard modules: Main, Core, and Base.

Main is the top-level module, and Julia starts with Main set as the current module. Variables
defined at the prompt go in Main, and `whos()` lists variables in Main.
defined at the prompt go in Main, and `varinfo()` lists variables in Main.

Core contains all identifiers considered "built in" to the language, i.e. part of the core language
and not libraries. Every module implicitly specifies `using Core`, since you can't do anything
Expand Down
13 changes: 7 additions & 6 deletions doc/src/manual/parallel-computing.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,13 @@ julia> let B = B
remotecall_fetch(()->B, 2)
end;
julia> @spawnat 2 whos();
julia> From worker 2: A 800 bytes 10×10 Array{Float64,2}
From worker 2: Base Module
From worker 2: Core Module
From worker 2: Main Module
julia> @fetchfrom 2 varinfo()
name size summary
––––––––– ––––––––– ––––––––––––––––––––––
A 800 bytes 10×10 Array{Float64,2}
Base Module
Core Module
Main Module
```

As can be seen, global variable `A` is defined on worker 2, but `B` is captured as a local variable
Expand Down
15 changes: 9 additions & 6 deletions test/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -327,13 +327,16 @@ let R = Ref{Any}(nothing), depth = 10^6
@test summarysize(R) == (depth + 4) * sizeof(Ptr)
end

module _test_whos_
module _test_varinfo_
export x
x = 1.0
end
@test sprint(whos, Main, r"^$") == ""
let v = sprint(whos, _test_whos_)
@test contains(v, "x 8 bytes Float64")
@test repr(varinfo(Main, r"^$")) == """
| name | size | summary |
|:---- | ----:|:------- |
"""
let v = repr(varinfo(_test_varinfo_))
@test contains(v, "| x | 8 bytes | Float64 |")
end

# issue #13021
Expand All @@ -351,9 +354,9 @@ module Tmp14173
export A
A = randn(2000, 2000)
end
whos(IOBuffer(), Tmp14173) # warm up
varinfo(Tmp14173) # warm up
const MEMDEBUG = ccall(:jl_is_memdebug, Bool, ())
@test @allocated(whos(IOBuffer(), Tmp14173)) < (MEMDEBUG ? 30000 : 10000)
@test @allocated(varinfo(Tmp14173)) < (MEMDEBUG ? 60000 : 20000)

## test conversion from UTF-8 to UTF-16 (for Windows APIs)

Expand Down

0 comments on commit 6af5016

Please sign in to comment.