feat: add MontySession for calling Python functions from Rust
Add MontySession<T> that runs Python setup code, retains the heap/globals/
interns, and allows repeated invocation of Python-defined functions from Rust.
Key changes:
- New session.rs with MontySession struct, call_function/call_function_with_print,
function_names, has_function, and tracker_mut APIs
- MontyRun::into_session/into_session_with_print entry points
- VM::run_callable for invoking callables without an active parent frame
- Refactored call_sync_function into call_sync_function_inner to support
optional call_position (None when called from host, Some when called during
bytecode execution)
- call_function_no_position + call_heap_callable_no_position for frame-less dispatch
- 23 integration tests covering basic calls, state persistence, closures,
defaults, error handling, introspection, print capture, and complex types