Skip to content

Precompile invalidation cannot represent the non-file inputs of a crate's artifact identity #355

Description

@terasakisatoshi

Split out of the review of PR #351 (#339), where the class became visible.

The class

A crate's artifact identity (compute_crate_hash, _pyo3_wrapper_build_env) is computed from more than files. RUSTFLAGS, PYO3_PYTHON, RUSTCALL_PYTHON_LIBDIR, a PYO3_CONFIG_FILE that now points at a different file, and the rest of the artifact_build_env allowlist all change what is built.

Julia invalidates a precompile image from files: Base.include_dependency tracks a file's content (or a directory's entry list), and that is the only lever a generated module has. So after #351 the image is invalidated by an edit to the crate, to a path dependency, to .cargo/config.toml, to PYO3_CONFIG_FILE itself, and by a file appearing or disappearing in any of those directories — but not by the environment changing. Every tracked file is then still byte-for-byte what it was, the image stays valid, and the package loads a library built for the other environment.

#351 makes the module record the environment it was generated under and @warn from __init__ when it no longer matches, naming the variables. That converts silence into a message; it does not invalidate anything.

What a real fix would need

Something the image can carry that changes when a non-file input does. Options, none of them free:

  • a stamp file per (crate, environment) under RustCall's cache whose content is the artifact key, declared with include_dependency — the difficulty is that only a re-precompile rewrites it, which is the step being skipped, so the stamp has to be written by something that runs on every load, or keyed so that a new environment names a path that does not exist yet;
  • Base.CacheFlags-style participation, if Julia gains a hook for package-defined invalidation predicates;
  • refusing to load instead of warning, which is honest but breaks a workflow where the difference is deliberate.

Acceptance

  • a package precompiled with one PYO3_PYTHON and loaded with another either rebuilds or refuses, rather than warning and continuing;
  • the same for RUSTFLAGS;
  • no spurious invalidation when nothing relevant changed — the @rust_crate precompile testsets already pin that an unchanged crate is not re-precompiled;
  • docs/src/crate_bindings.md describes whatever rule replaces the warning.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:crate-bindings@rust_crate, write_bindings_to_file, generated Julia wrapperstech-debtAccumulated design or implementation shortcuts that should be repaid

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions