33
44__version__ = '0.9.1'
55
6+ from ctypes import pointer , c_int , POINTER , c_char_p
7+ from typing import Any
8+
69_newmodule = None
710
811def newmodule (name ):
@@ -64,37 +67,66 @@ def option(name, default=None):
6467 return default
6568
6669 def choice (name , choices , default = None ):
67- k = option (name )
68- if k is None :
70+ v = option (name )
71+ if v is None :
6972 return default
70- if k in choices :
71- if isinstance (k , dict ):
72- return choices [k ]
73+ if v in choices :
74+ if isinstance (choices , dict ):
75+ return choices [v ]
7376 else :
74- return k
75- raise ValueError (f'invalid value for option: JULIACALL_{ name .upper ()} ={ k } , expecting one of { ", " .join (choices )} ' )
77+ return v
78+ raise ValueError (
79+ f'invalid value for option: JULIACALL_{ name .upper ()} ={ v } , expecting one of { ", " .join (choices )} ' )
7680
7781 def path_option (name , default = None ):
7882 path = option (name )
7983 if path is not None :
8084 return os .path .abspath (path )
8185 return default
8286
87+ def int_option (name , * , accept_auto = False ):
88+ val = option (name )
89+ if val is None :
90+ return None
91+ if accept_auto and val == "auto" :
92+ return "auto"
93+ try :
94+ int (val )
95+ return val
96+ except ValueError :
97+ raise ValueError (f'invalid value for option: JULIACALL_{ name .upper ()} ={ val } , '
98+ f'expecting an int' + ' or auto' if accept_auto else "" )
99+
100+ def args_from_config ():
101+ argv = ["--" + opt [4 :].replace ("_" , "-" )+ "=" + val for opt , val in CONFIG .items ()
102+ if val is not None and opt .startswith ("opt_" )]
103+ argv = [CONFIG ['exepath' ]]+ argv
104+ if sys .version_info [0 ] >= 3 :
105+ argv = [s .encode ("utf-8" ) for s in argv ]
106+
107+ argc = len (argv )
108+ c = c_int (argc )
109+ v = POINTER (c_char_p )((c_char_p * len (argv ))(* argv ))
110+ return c , v
111+
83112 # Determine if we should skip initialising.
84113 CONFIG ['init' ] = choice ('init' , ['yes' , 'no' ], default = 'yes' ) == 'yes'
85114 if not CONFIG ['init' ]:
86115 return
87116
88117 # Parse some more options
89- CONFIG ['opt_bindir' ] = path_option ('bindir' ) # TODO
90- CONFIG ['opt_check_bounds' ] = choice ('check_bounds' , ['yes' , 'no' ]) # TODO
91- CONFIG ['opt_compile' ] = choice ('compile' , ['yes' , 'no' , 'all' , 'min' ]) # TODO
92- CONFIG ['opt_compiled_modules' ] = choice ('compiled_modules' , ['yes' , 'no' ]) # TODO
93- CONFIG ['opt_depwarn' ] = choice ('depwarn' , ['yes' , 'no' , 'error' ]) # TODO
94- CONFIG ['opt_inline' ] = choice ('inline' , ['yes' , 'no' ]) # TODO
95- CONFIG ['opt_optimize' ] = choice ('optimize' , ['0' , '1' , '2' , '3' ]) # TODO
96- CONFIG ['opt_sysimage' ] = path_option ('sysimage' ) # TODO
97- CONFIG ['opt_warn_overwrite' ] = choice ('warn_overwrite' , ['yes' , 'no' ]) # TODO
118+ CONFIG ['opt_bindir' ] = path_option ('bindir' )
119+ CONFIG ['opt_check_bounds' ] = choice ('check_bounds' , ['yes' , 'no' , 'auto' ])
120+ CONFIG ['opt_compile' ] = choice ('compile' , ['yes' , 'no' , 'all' , 'min' ])
121+ CONFIG ['opt_compiled_modules' ] = choice ('compiled_modules' , ['yes' , 'no' ])
122+ CONFIG ['opt_depwarn' ] = choice ('depwarn' , ['yes' , 'no' , 'error' ])
123+ CONFIG ['opt_inline' ] = choice ('inline' , ['yes' , 'no' ])
124+ CONFIG ['opt_min_optlevel' ] = choice ('min_optlevel' , ['0' , '1' , '2' , '3' ])
125+ CONFIG ['opt_optimize' ] = choice ('optimize' , ['0' , '1' , '2' , '3' ])
126+ CONFIG ['opt_procs' ] = int_option ('procs' , accept_auto = True )
127+ CONFIG ['opt_sysimage' ] = path_option ('sysimage' )
128+ CONFIG ['opt_threads' ] = int_option ('threads' , accept_auto = True )
129+ CONFIG ['opt_warn_overwrite' ] = choice ('warn_overwrite' , ['yes' , 'no' ])
98130
99131 # Stop if we already initialised
100132 if CONFIG ['inited' ]:
@@ -109,7 +141,8 @@ def path_option(name, default=None):
109141 CONFIG ['project' ] = project = juliapkg .project ()
110142
111143 # Find the Julia library
112- cmd = [exepath , '--project=' + project , '--startup-file=no' , '-O0' , '--compile=min' , '-e' , 'import Libdl; print(abspath(Libdl.dlpath("libjulia")))' ]
144+ cmd = [exepath , '--project=' + project , '--startup-file=no' , '-O0' , '--compile=min' ,
145+ '-e' , 'import Libdl; print(abspath(Libdl.dlpath("libjulia")))' ]
113146 CONFIG ['libpath' ] = libpath = subprocess .run (cmd , check = True , capture_output = True , encoding = 'utf8' ).stdout
114147 assert os .path .exists (libpath )
115148
@@ -121,6 +154,8 @@ def path_option(name, default=None):
121154 CONFIG ['lib' ] = lib = c .CDLL (libpath , mode = c .RTLD_GLOBAL )
122155 lib .jl_init__threading .argtypes = []
123156 lib .jl_init__threading .restype = None
157+ argc , argv = args_from_config ()
158+ lib .jl_parse_opts (pointer (argc ), pointer (argv ))
124159 lib .jl_init__threading ()
125160 lib .jl_eval_string .argtypes = [c .c_char_p ]
126161 lib .jl_eval_string .restype = c .c_void_p
0 commit comments