[ANN] JET v0.11

Hi everyone,

Today, I’d like to introduce the new version of JET, v0.11.

In JET v0.11.0, the implementation of report_package has been revamped and switched to a Revise-based implementation. This allows it to work reliably for most loadable packages. If you have tried report_package before and gave up on JET because it didn’t work as expected, please give it another try!

Furthermore, the move to a Revise-based implementation enables incremental analysis, making subsequent analyses of the same package extremely fast. Please see the GIF in the release notes below to see the incremental analysis in action.

There are also some deprecations, so please refer to the release notes below for details (the following is an excerpt from the release notes for JET v0.11.0).


Changed

  • Major improvement to report_package: Switched to a Revise.jl-based
    implementation that brings significant improvements (aviatesk/JET.jl#763):
    • Incremental analysis: Analysis results are now cached and reused across
      multiple runs. When you analyze the same package again, only methods
      affected by code changes are re-analyzed, while unchanged methods reuse
      their cached results. This dramatically reduces analysis time for iterative
      development workflows.

      E.g. Incremental analysis on JET itself

      ScreenRecording2025-10-23at03.01.14-ezgif.com-video-to-gif-converter

    • Improved robustness: The new implementation leverages Revise’s
      battle-tested infrastructure for tracking package definitions, providing
      much more reliable analysis coverage across diverse code patterns compared
      to the previous custom code loading mechanism.

    • Breaking change: report_package now requires a Module argument
      instead of accepting a package name as AbstractString. Users must now
      load the target package before analysis. See the deprecated section for
      more details.

    • Limitation: As a trade-off of the Revise-based approach, report_package
      can no longer analyze packages that fail to load. Previously, report_package
      could atl least report top-level errors for such packages (though it
      couldn’t perform inference-based analysis). Now users must afix loading
      errors before applying JET analysis via report_package. These errors are
      typically straightforward to fix by examining the error output from
      using MyPkg or Pkg.precompile().

    • The previous default configurations analyze_from_definitions=true and
      concretization_patterns=[:(x_)] are no longer needed or used, as the
      Revise-based approach does not require JET’s own code loading mechanism
      (they can still be used for report_file or report_text, since those functions still use JET’s own code loading mechanism)

  • Revise.jl is now a required dependency instead of an optional weak
    dependency. This means watch_file no longer requires manually loading
    Revise with using Revise before use.
  • Enabled the ad-hoc concrete evaluation in JETAnalyzer for Julia v1.13 and higher, reducing false positives in more general cases
  • Module filtering behavior change: target_modules and ignored_modules
    now include submodules by default (aviatesk/JET.jl#628, aviatesk/JET.jl#772):
    • Submodule-inclusive filtering: When a Module object is passed to
      target_modules or ignored_modules, JET now matches not only that exact
      module but also all of its submodules. This provides more intuitive
      filtering behavior in most use cases.
    • Breaking change: This changes the filtering behavior when
      target_modules or ignored_modules accept an iterator of modules.
      To preserve the previous exact-match behavior (matching only the specified
      module without its submodules), wrap the module with LastFrameModuleExact
      or AnyFrameModuleExact:
      # New default (v0.11+): matches MyPackage and all its submodules
      report_call(f, args...; target_modules=(MyPackage,))
      
      # Previous behavior (v0.10): matched only MyPackage exactly
      # To preserve this in v0.11+, use:
      report_call(f, args...; target_modules=(LastFrameModuleExact(MyPackage),))
      
    • New matcher types:
      • ReportMatcher: abstract interface type for JET.match_report
      • LastFrameModuleExact: exact match in last frame only
      • AnyFrameModuleExact: exact match in any frame

Added

  • Symbol-based module filtering: target_modules and ignored_modules now accept Symbol in addition to Module objects (aviatesk/JET.jl#602, aviatesk/JET.jl#773).
    This allows filtering by module name without requiring the module as a dependency:
    # Filter by module name without loading CUDA package
    report_call(f, args...; ignored_modules=(:CUDA,))
    
    # Equivalent to passing the Module object (if CUDA is loaded)
    report_call(f, args...; ignored_modules=(CUDA,))
    
    All matcher types (LastFrameModule, AnyFrameModule, LastFrameModuleExact,
    AnyFrameModuleExact) now accept Union{Module,Symbol}.

Deprecated

  • report_package(::AbstractString), report_package([::Nothing]):
    The old signatures accepting a package name as a string, or no arguments are
    deprecated. Load the package first and pass the Module instead:
    # Preferred (v0.11):
    julia> using MyPackage
    julia> report_package(MyPackage)
    
    # Deprecated (v0.10):
    julia> report_package("MyPackage")
    julia> report_package()
    
  • target_defined_modules configuration: Use the more flexible target_modules
    configuration instead. To limit error reports to your package’s module
    context (filtering out errors from dependencies), use:
    report_package(MyPackage; target_modules=(MyPackage,))
    
33 Likes