• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37433

pending completion
#37433

push

local

web-flow
Merge pull request #48513 from JuliaLang/jn/extend-once

ensure extension triggers are only run by the package that satified them

60 of 60 new or added lines in 1 file covered. (100.0%)

72324 of 82360 relevant lines covered (87.81%)

31376331.4 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.35
/stdlib/InteractiveUtils/src/InteractiveUtils.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
module InteractiveUtils
4

5
Base.Experimental.@optlevel 1
6

7
export apropos, edit, less, code_warntype, code_llvm, code_native, methodswith, varinfo,
8
    versioninfo, subtypes, supertypes, @which, @edit, @less, @functionloc, @code_warntype,
9
    @code_typed, @code_lowered, @code_llvm, @code_native, @time_imports, clipboard
10

11
import Base.Docs.apropos
12

13
using Base: unwrap_unionall, rewrap_unionall, isdeprecated, Bottom, show_unquoted, summarysize,
14
    signature_type, format_bytes
15

16
using Markdown
17

18
include("editless.jl")
19
include("codeview.jl")
20
include("macros.jl")
21
include("clipboard.jl")
22

23
"""
24
    varinfo(m::Module=Main, pattern::Regex=r""; all::Bool = false, imported::Bool = false, sortby::Symbol = :name, minsize::Int = 0)
25

26
Return a markdown table giving information about exported global variables in a module, optionally restricted
27
to those matching `pattern`.
28

29
The memory consumption estimate is an approximate lower bound on the size of the internal structure of the object.
30

31
- `all` : also list non-exported objects defined in the module, deprecated objects, and compiler-generated objects.
32
- `imported` : also list objects explicitly imported from other modules.
33
- `recursive` : recursively include objects in sub-modules, observing the same settings in each.
34
- `sortby` : the column to sort results by. Options are `:name` (default), `:size`, and `:summary`.
35
- `minsize` : only includes objects with size at least `minsize` bytes. Defaults to `0`.
36
"""
37
function varinfo(m::Module=Base.active_module(), pattern::Regex=r""; all::Bool = false, imported::Bool = false, sortby::Symbol = :name, recursive::Bool = false, minsize::Int=0)
32✔
38
    sortby in (:name, :size, :summary) || throw(ArgumentError("Unrecognized `sortby` value `:$sortby`. Possible options are `:name`, `:size`, and `:summary`"))
11✔
39
    rows = Vector{Any}[]
11✔
40
    workqueue = [(m, ""),]
11✔
41
    while !isempty(workqueue)
23✔
42
        m2, prep = popfirst!(workqueue)
12✔
43
        for v in names(m2; all, imported)
12✔
44
            if !isdefined(m2, v) || !occursin(pattern, string(v))
154✔
45
                continue
18✔
46
            end
47
            value = getfield(m2, v)
59✔
48
            isbuiltin = value === Base || value === Base.active_module() || value === Core
118✔
49
            if recursive && !isbuiltin && isa(value, Module) && value !== m2 && nameof(value) === v && parentmodule(value) === m2
59✔
50
                push!(workqueue, (value, "$prep$v."))
1✔
51
            end
52
            ssize_str, ssize = if isbuiltin
59✔
53
                    ("", typemax(Int))
×
54
                else
55
                    ss = summarysize(value)
59✔
56
                    (format_bytes(ss), ss)
118✔
57
                end
58
            if ssize >= minsize
59✔
59
                push!(rows, Any[string(prep, v), ssize_str, summary(value), ssize])
55✔
60
            end
61
        end
89✔
62
    end
12✔
63
    let (col, rev) = if sortby === :name
11✔
64
            1, false
9✔
65
        elseif sortby === :size
2✔
66
            4, true
1✔
67
        elseif sortby === :summary
1✔
68
            3, false
1✔
69
        else
70
            @assert "unreachable"
25✔
71
        end
72
        sort!(rows; by=r->r[col], rev)
190✔
73
    end
74
    pushfirst!(rows, Any["name", "size", "summary"])
33✔
75

76
    return Markdown.MD(Any[Markdown.Table(map(r->r[1:3], rows), Symbol[:l, :r, :l])])
77✔
77
end
78
varinfo(pat::Regex; kwargs...) = varinfo(Base.active_module(), pat; kwargs...)
×
79

80
"""
81
    versioninfo(io::IO=stdout; verbose::Bool=false)
82

83
Print information about the version of Julia in use. The output is
84
controlled with boolean keyword arguments:
85

86
- `verbose`: print all additional information
87

88
!!! warning "Warning"
89
    The output of this function may contain sensitive information. Before sharing the output,
90
    please review the output and remove any data that should not be shared publicly.
91

92
See also: [`VERSION`](@ref).
93
"""
94
function versioninfo(io::IO=stdout; verbose::Bool=false)
15✔
95
    println(io, "Julia Version $VERSION")
6✔
96
    if !isempty(Base.GIT_VERSION_INFO.commit_short)
6✔
97
        println(io, "Commit $(Base.GIT_VERSION_INFO.commit_short) ($(Base.GIT_VERSION_INFO.date_string))")
6✔
98
    end
99
    if Base.isdebugbuild()
6✔
100
        println(io, "DEBUG build")
×
101
    end
102
    println(io, "Platform Info:")
6✔
103
    println(io, "  OS: ", Sys.iswindows() ? "Windows" : Sys.isapple() ?
6✔
104
        "macOS" : Sys.KERNEL, " (", Sys.MACHINE, ")")
105

106
    if verbose
6✔
107
        lsb = ""
1✔
108
        if Sys.islinux()
1✔
109
            try lsb = readchomp(pipeline(`lsb_release -ds`, stderr=devnull)); catch; end
3✔
110
        end
111
        if Sys.iswindows()
1✔
112
            try lsb = strip(read(`$(ENV["COMSPEC"]) /c ver`, String)); catch; end
×
113
        end
114
        if !isempty(lsb)
2✔
115
            println(io, "      ", lsb)
×
116
        end
117
        if Sys.isunix()
1✔
118
            println(io, "  uname: ", readchomp(`uname -mprsv`))
1✔
119
        end
120
    end
121

122
    if verbose
6✔
123
        cpuio = IOBuffer() # print cpu_summary with correct alignment
1✔
124
        Sys.cpu_summary(cpuio)
1✔
125
        for (i, line) in enumerate(split(chomp(String(take!(cpuio))), "\n"))
2✔
126
            prefix = i == 1 ? "  CPU: " : "       "
3✔
127
            println(io, prefix, line)
3✔
128
        end
5✔
129
    else
130
        cpu = Sys.cpu_info()
5✔
131
        println(io, "  CPU: ", length(cpu), " × ", cpu[1].model)
5✔
132
    end
133

134
    if verbose
6✔
135
        println(io, "  Memory: $(Sys.total_memory()/2^30) GB ($(Sys.free_memory()/2^20) MB free)")
2✔
136
        try println(io, "  Uptime: $(Sys.uptime()) sec"); catch; end
2✔
137
        print(io, "  Load Avg: ")
