Package definitions include a manually-defined list of extensions required to load the hugr,
that gets included in the envelope when calling Package.to_bytes/to_str.
When encoding a standalone Hugr, we wrap it in a Package with an empty list of extensions before encoding it.
Now that we can compute the list of extensions used by a hugr dinamically (#2817), we could automatically add those to the created package to ensure that the envelope can be loaded by any target.
I'd propose adding a new parameter to Hugr.to_bytes and to_str,
class Hugr:
def to_bytes(self, (...), *, include_extensions: ExtensionRegistry | None = None) -> bytes: ...
def to_str(self, (...), *, include_extensions: ExtensionRegistry | None = None) -> str: ...
If include_extensions is None, we run used_extensions and add any non-prelude ones to the package. Otherwise we embed the given registry.
If one wants better control over the included extensions, it's always possible to create a package manually with the desired bundled extensions.
Note that this behaviour differs from the rust definition, where the default store explicitly omits storing extra extensions.
|
/// Store the HUGR in an Envelope. |
|
/// |
|
/// The Envelope will not include any extension definition, and will require |
|
/// an adequate [`ExtensionRegistry`] to be loaded (see [`Hugr::load`]). |
|
/// Use [`Hugr::store_with_exts`] to include additional extensions in the |
|
/// Envelope. |
|
pub fn store(&self, writer: impl io::Write, config: EnvelopeConfig) -> Result<(), WriteError> { |
|
self.store_with_exts(writer, config, &EMPTY_REG) |
|
} |
|
|
|
/// Store the HUGR in an Envelope. |
|
/// |
|
/// The Envelope will embed the definitions of the extensions in the |
|
/// `extensions` registry. Any other extension used in the HUGR definition |
|
/// must be passed to [`Hugr::load`] to load back the HUGR. |
|
pub fn store_with_exts( |
|
&self, |
|
writer: impl io::Write, |
|
config: EnvelopeConfig, |
|
extensions: &ExtensionRegistry, |
|
) -> Result<(), WriteError> { |
The rust interface in general provides finer control over the compiler behaviour, but for the python side we should err on the side of intuitiveness.
If I to_bytes a hugr I would expect it can be loaded afterwards wherever I need it. Trimming the extensions included in the envelope should be a later size-optimization.
Package definitions include a manually-defined list of extensions required to load the hugr,
that gets included in the envelope when calling
Package.to_bytes/to_str.When encoding a standalone Hugr, we wrap it in a Package with an empty list of extensions before encoding it.
Now that we can compute the list of extensions used by a hugr dinamically (#2817), we could automatically add those to the created package to ensure that the envelope can be loaded by any target.
I'd propose adding a new parameter to
Hugr.to_bytesandto_str,If
include_extensionsisNone, we runused_extensionsand add any non-prelude ones to the package. Otherwise we embed the given registry.If one wants better control over the included extensions, it's always possible to create a package manually with the desired bundled extensions.
Note that this behaviour differs from the rust definition, where the default
storeexplicitly omits storing extra extensions.hugr/hugr-core/src/hugr.rs
Lines 184 to 204 in a21e818
The rust interface in general provides finer control over the compiler behaviour, but for the python side we should err on the side of intuitiveness.
If I
to_bytesa hugr I would expect it can be loaded afterwards wherever I need it. Trimming the extensions included in the envelope should be a later size-optimization.