@@ -45,8 +45,50 @@ class JuliaError(Exception):
45
45
pass
46
46
47
47
48
+ def jl_name (name ):
49
+ if name .endswith ('_b' ):
50
+ return name [:- 2 ] + '!'
51
+ return name
52
+
53
+
48
54
class JuliaModule (ModuleType ):
49
- pass
55
+
56
+ def __init__ (self , loader , * args , ** kwargs ):
57
+ super (JuliaModule , self ).__init__ (* args , ** kwargs )
58
+ self ._julia = loader .julia
59
+ self .__loader__ = loader
60
+
61
+ def __getattr__ (self , name ):
62
+ try :
63
+ return self .__try_getattr (name )
64
+ except AttributeError :
65
+ if name .endswith ("_b" ):
66
+ try :
67
+ return self .__try_getattr (jl_name (name ))
68
+ except AttributeError :
69
+ pass
70
+ raise
71
+
72
+ def __try_getattr (self , name ):
73
+ juliapath = self .__name__ .lstrip ("julia." )
74
+ try :
75
+ module_path = "." .join ((juliapath , name ))
76
+ is_module = self ._julia .eval ("isa({}, Module)" .format (module_path ))
77
+ if is_module :
78
+ # TODO: find a better way to handle submodules
79
+ split_path = module_path .split ("." )
80
+ is_base = split_path [- 1 ] == "Base"
81
+ recur_module = split_path [- 1 ] == split_path [- 2 ]
82
+ if not is_base and not recur_module :
83
+ newpath = "." .join ((self .__name__ , name ))
84
+ return self .__loader__ .load_module (newpath )
85
+ return self ._julia .eval (module_path )
86
+ except Exception :
87
+ if isafunction (self ._julia , name , mod_name = juliapath ):
88
+ func = "{}.{}" .format (juliapath , name )
89
+ return self ._julia .eval (func )
90
+
91
+ raise AttributeError (name )
50
92
51
93
52
94
@@ -72,38 +114,7 @@ def __init__(self, julia):
72
114
def load_module (self , fullname ):
73
115
juliapath = fullname .lstrip ("julia." )
74
116
if isamodule (self .julia , juliapath ):
75
- mod = sys .modules .setdefault (fullname , JuliaModule (fullname ))
76
- mod .__loader__ = self
77
- names = self .julia .eval ("names({}, true, false)" .format (juliapath ))
78
- for name in names :
79
- if (ismacro (name ) or
80
- isoperator (name ) or
81
- isprotected (name ) or
82
- notascii (name )):
83
- continue
84
- attrname = name
85
- if name .endswith ("!" ):
86
- attrname = name .replace ("!" , "_b" )
87
- if keyword .iskeyword (name ):
88
- attrname = "jl" .join (name )
89
- try :
90
- module_path = "." .join ((juliapath , name ))
91
- module_obj = self .julia .eval (module_path )
92
- is_module = self .julia .eval ("isa({}, Module)"
93
- .format (module_path ))
94
- if is_module :
95
- split_path = module_path .split ("." )
96
- is_base = split_path [- 1 ] == "Base"
97
- recur_module = split_path [- 1 ] == split_path [- 2 ]
98
- if is_module and not is_base and not recur_module :
99
- newpath = "." .join ((fullname , name ))
100
- module_obj = self .load_module (newpath )
101
- setattr (mod , attrname , module_obj )
102
- except Exception :
103
- if isafunction (self .julia , name , mod_name = juliapath ):
104
- func = "{}.{}" .format (juliapath , name )
105
- setattr (mod , name , self .julia .eval (func ))
106
- return mod
117
+ return sys .modules .setdefault (fullname , JuliaModule (self , fullname ))
107
118
elif isafunction (self .julia , juliapath ):
108
119
return getattr (self .julia , juliapath )
109
120
else :
0 commit comments