mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-19 04:54:37 +00:00
* refactor(python-bridge): ship a signature base and read the resolved call NativeCall carries base (positionals by name plus signature defaults) instead of the fully bound dict. resolved lays kwargs over base, which is what bound held, so every pre-hook read and every route host keeps seeing the same values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(bedrock): build the transcription NativeCall with an empty base Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(dispatch): read the resolved call instead of bound Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(host-python): rename effective to effective_py_args and note the shallow copy Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
75 lines
2.4 KiB
Rust
75 lines
2.4 KiB
Rust
//! The CPython runtime adapter: value marshalling, interpreter detachment, the tokio and
|
|
//! asyncio glue, and the driver that runs a native [`Machine`](litellm_host::machine::Machine)
|
|
//! against a Python binding, host services and active call hooks. Everything here is Python-specific by
|
|
//! construction; another host language gets its own crate of the same shape.
|
|
|
|
mod argument;
|
|
mod binding;
|
|
mod conversion_cache;
|
|
mod driver;
|
|
mod error;
|
|
mod file_reader;
|
|
mod fork_gate;
|
|
mod gil;
|
|
mod handle;
|
|
mod hooks;
|
|
mod marshal;
|
|
mod native;
|
|
mod owned;
|
|
mod runtime;
|
|
mod services;
|
|
|
|
pub use argument::{effective_py_args, lookup, present};
|
|
pub use binding::PythonBinding;
|
|
pub use conversion_cache::{FromPythonCache, ToPythonCache};
|
|
pub use driver::{CallOptions, run_call};
|
|
pub use error::{InvokeError, missing_state};
|
|
pub use file_reader::{FileContent, PythonFileReader, py_bytes};
|
|
pub use fork_gate::RuntimeAlreadyStarted;
|
|
pub use gil::{PythonContext, attach_blocking, release_count, release_gil};
|
|
pub use handle::{Execution, ExecutionBody, ExecutionStep, PythonLifecycle};
|
|
pub use hooks::{HookChain, HookResume, HookStep, PythonCallEvent, PythonCallHooks, PythonRuntime};
|
|
pub use marshal::{
|
|
Pythonized, from_py, from_py_argument, json_loads, json_object_field, panic_to_pyerr, to_py,
|
|
};
|
|
pub use owned::PythonOwned;
|
|
pub use runtime::{
|
|
ForkedAfterNativeRuntimeStarted, ProcessReservedForForking, enter_native, poll_async_value,
|
|
ready_future, reserve_process_for_forking, run_async, run_async_value, run_sync,
|
|
run_sync_value, runtime_started,
|
|
};
|
|
pub use services::PythonHostCalls;
|
|
|
|
/// Starts the interpreter and imports the standard modules the tests share, once, so
|
|
/// parallel test threads never race a first import of `asyncio`.
|
|
#[cfg(test)]
|
|
pub(crate) fn initialize_python() {
|
|
static IMPORTED: std::sync::Once = std::sync::Once::new();
|
|
pyo3::Python::initialize();
|
|
IMPORTED.call_once(|| {
|
|
pyo3::Python::attach(|py| {
|
|
py.import("asyncio").expect("asyncio imports");
|
|
});
|
|
});
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub(crate) struct InitializedPython;
|
|
|
|
#[cfg(test)]
|
|
impl InitializedPython {
|
|
pub(crate) fn attach<F, R>(&self, f: F) -> R
|
|
where
|
|
F: for<'py> FnOnce(pyo3::Python<'py>) -> R,
|
|
{
|
|
pyo3::Python::attach(f)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
#[rstest::fixture]
|
|
#[once]
|
|
pub(crate) fn initialized_python() -> InitializedPython {
|
|
initialize_python();
|
|
InitializedPython
|
|
}
|