ericphanson / ExplicitImports.jl

Developer tooling for Julia namespace management: detecting implicit imports, improper explicit imports, and improper qualified accesses
https://ericphanson.github.io/ExplicitImports.jl/
MIT License
77 stars 4 forks source link

`unanalyzable` not clearly defined #79

Open Sbozzolo opened 1 month ago

Sbozzolo commented 1 month ago

I am trying ExplicitImports.jl with a package with a slightly complex module structure (the package is mostly implemented in modules loaded by extensions). When I run check_no_implicit_imports, I get UnanalyzableModuleException and a message telling me that I show allow my module to be unalayzable. However, what "unanalyzable" means is not really clear. Is it an issue I can solve on my end?

(The package I want to check is ClimaUtilities.jl)

ericphanson commented 1 month ago

often it means dynamic include statements, but I don't see any there. If you do print_explicit_imports it should show which modules aren't analyzable. Also try setting ENV["JULIA_DEBUG"] = "ExplicitImports" first.

I wasn't able to reproduce:

julia> using ExplicitImports

julia> ENV["JULIA_DEBUG"] = "ExplicitImports"
"ExplicitImports"

julia> check_no_implicit_imports(ClimaUtilities)
Sbozzolo commented 1 month ago

To reproduce, you also have to load the packages that trigger extension loading:

import ExplicitImports
ENV["JULIA_DEBUG"] = "ExplicitImports"

import NCDatasets
import ClimaComms
import Interpolations
import ClimaCoreTempestRemap

using ClimaUtilities
ExplicitImports.check_no_implicit_imports(ClimaUtilities)

results in

julia> ExplicitImports.check_no_implicit_imports(ClimaUtilities)
ERROR: UnanalyzableModuleException
Module `ClimaUtilitiesClimaCoreTempestRemapExt.TempestRegridderExt` was found to be unanalyzable. Include this module in the `allow_unanalyzable` keyword argument to allow it to be unanalyzable.

Stacktrace:
 [1] should_ignore!(::Nothing, mod::Module; ignore::Tuple{})
   @ ExplicitImports ~/.julia/packages/ExplicitImports/JSYBk/src/checks.jl:260
 [2] check_no_implicit_imports(mod::Module, file::String; skip::Tuple{Module, Module, Module}, ignore::Tuple{}, allow_unanalyzable::Tuple{})
   @ ExplicitImports ~/.julia/packages/ExplicitImports/JSYBk/src/checks.jl:231
 [3] check_no_implicit_imports
   @ ~/.julia/packages/ExplicitImports/JSYBk/src/checks.jl:223 [inlined]
 [4] check_no_implicit_imports(mod::Module)
   @ ExplicitImports ~/.julia/packages/ExplicitImports/JSYBk/src/checks.jl:223
 [5] top-level scope
   @ REPL[8]:1

As for printing imports:

julia> ExplicitImports.print_explicit_imports(ClimaUtilities)
  Module ClimaUtilitiesClimaCoreTempestRemapExt.TempestRegridderExt could not be accurately analyzed, likely due to dynamic include statements. You can pass
  strict=false to attempt to get (possibly inaccurate) results anyway.

  Module ClimaUtilities.OutputPathGenerator is not relying on any implicit imports.

  Module ClimaUtilities.Utils is not relying on any implicit imports.

  Module ClimaUtilitiesClimaCoreTempestRemapExt is not relying on any implicit imports.

  Module ClimaUtilitiesClimaCoreInterpolationsExt.InterpolationsRegridderExt could not be accurately analyzed, likely due to dynamic include statements. You
  can pass strict=false to attempt to get (possibly inaccurate) results anyway.

  Module ClimaUtilitiesClimaCoreExt.TimeVaryingInputs0DExt could not be accurately analyzed, likely due to dynamic include statements. You can pass
  strict=false to attempt to get (possibly inaccurate) results anyway.

  Module ClimaUtilitiesClimaCommsExt.MPIUtilsExt could not be accurately analyzed, likely due to dynamic include statements. You can pass strict=false to
  attempt to get (possibly inaccurate) results anyway.

  Module ClimaUtilities.FileReaders is not relying on any implicit imports.

  Module ClimaUtilitiesClimaCoreInterpolationsExt is not relying on any implicit imports.

  Module ClimaUtilitiesNCDatasetsExt is not relying on any implicit imports.

  Module ClimaUtilitiesClimaCoreNCDatasetsExt.DataHandlingExt could not be accurately analyzed, likely due to dynamic include statements. You can pass
  strict=false to attempt to get (possibly inaccurate) results anyway.

  Module ClimaUtilities.DataHandling is not relying on any implicit imports.

  Module ClimaUtilities.Regridders is not relying on any implicit imports.

  Module ClimaUtilities.TimeVaryingInputs is not relying on any implicit imports.

  Module ClimaUtilities.TimeManager is not relying on any implicit imports.

  Module ClimaUtilitiesClimaCoreNCDatasetsExt is not relying on any implicit imports.

  Module ClimaUtilitiesClimaCoreNCDatasetsExt.TimeVaryingInputsExt could not be accurately analyzed, likely due to dynamic include statements. You can pass
  strict=false to attempt to get (possibly inaccurate) results anyway.

  Module ClimaUtilities is not relying on any implicit imports.

  Module ClimaUtilities.DataStructures is not relying on any implicit imports.

  Module ClimaUtilities.ClimaArtifacts is not relying on any implicit imports.

  Module ClimaUtilitiesClimaCommsExt is not relying on any implicit imports.

  Module ClimaUtilitiesClimaCoreExt is not relying on any implicit imports.

  Module ClimaUtilitiesClimaCoreNCDatasetsExt.SpaceVaryingInputsExt could not be accurately analyzed, likely due to dynamic include statements. You can pass
  strict=false to attempt to get (possibly inaccurate) results anyway.

  Module ClimaUtilities.MPIUtils is not relying on any implicit imports.

  Module ClimaUtilities.SpaceVaryingInputs is not relying on any implicit imports.

  Module ClimaUtilitiesNCDatasetsExt.NCFileReaderExt could not be accurately analyzed, likely due to dynamic include statements. You can pass strict=false to
  attempt to get (possibly inaccurate) results anyway.
Sbozzolo commented 1 month ago

The common thread I think I see is that the modules that cannot be analyzed are modules that are included in the extensions, as in ClimaUtilitiesClimaCoreTempestRemapExt.jl

module ClimaUtilitiesClimaCoreTempestRemapExt

include("TempestRegridderExt.jl")

end

where TempestRegridderExt.jl is a module itself (but not an extension, despite what the name might suggest).

ericphanson commented 1 month ago

interesting, I have a test for extensions but it doesn't include submodules in the extension, so something must be going wrong there, thanks for the report