diff --git a/CHANGELOG.md b/CHANGELOG.md index 29e18b34..05d99917 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Adapt to internal method table changes in Julia 1.12 and later. ([#334]) - The minimum supported julia version is increased to 1.6. ([#328]) ## Version [v0.8.12] - 2025-05-05 @@ -323,3 +324,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#319]: https://github.com/JuliaTesting/Aqua.jl/issues/319 [#322]: https://github.com/JuliaTesting/Aqua.jl/issues/322 [#328]: https://github.com/JuliaTesting/Aqua.jl/issues/328 +[#334]: https://github.com/JuliaTesting/Aqua.jl/issues/334 diff --git a/src/piracies.jl b/src/piracies.jl index 3ad33051..f60654eb 100644 --- a/src/piracies.jl +++ b/src/piracies.jl @@ -10,38 +10,39 @@ function all_methods(mods::Module...; skip_deprecated::Bool = true) meths = Method[] mods = collect(mods)::Vector{Module} - function examine(mt::Core.MethodTable) - examine(Base.MethodList(mt)) - end - function examine(ml::Base.MethodList) - for m in ml - is_in_mods(m.module, true, mods) || continue - push!(meths, m) - end + function examine_def(m::Method) + is_in_mods(m.module, true, mods) && push!(meths, m) + nothing end - work = Base.loaded_modules_array() - filter!(mod -> mod === parentmodule(mod), work) # some items in loaded_modules_array are not top modules (really just Base) - while !isempty(work) - mod = pop!(work) - for name in names(mod; all = true) - (skip_deprecated && Base.isdeprecated(mod, name)) && continue - isdefined(mod, name) || continue - f = Base.unwrap_unionall(getfield(mod, name)) - if isa(f, Module) && f !== mod && parentmodule(f) === mod && nameof(f) === name - push!(work, f) - elseif isa(f, DataType) && - isdefined(f.name, :mt) && - parentmodule(f) === mod && - nameof(f) === name && - f.name.mt !== Symbol.name.mt && - f.name.mt !== DataType.name.mt - examine(f.name.mt) + examine(mt::Core.MethodTable) = Base.visit(examine_def, mt) + + if VERSION >= v"1.12-" && isdefined(Core, :GlobalMethods) + examine(Core.GlobalMethods) + else + work = Base.loaded_modules_array() + filter!(mod -> mod === parentmodule(mod), work) # some items in loaded_modules_array are not top modules (really just Base) + while !isempty(work) + mod = pop!(work) + for name in names(mod; all = true) + (skip_deprecated && Base.isdeprecated(mod, name)) && continue + isdefined(mod, name) || continue + f = Base.unwrap_unionall(getfield(mod, name)) + if isa(f, Module) && f !== mod && parentmodule(f) === mod && nameof(f) === name + push!(work, f) + elseif isa(f, DataType) && + isdefined(f.name, :mt) && + parentmodule(f) === mod && + nameof(f) === name && + f.name.mt !== Symbol.name.mt && + f.name.mt !== DataType.name.mt + examine(f.name.mt) + end end end + examine(Symbol.name.mt) + examine(DataType.name.mt) end - examine(Symbol.name.mt) - examine(DataType.name.mt) return meths end