Skip to content

Commit 19bc977

Browse files
committed
Release version 2.2.0
1 parent c6a1e13 commit 19bc977

File tree

3 files changed

+75
-3
lines changed

3 files changed

+75
-3
lines changed

CHANGELOG.md

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,77 @@
11
# Changelog
22

3-
## 2.2.0 (unreleased)
3+
## 2.2.0 (2026-03-24)
44

55
### Added
66

7+
- **OWN_GIL Mode** - True parallel Python execution with Python 3.14+ subinterpreters
8+
- Each subinterpreter runs with its own GIL (`Py_GIL_OWN`) in a dedicated thread
9+
- Full isolation between interpreters (separate namespaces, modules, state)
10+
- `py_context:start_link(N, owngil)` to create OWN_GIL contexts
11+
- Enables true parallelism for CPU-bound Python workloads
12+
- See [OWN_GIL Internals](docs/owngil_internals.md) for architecture details
13+
14+
- **Process-Bound Python Environments** - Per-Erlang-process Python namespaces
15+
- Each Erlang process gets isolated Python globals/locals
16+
- State persists across calls within the same process
17+
- Automatic cleanup when Erlang process terminates
18+
- See [Process-Bound Environments](docs/process-bound-envs.md) for details
19+
20+
- **Event Loop Pool** - Process affinity for parallel async execution
21+
- `py_event_loop_pool` distributes async tasks across multiple event loops
22+
- Scheduler-affinity routing for cache-friendly execution
23+
- Supports worker, subinterp, and owngil modes
24+
25+
- **ByteChannel API** - Raw byte streaming without term serialization
26+
- `py_byte_channel:new/0,1` - Create byte channels
27+
- `py_byte_channel:send/2` - Send raw bytes
28+
- `py_byte_channel:recv/1,2` - Receive bytes
29+
- Python `ByteChannel` class with sync/async iteration
30+
- Ideal for HTTP bodies, file streaming, binary protocols
31+
32+
- **PyBuffer API** - Zero-copy buffer for WSGI input streams
33+
- `py_buffer:new/0,1` - Create buffers with optional max size
34+
- `py_buffer:write/2` - Write data to buffer
35+
- Python `PyBuffer` class with file-like interface (`read`, `readline`, `readlines`)
36+
- Non-blocking reads for async I/O patterns
37+
- See [Buffer API](docs/buffer.md) for details
38+
739
- **True streaming API** - New `py:stream_start/3,4` and `py:stream_cancel/1` functions
840
for event-driven streaming from Python generators. Unlike `py:stream/3,4` which
941
collects all values at once, `stream_start` sends `{py_stream, Ref, {data, Value}}`
1042
messages as values are yielded. Supports both sync and async generators. Useful for
1143
LLM token streaming, real-time data feeds, and processing large sequences incrementally.
1244

45+
- **`erlang.whereis(name)`** - Lookup registered Erlang process PIDs from Python
46+
- Returns `erlang.Pid` object or `None` if not registered
47+
- Enables Python code to discover and message named processes
48+
49+
- **`erlang.schedule_inline(callback)`** - Inline continuation scheduling
50+
- Release dirty scheduler and continue with callback in same context
51+
- Preserves globals/locals across the continuation
52+
- Useful for cooperative long-running tasks
53+
54+
- **`py:spawn_call/3,4,5`** - Fire-and-forget with result delivery
55+
- Executes Python call asynchronously
56+
- Sends `{py_result, Ref, Result}` to caller when complete
57+
- Non-blocking alternative to `py:call` for async patterns
58+
59+
- **Explicit bytes conversion** - `{bytes, Binary}` tuple for round-trip safety
60+
- Erlang binaries convert to Python `str` by default
61+
- Use `{bytes, Binary}` to force Python `bytes` type
62+
- Ensures correct handling for binary protocols
63+
64+
- **Import caching API** - Lazy module import with caching
65+
- `py:import/1,2` - Import and cache modules
66+
- `py:add_import/1,2` - Register imports applied to all contexts
67+
- `py:add_path/1` - Add to sys.path across all contexts
68+
- Per-interpreter caching with generation tracking
69+
70+
- **Per-interpreter preload code** - Execute code in new interpreters
71+
- Configure via `{erlang_python, [{preload_code, <<"import mylib">>}]}`
72+
- Code runs with inherited globals from main interpreter
73+
- Useful for initializing common imports/state
74+
1375
### Fixed
1476

1577
- **Channel notification for create_task** - Fixed async channel receive hanging when using
@@ -51,6 +113,13 @@
51113

52114
### Changed
53115

116+
- **`py:cast` is now fire-and-forget** - `py:cast/3,4,5` no longer returns a reference.
117+
For async calls with result delivery, use the new `py:spawn_call/3,4,5` instead.
118+
119+
- **OWN_GIL requires Python 3.14+** - The OWN_GIL subinterpreter mode requires Python 3.14
120+
or later due to C extension compatibility issues in earlier versions. Use `worker` or
121+
`subinterp` modes for Python 3.12-3.13.
122+
54123
- **Removed auto-started io pool** - The io pool is no longer started automatically at
55124
application startup to reduce memory usage. Users who need a dedicated I/O pool can
56125
create one manually via `py_context_router:start_pool(io, 10, worker)`. The configuration
@@ -69,6 +138,9 @@
69138

70139
### Performance
71140

141+
- **Direct NIF channel operations** - Channel send/receive bypass `erlang.call()` overhead
142+
for up to 1760x speedup in raw throughput benchmarks
143+
72144
- **nif_process_ready_tasks optimization** - ~15% improvement in async task processing
73145
- Replace `asyncio.iscoroutine()` with `PyCoro_CheckExact` C API
74146
- Use stack buffers for module/func strings

docs/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Add to your `rebar.config`:
88

99
```erlang
1010
{deps, [
11-
{erlang_python, "2.1.0"}
11+
{erlang_python, "2.2.0"}
1212
]}.
1313
```
1414

src/erlang_python.app.src

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{application, erlang_python, [
22
{description, "Execute Python applications from Erlang using dirty NIFs"},
3-
{vsn, "2.1.0"},
3+
{vsn, "2.2.0"},
44
{registered, [py_pool]},
55
{mod, {erlang_python_app, []}},
66
{applications, [

0 commit comments

Comments
 (0)