1✔
138
        Base.print_matrix(io, Sys.loadavg()')
1✔
139
        println(io)
1✔
140
    end
141
    println(io, "  WORD_SIZE: ", Sys.WORD_SIZE)
6✔
142
    println(io, "  LIBM: ",Base.libm_name)
6✔
143
    println(io, "  LLVM: libLLVM-",Base.libllvm_version," (", Sys.JIT, ", ", Sys.CPU_NAME, ")")
6✔
144
    println(io, "  Threads: ", Threads.maxthreadid(), " on ", Sys.CPU_THREADS, " virtual cores")
6✔
145

146
    function is_nonverbose_env(k::String)
521✔
147
        return occursin(r"^JULIA_|^DYLD_|^LD_", k)
515✔
148
    end
149
    function is_verbose_env(k::String)
130✔
150
        return occursin(r"PATH|FLAG|^TERM$|HOME", k) && !is_nonverbose_env(k)
124✔
151
    end
152
    env_strs = String[
11✔
153
        String["  $(k) = $(v)" for (k,v) in ENV if is_nonverbose_env(uppercase(k))];
154
        (verbose ?
155
         String["  $(k) = $(v)" for (k,v) in ENV if is_verbose_env(uppercase(k))] :
156
         String[]);
157
    ]
158
    if !isempty(env_strs)
6✔
159
        println(io, "Environment:")
5✔
160
        for str in env_strs
5✔
161
            println(io, str)
35✔
162
        end
36✔
163
    end
164
end
165

166

167
function type_close_enough(@nospecialize(x), @nospecialize(t))
83,935✔
168
    x == t && return true
83,935✔
169
    # TODO: handle UnionAll properly
170
    return (isa(x, DataType) && isa(t, DataType) && x.name === t.name && x <: t) ||
83,524✔
171
           (isa(x, Union) && isa(t, DataType) && (type_close_enough(x.a, t) || type_close_enough(x.b, t)))
172
end
173

174
# `methodswith` -- shows a list of methods using the type given
175
"""
176
    methodswith(typ[, module or function]; supertypes::Bool=false])
177

178
Return an array of methods with an argument of type `typ`.
179

180
The optional second argument restricts the search to a particular module or function
181
(the default is all top-level modules).
182

183
If keyword `supertypes` is `true`, also return arguments with a parent type of `typ`,
184
excluding type `Any`.
185
"""
186
function methodswith(@nospecialize(t::Type), @nospecialize(f::Base.Callable), meths = Method[]; supertypes::Bool=false)
6,646✔
187
    for d in methods(f)
6,546✔
188
        if any(function (x)
102,254✔
189
                   let x = rewrap_unionall(x, d.sig)
90,623✔
190
                       (type_close_enough(x, t) ||
74,884✔
191
                        (supertypes ? (isa(x, Type) && t <: x && (!isa(x,TypeVar) || x.ub != Any)) :
192
                         (isa(x,TypeVar) && x.ub != Any && t == x.ub)) &&
193
                        x != Any)
194
                   end
195
               end,
196
               unwrap_unionall(d.sig).parameters)
197
            push!(meths, d)
411✔
198
        end
199
    end
51,517✔
200
    return meths
3,323✔
201
end
202

203
function _methodswith(@nospecialize(t::Type), m::Module, supertypes::Bool)
90✔
204
    meths = Method[]
90✔
205
    for nm in names(m)
90✔
206
        if isdefined(m, nm)
5,491✔
207
            f = getfield(m, nm)
5,491✔
208
            if isa(f, Base.Callable)
5,491✔
209
                methodswith(t, f, meths; supertypes = supertypes)
4,148✔
210
            end
211
        end
212
    end
5,581✔
213
    return unique(meths)
90✔
214
end
215

216
methodswith(@nospecialize(t::Type), m::Module; supertypes::Bool=false) = _methodswith(t, m, supertypes)
4✔
217

218
function methodswith(@nospecialize(t::Type); supertypes::Bool=false)
4✔
219
    meths = Method[]
2✔
220
    for mod in Base.loaded_modules_array()
2✔
221
        append!(meths, _methodswith(t, mod, supertypes))
88✔
222
    end
90✔
223
    return unique(meths)
2✔
224
end
225

226
# subtypes
227
function _subtypes_in!(mods::Array, x::Type)
22✔
228
    xt = unwrap_unionall(x)
22✔
229
    if !isabstracttype(x) || !isa(xt, DataType)
34✔
230
        # Fast path
231
        return Type[]
10✔
232
    end
233
    sts = Vector{Any}()
12✔
234
    while !isempty(mods)
2,052✔
235
        m = pop!(mods)
2,040✔
236
        xt = xt::DataType
2,040✔
237
        for s in names(m, all = true)
2,040✔
238
            if isdefined(m, s) && !isdeprecated(m, s)
416,318✔
239
                t = getfield(m, s)
416,277✔
240
                dt = isa(t, UnionAll) ? unwrap_unionall(t) : t
416,277✔
241
                if isa(dt, DataType)
416,277✔
242
                    if dt.name.name === s && dt.name.module == m && supertype(dt).name == xt.name
235,729✔
243
                        ti = typeintersect(t, x)
33✔
244
                        ti != Bottom && push!(sts, ti)
33✔
245
                    end
246
                elseif isa(t, Module) && nameof(t) === s && parentmodule(t) === m && t !== m
180,548✔
247
                    t === Base || push!(mods, t) # exclude Base, since it also parented by Main
1,524✔
248
                end
249
            end
250
        end
418,358✔
251
    end
2,040✔
252
    return permute!(sts, sortperm(map(string, sts)))
12✔
253
end
254

255
subtypes(m::Module, x::Type) = _subtypes_in!([m], x)
×
256

257
"""
258
    subtypes(T::DataType)
259

260
Return a list of immediate subtypes of DataType `T`. Note that all currently loaded subtypes
261
are included, including those not visible in the current module.
262

263
See also [`supertype`](@ref), [`supertypes`](@ref), [`methodswith`](@ref).
264

265
# Examples
266
```jldoctest
267
julia> subtypes(Integer)
268
3-element Vector{Any}:
269
 Bool
270
 Signed
271
 Unsigned
272
```
273
"""
274
subtypes(x::Type) = _subtypes_in!(Base.loaded_modules_array(), x)
22✔
275

276
"""
277
    supertypes(T::Type)
278

279
Return a tuple `(T, ..., Any)` of `T` and all its supertypes, as determined by
280
successive calls to the [`supertype`](@ref) function, listed in order of `<:`
281
and terminated by `Any`.
282

283
See also [`subtypes`](@ref).
284

285
# Examples
286
```jldoctest
287
julia> supertypes(Int)
288
(Int64, Signed, Integer, Real, Number, Any)
289
```
290
"""
291
function supertypes(T::Type)
10✔
292
    S = supertype(T)
14✔
293
    # note: we return a tuple here, not an Array as for subtypes, because in
294
    #       the future we could evaluate this function statically if desired.
295
    return S === T ? (T,) : (T, supertypes(S)...)
10✔
296
end
297

298
# TODO: @deprecate peakflops to LinearAlgebra
299
export peakflops
300
"""
301
    peakflops(n::Integer=2000; parallel::Bool=false)
302

303
`peakflops` computes the peak flop rate of the computer by using double precision
304
[`gemm!`](@ref LinearAlgebra.BLAS.gemm!). For more information see
305
[`LinearAlgebra.peakflops`](@ref).
306

307
!!! compat "Julia 1.1"
308
    This function will be moved from `InteractiveUtils` to `LinearAlgebra` in the
309
    future. In Julia 1.1 and later it is available as `LinearAlgebra.peakflops`.
310
"""
311
function peakflops(n::Integer=2000; parallel::Bool=false)
×
312
    # Base.depwarn("`peakflop`s have moved to the LinearAlgebra module, " *
313
    #              "add `using LinearAlgebra` to your imports.", :peakflops)
314
    let LinearAlgebra = Base.require(Base.PkgId(
×
315
            Base.UUID((0x37e2e46d_f89d_539d,0xb4ee_838fcccc9c8e)), "LinearAlgebra"))
316
        return LinearAlgebra.peakflops(n; parallel = parallel)
×
317
    end
318
end
319

320
function report_bug(kind)
×
321
    @info "Loading BugReporting package..."
×
322
    BugReportingId = Base.PkgId(
×
323
        Base.UUID((0xbcf9a6e7_4020_453c,0xb88e_690564246bb8)), "BugReporting")
324
    # Check if the BugReporting package exists in the current environment
325
    local BugReporting
×
326
    if Base.locate_package(BugReportingId) === nothing
×
327
        @info "Package `BugReporting` not found - attempting temporary installation"
×
328
        # Create a temporary environment and add BugReporting
329
        let Pkg = Base.require(Base.PkgId(
×
330
            Base.UUID((0x44cfe95a_1eb2_52ea,0xb672_e2afdf69b78f)), "Pkg"))
331
            mktempdir() do tmp
×
332
                old_load_path = copy(LOAD_PATH)
×
333
                push!(empty!(LOAD_PATH), joinpath(tmp, "Project.toml"))
×
334
                old_active_project = Base.ACTIVE_PROJECT[]
×
335
                Base.ACTIVE_PROJECT[] = nothing
×
336
                Pkg.add(Pkg.PackageSpec(BugReportingId.name, BugReportingId.uuid))
×
337
                BugReporting = Base.require(BugReportingId)
×
338
                append!(empty!(LOAD_PATH), old_load_path)
×
339
                Base.ACTIVE_PROJECT[] = old_active_project
×
340
            end
341
        end
342
    else
343
        BugReporting = Base.require(BugReportingId)
×
344
    end
345
    return Base.invokelatest(BugReporting.make_interactive_report, kind, ARGS)
×
346
end
347

348
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc