@@ -137,6 +137,14 @@ defmodule Pythonx do
137137 > those releases the GIL. GIL is also released when waiting on I/O
138138 > operations.
139139
140+ ## Options
141+
142+ * `:stdout_device` - IO process to send Python stdout output to.
143+ Defaults to the caller's group leader.
144+
145+ * `:stderr_device` - IO process to send Python stderr output to.
146+ Defaults to the global `:standard_error`.
147+
140148 ## Examples
141149
142150 iex> {result, globals} =
@@ -201,9 +209,12 @@ defmodule Pythonx do
201209 >
202210
203211 '''
204- @ spec eval ( String . t ( ) , % { optional ( String . t ( ) ) => term ( ) } ) ::
212+ @ spec eval ( String . t ( ) , % { optional ( String . t ( ) ) => term ( ) } , keyword ( ) ) ::
205213 { Object . t ( ) | nil , % { optional ( String . t ( ) ) => Object . t ( ) } }
206- def eval ( code , globals ) do
214+ def eval ( code , globals , opts \\ [ ] )
215+ when is_binary ( code ) and is_map ( globals ) and is_list ( opts ) do
216+ opts = Keyword . validate! ( opts , [ :stdout_device , :stderr_device ] )
217+
207218 globals =
208219 for { key , value } <- globals do
209220 if not is_binary ( key ) do
@@ -214,8 +225,11 @@ defmodule Pythonx do
214225 end
215226
216227 code_md5 = :erlang . md5 ( code )
217- stdout_device = Process . group_leader ( )
218- stderr_device = Process . whereis ( :standard_error )
228+
229+ stdout_device = Keyword . get_lazy ( opts , :stdout_device , fn -> Process . group_leader ( ) end )
230+
231+ stderr_device =
232+ Keyword . get_lazy ( opts , :stderr_device , fn -> Process . whereis ( :standard_error ) end )
219233
220234 result = Pythonx.NIF . eval ( code , code_md5 , globals , stdout_device , stderr_device )
221235
0 commit comments