From 2efe28d323e59b1518b426e8f507eab25f2cf92f Mon Sep 17 00:00:00 2001 From: Cody Tapscott Date: Tue, 31 Jan 2023 08:26:25 -0500 Subject: [PATCH] Avoid unnecessary Docs.META initializations If the target module does not have a Docs.META dict (e.g. if `--strip-metadata` is used), `Docs.meta()` has the side effect of creating a new IdDict and initializing the Docs.META field of the target module. We need to avoid eval'ing into modules after they've been closed, so for methods that do not mutate the new IdDict we should avoid the init. Resolves #48390. Co-authored-by: Steve Kelly --- base/docs/Docs.jl | 7 ++++--- stdlib/REPL/src/docview.jl | 10 +++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/base/docs/Docs.jl b/base/docs/Docs.jl index f4db13f828ed6..61b5786298475 100644 --- a/base/docs/Docs.jl +++ b/base/docs/Docs.jl @@ -73,9 +73,9 @@ const modules = Module[] const META = gensym(:meta) const METAType = IdDict{Any,Any} -function meta(m::Module) +function meta(m::Module; autoinit::Bool=true) if !isdefined(m, META) || getfield(m, META) === nothing - initmeta(m) + autoinit ? initmeta(m) : return nothing end return getfield(m, META)::METAType end @@ -161,7 +161,8 @@ end function docstr(binding::Binding, typesig = Union{}) @nospecialize typesig for m in modules - dict = meta(m) + dict = meta(m; autoinit=false) + isnothing(dict) && continue if haskey(dict, binding) docs = dict[binding].docs if haskey(docs, typesig) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 24bbfc2e6282d..ea663fa16007f 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -164,7 +164,8 @@ function doc(binding::Binding, sig::Type = Union{}) results, groups = DocStr[], MultiDoc[] # Lookup `binding` and `sig` for matches in all modules of the docsystem. for mod in modules - dict = meta(mod) + dict = meta(mod; autoinit=false) + isnothing(dict) && continue if haskey(dict, binding) multidoc = dict[binding] push!(groups, multidoc) @@ -565,7 +566,8 @@ Return documentation for a particular `field` of a type if it exists. """ function fielddoc(binding::Binding, field::Symbol) for mod in modules - dict = meta(mod) + dict = meta(mod; autoinit=false) + isnothing(dict) && continue if haskey(dict, binding) multidoc = dict[binding] if haskey(multidoc.docs, Union{}) @@ -834,7 +836,9 @@ function apropos(io::IO, needle::Regex) for mod in modules # Module doc might be in README.md instead of the META dict docsearch(doc(mod), needle) && println(io, mod) - for (k, v) in meta(mod) + dict = meta(mod; autoinit=false) + isnothing(dict) && continue + for (k, v) in dict docsearch(v, needle) && println(io, k) end end