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

JuliaLang / julia / 1560

07 Jun 2026 04:53PM UTC coverage: 77.469% (-0.3%) from 77.813%
1560

push

buildkite

web-flow
gf.c: skip dispatch cache re-checks when no mt insertions since check (#62031)

65580 of 84653 relevant lines covered (77.47%)

15278206.21 hits per line

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

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

3
"""
4
The `InteractiveUtils` module provides utilities for interactive use of Julia,
5
such as code introspection and clipboard access.
6
It is intended for interactive work and is loaded automatically in interactive mode.
7
"""
8
module InteractiveUtils
9

10
Base.Experimental.@optlevel 1
11

12
export apropos, edit, less, code_warntype, code_llvm, code_native, methodswith, varinfo,
13
    versioninfo, subtypes, supertypes, @which, @edit, @less, @functionloc, @code_warntype,
14
    @code_typed, @code_lowered, @code_llvm, @code_native, @time_imports, clipboard,
15
    has_system_clipboard, @trace_compile, @trace_dispatch, @activate
16

17
import Base.Docs.apropos
18

19
using Base: unsorted_names, unwrap_unionall, rewrap_unionall, isdeprecated, Bottom, summarysize,
20
    signature_type, format_bytes
21
using Base.Libc
22
using Markdown
23

24
include("editless.jl")
25
include("codeview.jl")
26
include("macros.jl")
27
include("clipboard.jl")
28

29
"""
30
    varinfo(m::Module=Main, pattern::Regex=r""; all=false, imported=false, recursive=false, sortby::Symbol=:name, minsize::Int=0)
31

32
Return a markdown table giving information about public global variables in a module, optionally restricted
33
to those matching `pattern`.
34

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

37
- `all` : also list non-public objects defined in the module, deprecated objects, and compiler-generated objects.
38
- `imported` : also list objects explicitly imported from other modules.
39
- `recursive` : recursively include objects in sub-modules, observing the same settings in each.
40
- `sortby` : the column to sort results by. Options are `:name` (default), `:size`, and `:summary`.
41
- `minsize` : only includes objects with size at least `minsize` bytes. Defaults to `0`.
42

43
The output of `varinfo` is intended for display purposes only.  See also [`names`](@ref) to get an array of symbols defined in
44
a module, which is suitable for more general manipulations.
45
"""
46
function varinfo(m::Module=Base.active_module(), pattern::Regex=r""; all::Bool = false, imported::Bool = false, recursive::Bool = false, sortby::Symbol = :name, minsize::Int=0, world::UInt=Base.get_world_counter())
76✔
47
    sortby in (:name, :size, :summary) || throw(ArgumentError("Unrecognized `sortby` value `:$sortby`. Possible options are `:name`, `:size`, and `:summary`"))
26✔
48
    rows = Vector{Any}[]
26✔
49
    workqueue = [(m, ""),]
26✔
50
    while !isempty(workqueue)
54✔
51
        m2, prep = popfirst!(workqueue)
28✔
52
        for v in names(m2; all, imported, world)
28✔
53
            if !Base.invoke_in_world(world, isdefined, m2, v) || !occursin(pattern, string(v))
292✔
54
                continue
37✔
55
            end
56
            value = Base.invoke_in_world(world, getglobal, m2, v)
110✔
57
            isbuiltin = value === Base || value === Base.active_module() || value === Core
220✔
58
            if recursive && !isbuiltin && isa(value, Module) && value !== m2 && nameof(value) === v && parentmodule(value) === m2
110✔
59
                push!(workqueue, (value, "$prep$v."))
2✔
60
            end
61
            ssize_str, ssize = if isbuiltin
110✔
62
                    ("", typemax(Int))
×
63
                else
64
                    ss = summarysize(value)
110✔
65
                    (format_bytes(ss), ss)
220✔
66
                end
67
            if ssize >= minsize
110✔
68
                push!(rows, Any[string(prep, v), ssize_str, summary(value), ssize])
102✔
69
            end
70
        end
147✔
71
    end
28✔
72
    let (col, rev) = if sortby === :name
26✔
73
            1, false
22✔
74
        elseif sortby === :size
4✔
75
            4, true
2✔
76
        elseif sortby === :summary
2✔
77
            3, false
2✔
78
        else
79
            @assert "unreachable"
30✔
80
        end
81
        sort!(rows; by=r->r[col], rev)
332✔
82
    end
83
    pushfirst!(rows, Any["name", "size", "summary"])
52✔
84

85
    return Markdown.MD(Any[Markdown.Table(map(r->r[1:3], rows), Symbol[:l, :r, :l])])
282✔
86
end
87
varinfo(pat::Regex; kwargs...) = varinfo(Base.active_module(), pat; kwargs...)
×
88

89
"""
90
    versioninfo(io::IO=stdout; verbose::Bool=false)
91

92
Print information about the version of Julia in use. The output is
93
controlled with boolean keyword arguments:
94

95
- `verbose`: print all additional information
96

97
!!! warning "Warning"
98
    The output of this function may contain sensitive information. Before sharing the output,
99
    please review the output and remove any data that should not be shared publicly.
100

101
See also: [`VERSION`](@ref).
102
"""
103
function versioninfo(io::IO=stdout; verbose::Bool=false)
28✔
104
    println(io, "Julia Version $VERSION")
10✔
105
    println(io, "Build Info:")
10✔
106
    if Base.isdebugbuild()
10✔
107
        println(io, "  DEBUG build")
×
108
    end
109
    if !isempty(Base.TAGGED_RELEASE_BANNER)
10✔
110
        println(io, "  ", Base.TAGGED_RELEASE_BANNER)
×
111
    end
112
    if !isempty(Base.GIT_VERSION_INFO.commit_short_raw)
10✔
113
        println(io, "  Commit $(Base.GIT_VERSION_INFO.commit_short) ($(Base.GIT_VERSION_INFO.date_string))")
10✔
114
    end
115
    println(io, "  GC: ", unsafe_string(ccall(:jl_gc_active_impl, Ptr{UInt8}, ())))
10✔
116
    if verbose
10✔
117
        println(io, "  Sysimage: ", Sys.sysimage_target(), " (", Sys.MACHINE, ")")
2✔
118
    end
119
    official_release = Base.TAGGED_RELEASE_BANNER == "Official https://julialang.org release"
10✔
120
    if Base.GIT_VERSION_INFO.tagged_commit && !official_release
10✔
121
        println(io,
×
122
            """
123

124
                Note: This is an unofficial build, please report bugs to the project
125
                responsible for this build and not to the Julia project unless you can
126
                reproduce the issue using official builds available at https://julialang.org
127
            """
128
        )
129
    end
130

131
    jit_triple = let _jit = ccall(:JLJITGetJuliaOJIT, Ptr{Cvoid}, ())
10✔
132
        unsafe_string(ccall(:JLJITGetTripleString, Cstring, (Ptr{Cvoid},), _jit))
10✔
133
    end
134
    jit_cpu = first(Base.current_image_targets()).name
10✔
135

136
    println(io, "Platform Info:")
10✔
137
    println(io, "  OS: ", Sys.iswindows() ? "Windows" : Sys.isapple() ?
10✔
138
        "macOS" : Sys.KERNEL, " (", jit_triple, ")")
139

140
    if verbose
10✔
141
        lsb = ""
2✔
142
        if Sys.islinux()
2✔
143
            try lsb = readchomp(pipeline(`lsb_release -ds`, stderr=devnull)); catch; end
×
144
        end
145
        if Sys.iswindows()
2✔
146
            try lsb = strip(read(`$(ENV["COMSPEC"]) /c ver`, String)); catch; end
2✔
147
        end
148
        if !isempty(lsb)
2✔
149
            println(io, "      ", lsb)
1✔
150
        end
151
        if Sys.isunix()
2✔
152
            println(io, "  uname: ", readchomp(`uname -mprsv`))
2✔
153
        end
154
    end
155

156
    if verbose
10✔
157
        cpuio = IOBuffer() # print cpu_summary with correct alignment
2✔
158
        Sys.cpu_summary(cpuio)
2✔
159
        for (i, _line) in enumerate(split(chomp(takestring!(cpuio)), "\n"))
4✔
160
            prefix = i == 1 ? "  CPU: " : "       "
20✔
161
            line = if i == 1
20✔
162
                strip(x -> isspace(x) || x == ':', _line) * " (" * Sys.CPU_NAME * "):"
16✔
163
            else
164
                _line
38✔
165
            end
166
            println(io, prefix, line)
22✔
167
        end
38✔
168
    else
169
        cpu = Sys.cpu_info()
8✔
170
        println(io, "  CPU: ", length(cpu), " × ", cpu[1].model, " (", Sys.CPU_NAME, ")")
8✔
171
    end
172

173
    if verbose
10✔
174
        println(io, "  Memory: $(Sys.total_memory()/2^30) GiB ($(Sys.free_memory()/2^20) MiB free)")
4✔
175
        try println(io, "  Uptime: $(Sys.uptime()) sec"); catch; end
2✔
176
        print(io, "  Load Avg: ")
2✔
177
        Base.print_matrix(io, Sys.loadavg()')
2✔
178
        println(io)
2✔
179
    end
180
    println(io, "  WORD_SIZE: ", Sys.WORD_SIZE)
10✔
181
    println(io, "  LLVM: libLLVM-", Base.libllvm_version, " (", Sys.JIT, ", ", jit_cpu, ")")
10✔
182
    println(io, """Threads: $(Threads.nthreads(:default)) default, $(Threads.nthreads(:interactive)) interactive, \
10✔
183
      $(Threads.ngcthreads()) GC (on $(Sys.CPU_THREADS) virtual cores)""")
184

185
    function is_nonverbose_env(k::String)
10✔
186
        return occursin(r"^JULIA_|^DYLD_|^LD_", k)
778✔
187
    end
188
    function is_verbose_env(k::String)
252✔
189
        return occursin(r"PATH|FLAG|^TERM$|HOME", k) && !is_nonverbose_env(k)
242✔
190
    end
191
    env_strs = String[
1,084✔
192
        String["  $(k) = $(v)" for (k,v) in ENV if is_nonverbose_env(uppercase(k))];
193
        (verbose ?
194
         String["  $(k) = $(v)" for (k,v) in ENV if is_verbose_env(uppercase(k))] :
195
         String[]);
196
    ]
197
    if !isempty(env_strs)
10✔
198
        println(io, "Environment:")
8✔
199
        for str in env_strs
8✔
200
            println(io, str)
73✔
201
        end
73✔
202
    end
203
end
204

205

206
function type_close_enough(@nospecialize(x), @nospecialize(t))
163,156✔
207
    x == t && return true
167,696✔
208
    # TODO: handle UnionAll properly
209
    return (isa(x, DataType) && isa(t, DataType) && x.name === t.name && x <: t) ||
164,497✔
210
           (isa(x, Union) && isa(t, DataType) && (type_close_enough(x.a, t) || type_close_enough(x.b, t)))
211
end
212

213
# `methodswith` -- shows a list of methods using the type given
214
"""
215
    methodswith(typ[, module or function]; supertypes::Bool=false)
216

217
Return an array of methods with an argument of type `typ`.
218

219
The optional second argument restricts the search to a particular module or function
220
(the default is all top-level modules).
221

222
If keyword `supertypes` is `true`, also return arguments with a parent type of `typ`,
223
excluding type `Any`.
224

225
See also: [`methods`](@ref).
226
"""
227
function methodswith(@nospecialize(t::Type), @nospecialize(f::Base.Callable), meths = Method[]; supertypes::Bool=false)
14,896✔
228
    for d in methods(f)
14,592✔
229
        if any(function (x)
198,883✔
230
                   let x = rewrap_unionall(x, d.sig)
171,803✔
231
                       (type_close_enough(x, t) ||
145,209✔
232
                        (supertypes ? (isa(x, Type) && t <: x && (!isa(x,TypeVar) || x.ub != Any)) :
233
                         (isa(x,TypeVar) && x.ub != Any && t == x.ub)) &&
234
                        x != Any)
235
                   end
236
               end,
237
               unwrap_unionall(d.sig).parameters)
238
            push!(meths, d)
929✔
239
        end
240
    end
100,204✔
241
    return meths
7,448✔
242
end
243

244
function _methodswith(@nospecialize(t::Type), m::Module, supertypes::Bool, world::UInt)
152✔
245
    meths = Method[]
152✔
246
    for nm in names(m; world)
152✔
247
        if Base.invoke_in_world(world, isdefinedglobal, m, nm)
10,004✔
248
            f = Base.invoke_in_world(world, getglobal, m, nm)
10,004✔
249
            if isa(f, Base.Callable)
10,004✔
250
                methodswith(t, f, meths; supertypes = supertypes)
9,422✔
251
            end
252
        end
253
    end
10,004✔
254
    return unique(meths)
152✔
255
end
256

257
methodswith(@nospecialize(t::Type), m::Module; supertypes::Bool=false, world::UInt=Base.get_world_counter()) = _methodswith(t, m, supertypes, world)
8✔
258

259
function methodswith(@nospecialize(t::Type); supertypes::Bool=false, world::UInt=Base.get_world_counter())
8✔
260
    meths = Method[]
4✔
261
    for mod in Base.loaded_modules_array()
4✔
262
        append!(meths, _methodswith(t, mod, supertypes, world))
174✔
263
    end
148✔
264
    return unique(meths)
4✔
265
end
266

267
# subtypes
268
function _subtypes_in!(mods::Array, @nospecialize(x::Type), world::UInt)
54✔
269
    xt = unwrap_unionall(x)
54✔
270
    if !isabstracttype(x) || !isa(xt, DataType)
178✔
271
        # Fast path
272
        return Type[]
24✔
273
    end
274
    sts = Vector{Any}()
30✔
275
    while !isempty(mods)
3,847✔
276
        m = pop!(mods)
3,817✔
277
        xt = xt::DataType
3,817✔
278
        for s in unsorted_names(m; all = true, world)
3,817✔
279
            if !isdeprecated(m, s) && Base.invoke_in_world(world, isdefinedglobal, m, s)
690,795✔
280
                t = Base.invoke_in_world(world, getglobal, m, s)
690,679✔
281
                dt = isa(t, UnionAll) ? unwrap_unionall(t) : t
690,679✔
282
                if isa(dt, DataType)
690,679✔
283
                    if dt.name.name === s && dt.name.module == m && supertype(dt).name == xt.name
313,997✔
284
                        ti = typeintersect(t, x)
74✔
285
                        ti != Bottom && push!(sts, ti)
74✔
286
                    end
287
                elseif isa(t, Module) && nameof(t) === s && parentmodule(t) === m && t !== m
376,682✔
288
                    t === Base || push!(mods, t) # exclude Base, since it also parented by Main
2,994✔
289
                end
290
            end
291
        end
690,795✔
292
    end
3,817✔
293
    return permute!(sts, sortperm(map(string, sts)))
30✔
294
end
295

296
subtypes(m::Module, x::Type; world::UInt=Base.get_world_counter()) = _subtypes_in!([m], x, world)
8✔
297

298
"""
299
    subtypes(T::DataType)
300

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

304
See also [`supertype`](@ref), [`supertypes`](@ref), [`methodswith`](@ref).
305

306
# Examples
307
```jldoctest
308
julia> subtypes(Integer)
309
3-element Vector{Any}:
310
 Bool
311
 Signed
312
 Unsigned
313
```
314
"""
315
subtypes(x::Type; world::UInt=Base.get_world_counter()) = _subtypes_in!(Base.loaded_modules_array(), x, world)
100✔
316

317
"""
318
    supertypes(T::Type)
319

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

324
See also [`subtypes`](@ref).
325

326
# Examples
327
```jldoctest
328
julia> supertypes(Int)
329
(Int64, Signed, Integer, Real, Number, Any)
330
```
331
"""
332
function supertypes(T::Type)
20✔
333
    S = supertype(T)
24✔
334
    # note: we return a tuple here, not an Array as for subtypes, because in
335
    #       the future we could evaluate this function statically if desired.
336
    return S === T ? (T,) : (T, supertypes(S)...)
20✔
337
end
338

339
# TODO: @deprecate peakflops to LinearAlgebra
340
export peakflops
341
"""
342
    peakflops(n::Integer=4096; eltype::DataType=Float64, ntrials::Integer=3, parallel::Bool=false)
343

344
`peakflops` computes the peak flop rate of the computer by using double precision
345
[`gemm!`](@ref LinearAlgebra.BLAS.gemm!). For more information see
346
[`LinearAlgebra.peakflops`](@ref).
347

348
!!! compat "Julia 1.1"
349
    This function will be moved from `InteractiveUtils` to `LinearAlgebra` in the
350
    future. In Julia 1.1 and later it is available as `LinearAlgebra.peakflops`.
351
"""
352
function peakflops(n::Integer=4096; eltype::DataType=Float64, ntrials::Integer=3, parallel::Bool=false)
3✔
353
    # Base.depwarn("`peakflops` has moved to the LinearAlgebra module, " *
354
    #              "add `using LinearAlgebra` to your imports.", :peakflops)
355
    let LinearAlgebra = Base.require_stdlib(Base.PkgId(
1✔
356
            Base.UUID((0x37e2e46d_f89d_539d,0xb4ee_838fcccc9c8e)), "LinearAlgebra"))
357
        return LinearAlgebra.peakflops(n, eltype=eltype, ntrials=ntrials, parallel=parallel)
1✔
358
    end
359
end
360

361
function report_bug(kind)
×
362
    @info "Loading BugReporting package..."
×
363
    BugReportingId = Base.PkgId(
×
364
        Base.UUID((0xbcf9a6e7_4020_453c,0xb88e_690564246bb8)), "BugReporting")
365
    # Check if the BugReporting package exists in the current environment
366
    BugReporting = if Base.locate_package(BugReportingId) === nothing
×
367
        @info "Package `BugReporting` not found - attempting temporary installation"
×
368
        # Create a temporary environment and add BugReporting
369
        let Pkg = Base.require_stdlib(Base.PkgId(
×
370
            Base.UUID((0x44cfe95a_1eb2_52ea,0xb672_e2afdf69b78f)), "Pkg"))
371
            mktempdir() do tmp
×
372
                old_load_path = copy(LOAD_PATH)
×
373
                push!(empty!(LOAD_PATH), joinpath(tmp, "Project.toml"))
×
374
                old_active_project = Base.ACTIVE_PROJECT[]
×
375
                Base.ACTIVE_PROJECT[] = nothing
×
376
                pkgspec = @invokelatest Pkg.PackageSpec(BugReportingId.name, BugReportingId.uuid)
×
377
                @invokelatest Pkg.add(pkgspec)
×
378
                _BugReporting = Base.require(BugReportingId)
×
379
                append!(empty!(LOAD_PATH), old_load_path)
×
380
                Base.ACTIVE_PROJECT[] = old_active_project
×
381
                _BugReporting
×
382
            end
383
        end
384
    else
385
        Base.require(BugReportingId)
×
386
    end
387
    return @invokelatest BugReporting.make_interactive_report(kind, ARGS)
×
388
end
389

390
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

© 2026 Coveralls, Inc