Files
zeekayandHanzo Dev 3e5f509c69 One plugin runtime, four languages, one interface
The contract was written down twice — zip declares Module and Loader, and the
loader beside base's runners declared its own copy. Structural typing was the
only thing keeping them equal, which is a property nobody can see and a compiler
will not check.

This implements zip's. The loader, the manifest and the runners live here so
cloud can stop carrying a second goja runtime of its own — a shim, a bundler and
a third registry that answered the same question this one does.

native, goja, wazero and pyvm. wazero is the reason this is not a list of four
languages: anything compiled to WebAssembly ahead of time arrives without a new
runner, and Rust walks through that door rather than getting one built for it.
pyvm is real CPython through cgo with PEP 684 sub-interpreters, behind a build
tag, because embedding the language beats reimplementing a subset of it.

Its one dependency on base was a single call for an unguessable string, which
crypto/rand says directly.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 12:33:40 -07:00

49 lines
1.7 KiB
Go

//go:build !pyvm
// +build !pyvm
// Package pyvm is the CPython (cgo) extension runtime for Base.
//
// The real implementation lives behind the `pyvm` build tag because it
// links libpython at the C level and requires Python 3.12+ development
// headers (pkg-config python-3.13-embed or python-3.12-embed). Default
// base builds compile without it — this stub is what gets linked in
// normally so `NewRuntime()` is always callable, only the engine is
// opt-in via `go build -tags pyvm`.
package pyvm
import (
"context"
"fmt"
"github.com/hanzoai/plugin/extruntime"
)
// NewRuntime returns a CPython-shaped runtime that errors at Load time
// when the binary was built without the `pyvm` build tag. Name() and
// Capabilities() still report the pyvm identity so callers can detect
// the runtime is present-but-unavailable rather than missing entirely.
func NewRuntime() extruntime.Runtime { return &stubRuntime{} }
type stubRuntime struct{}
func (*stubRuntime) Name() string { return "pyvm" }
func (*stubRuntime) Capabilities() extruntime.Capabilities {
return extruntime.Capabilities{
AcceptsLanguages: []string{"py"},
// HardSandbox=false: cgo CPython shares the host process. A C
// extension segfault kills the whole Go binary. Use wazero +
// RustPython if you need a sandboxed Python.
HardSandbox: false,
Cgo: true,
// HONEST: pyvm cannot hard-abort a running invocation. See README.
SupportsAbort: false,
}
}
func (*stubRuntime) Load(_ context.Context, _ string) (extruntime.Module, error) {
return nil, fmt.Errorf("%w: built without -tags pyvm (cgo CPython disabled)", extruntime.ErrUnsupported)
}
func (*stubRuntime) Close() error { return nil }