Module: RbbtPython
- Extended by:
- PyCall::Import
- Defined in:
- lib/rbbt/util/python.rb,
lib/rbbt/util/python/run.rb,
lib/rbbt/util/python/util.rb,
lib/rbbt/util/python/paths.rb,
lib/rbbt/util/python/script.rb
Defined Under Namespace
Classes: Binding, RbbtPythonException
Constant Summary
collapse
- MUTEX =
Mutex.new
Class Attribute Summary collapse
Class Method Summary
collapse
-
.add_path(path) ⇒ Object
-
.add_paths(paths) ⇒ Object
-
.binding_run(binding = nil, *args, &block) ⇒ Object
-
.call_method(module_name, method_name, *args) ⇒ Object
-
.class_new_obj(module_name, class_name, args = {}) ⇒ Object
-
.collect(iterator, options = {}, &block) ⇒ Object
-
.df2tsv(tuple, options = {}) ⇒ Object
-
.exec(script) ⇒ Object
-
.get_class(module_name, class_name) ⇒ Object
-
.get_module(module_name) ⇒ Object
-
.import_method(module_name, method_name, as = nil) ⇒ Object
-
.init_rbbt ⇒ Object
-
.init_thread ⇒ Object
-
.iterate(iterator, options = {}, &block) ⇒ Object
-
.iterate_index(elem, options = {}) ⇒ Object
-
.list2ruby(list) ⇒ Object
-
.load_json(file) ⇒ Object
-
.load_pickle(file) ⇒ Object
(also: load_result)
-
.load_script_variables(variables = {}) ⇒ Object
-
.new_binding ⇒ Object
-
.numpy2ruby(numpy) ⇒ Object
-
.obj2hash(obj) ⇒ Object
-
.process_paths ⇒ Object
-
.py2ruby_a(array) ⇒ Object
(also: to_a)
-
.ruby2python(object) ⇒ Object
-
.run_direct(mod = nil, imports = nil, &block) ⇒ Object
-
.run_in_thread(&block) ⇒ Object
-
.run_log(mod = nil, imports = nil, severity = 0, severity_err = nil, &block) ⇒ Object
-
.run_log_stderr(mod = nil, imports = nil, severity = 0, &block) ⇒ Object
-
.run_simple(mod = nil, imports = nil, &block) ⇒ Object
(also: run)
-
.run_threaded(mod = nil, imports = nil, &block) ⇒ Object
-
.save_script_result_json(file) ⇒ Object
-
.save_script_result_pickle(file) ⇒ Object
(also: save_script_result)
-
.script(text, variables = {}) ⇒ Object
-
.stop_thread ⇒ Object
-
.synchronize(&block) ⇒ Object
-
.tsv2df(tsv) ⇒ Object
Class Attribute Details
.paths ⇒ Object
Returns the value of attribute paths.
3
4
5
|
# File 'lib/rbbt/util/python/paths.rb', line 3
def paths
@paths
end
|
.thread ⇒ Object
Returns the value of attribute thread.
3
4
5
|
# File 'lib/rbbt/util/python/run.rb', line 3
def thread
@thread
end
|
Class Method Details
.add_path(path) ⇒ Object
9
10
11
|
# File 'lib/rbbt/util/python/paths.rb', line 9
def self.add_path(path)
self.paths << path
end
|
.add_paths(paths) ⇒ Object
13
14
15
|
# File 'lib/rbbt/util/python/paths.rb', line 13
def self.add_paths(paths)
self.paths.concat paths
end
|
.binding_run(binding = nil, *args, &block) ⇒ Object
146
147
148
149
|
# File 'lib/rbbt/util/python.rb', line 146
def self.binding_run(binding = nil, *args, &block)
binding = new_binding
binding.instance_exec *args, &block
end
|
.call_method(module_name, method_name, *args) ⇒ Object
39
40
41
|
# File 'lib/rbbt/util/python.rb', line 39
def self.call_method(module_name, method_name, *args)
RbbtPython.import_method(module_name, method_name).call(*args)
end
|
.class_new_obj(module_name, class_name, args = {}) ⇒ Object
55
56
57
|
# File 'lib/rbbt/util/python.rb', line 55
def self.class_new_obj(module_name, class_name, args={})
RbbtPython.get_class(module_name, class_name).new(**args)
end
|
.collect(iterator, options = {}, &block) ⇒ Object
133
134
135
136
137
138
139
140
|
# File 'lib/rbbt/util/python.rb', line 133
def self.collect(iterator, options = {}, &block)
acc = []
self.iterate(iterator, options) do |elem|
res = block.call elem
acc << res
end
acc
end
|
.df2tsv(tuple, options = {}) ⇒ Object
20
21
22
23
24
25
26
27
28
29
30
31
32
|
# File 'lib/rbbt/util/python/util.rb', line 20
def self.df2tsv(tuple, options = {})
options = Misc.add_defaults options, :type => :list
IndiferentHash.setup options
tsv = TSV.setup({}, options)
tsv.key_field = options[:key_field] || tuple.columns.name.to_s
tsv.fields = py2ruby_a(tuple.columns.values)
keys = py2ruby_a(tuple.index.values)
PyCall.len(tuple.index).times do |i|
k = keys[i]
tsv[k] = py2ruby_a(tuple.values[i])
end
tsv
end
|
.exec(script) ⇒ Object
59
60
61
|
# File 'lib/rbbt/util/python.rb', line 59
def self.exec(script)
PyCall.exec(script)
end
|
.get_class(module_name, class_name) ⇒ Object
50
51
52
53
|
# File 'lib/rbbt/util/python.rb', line 50
def self.get_class(module_name, class_name)
mod = get_module(module_name)
mod.send(class_name)
end
|
.get_module(module_name) ⇒ Object
43
44
45
46
47
48
|
# File 'lib/rbbt/util/python.rb', line 43
def self.get_module(module_name)
init_rbbt
save_module_name = module_name.to_s.gsub(".", "_")
RbbtPython.pyimport(module_name, as: save_module_name)
RbbtPython.send(save_module_name)
end
|
.import_method(module_name, method_name, as = nil) ⇒ Object
33
34
35
36
37
|
# File 'lib/rbbt/util/python.rb', line 33
def self.import_method(module_name, method_name, as = nil)
init_rbbt
RbbtPython.pyfrom module_name, import: method_name
RbbtPython.method(method_name)
end
|
.init_rbbt ⇒ Object
22
23
24
25
26
27
28
29
30
31
|
# File 'lib/rbbt/util/python.rb', line 22
def self.init_rbbt
if ! defined?(@@__init_rbbt_python) || ! @@__init_rbbt_python
RbbtPython.process_paths
res = RbbtPython.run do
Log.debug "Loading python 'rbbt' module into pycall RbbtPython module"
pyimport("rbbt")
end
@@__init_rbbt_python = true
end
end
|
.init_thread ⇒ Object
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/rbbt/util/python/run.rb', line 17
def self.init_thread
if defined?(self.thread) && (self.thread && ! self.thread.alive?)
Log.warn "Reloading RbbtPython thread"
self.thread.join
self.thread = nil
end
self.thread ||= Thread.new do
require 'pycall'
RbbtPython.process_paths
begin
while block = QUEUE_IN.pop
break if block == :stop
res =
begin
module_eval(&block)
rescue Exception
Log.exception $!
raise $!
end
QUEUE_OUT.push res
end
rescue Exception
Log.exception $!
raise $!
ensure
PyCall.finalize if PyCall.respond_to?(:finalize)
end
end
end
|
.iterate(iterator, options = {}, &block) ⇒ Object
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/rbbt/util/python.rb', line 94
def self.iterate(iterator, options = {}, &block)
if ! iterator.respond_to?(:__next__)
if iterator.respond_to?(:__iter__)
iterator = iterator.__iter__
else
return iterate_index(iterator, options, &block)
end
end
bar = options[:bar]
case bar
when TrueClass
bar = Log::ProgressBar.new nil, :desc => "RbbtPython iterate"
when String
bar = Log::ProgressBar.new nil, :desc => bar
end
while true
begin
elem = iterator.__next__
yield elem
bar.tick if bar
rescue PyCall::PyError
if $!.type.to_s == "<class 'StopIteration'>"
break
else
raise $!
end
rescue
bar.error if bar
raise $!
end
end
Log::ProgressBar.remove_bar bar if bar
nil
end
|
.iterate_index(elem, options = {}) ⇒ Object
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# File 'lib/rbbt/util/python.rb', line 63
def self.iterate_index(elem, options = {})
bar = options[:bar]
len = PyCall.len(elem)
case bar
when TrueClass
bar = Log::ProgressBar.new nil, :desc => "RbbtPython iterate"
when String
bar = Log::ProgressBar.new nil, :desc => bar
end
len.times do |i|
begin
yield elem[i]
bar.tick if bar
rescue PyCall::PyError
if $!.type.to_s == "<class 'StopIteration'>"
break
else
raise $!
end
rescue
bar.error if bar
raise $!
end
end
Log::ProgressBar.remove_bar bar if bar
nil
end
|
.list2ruby(list) ⇒ Object
34
35
36
37
38
39
|
# File 'lib/rbbt/util/python/util.rb', line 34
def self.list2ruby(list)
return list unless PyCall::List === list
list.collect do |e|
list2ruby(e)
end
end
|
.load_json(file) ⇒ Object
84
85
86
|
# File 'lib/rbbt/util/python/script.rb', line 84
def self.load_json(file)
JSON.load_file(file)
end
|
.load_pickle(file) ⇒ Object
Also known as:
load_result
62
63
64
65
66
|
# File 'lib/rbbt/util/python/script.rb', line 62
def self.load_pickle(file)
require 'python/pickle'
Log.debug ("Loading pickle #{file}")
Python::Pickle.load_file(file)
end
|
.load_script_variables(variables = {}) ⇒ Object
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
# File 'lib/rbbt/util/python/script.rb', line 30
def self.load_script_variables(variables = {})
code = "# Variables\nimport rbbt\n"
tmp_files = []
variables.each do |name,value|
case value
when TSV
tmp_file = TmpFile.tmp_file
tmp_files << tmp_file
Open.write(tmp_file, value.to_s)
code << "#{name} = rbbt.tsv('#{tmp_file}')" << "\n"
else
code << "#{name} = #{RbbtPython.ruby2python(value)}" << "\n"
end
end
[code, tmp_files]
end
|
.new_binding ⇒ Object
142
143
144
|
# File 'lib/rbbt/util/python.rb', line 142
def self.new_binding
Binding.new
end
|
.numpy2ruby(numpy) ⇒ Object
41
42
43
|
# File 'lib/rbbt/util/python/util.rb', line 41
def self.numpy2ruby(numpy)
list2ruby(numpy.tolist)
end
|
.obj2hash(obj) ⇒ Object
45
46
47
48
49
50
51
|
# File 'lib/rbbt/util/python/util.rb', line 45
def self.obj2hash(obj)
hash = {}
RbbtPython.iterate obj.keys do |k|
hash[k] = obj[k]
end
hash
end
|
.process_paths ⇒ Object
17
18
19
20
21
22
23
24
|
# File 'lib/rbbt/util/python/paths.rb', line 17
def self.process_paths
RbbtPython.run_direct 'sys' do
RbbtPython.paths.each do |path|
sys.path.append path
end
nil
end
end
|
.py2ruby_a(array) ⇒ Object
Also known as:
to_a
2
3
4
|
# File 'lib/rbbt/util/python/util.rb', line 2
def self.py2ruby_a(array)
PyCall::List.(array).to_a
end
|
.ruby2python(object) ⇒ Object
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# File 'lib/rbbt/util/python/script.rb', line 2
def self.ruby2python(object)
case object
when Float::INFINITY
"inf"
when nil
"None"
when ":NA"
"None"
when Symbol
"#{ object }"
when String
object = object.dup if Path === object
object[0] == ":" ? object[1..-1] : "'#{ object }'"
when Numeric
object
when TrueClass
"True"
when FalseClass
"False"
when Array
"[#{object.collect{|e| ruby2python(e) } * ", "}]"
when Hash
"{" << object.collect{|k,v| [ruby2python(k.to_s), ruby2python(v)] * ":"} * ", " << "}"
else
raise "Type of object not known: #{ object.inspect }"
end
end
|
.run_direct(mod = nil, imports = nil, &block) ⇒ Object
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# File 'lib/rbbt/util/python/run.rb', line 64
def self.run_direct(mod = nil, imports = nil, &block)
if mod
if Hash === imports
pyimport mod, **imports
elsif imports.nil?
pyimport mod
else
pyfrom mod, :import => imports
end
end
module_eval(&block)
end
|
.run_in_thread(&block) ⇒ Object
49
50
51
52
53
54
55
|
# File 'lib/rbbt/util/python/run.rb', line 49
def self.run_in_thread(&block)
self.synchronize do
init_thread
QUEUE_IN.push block
QUEUE_OUT.pop
end
end
|
.run_log(mod = nil, imports = nil, severity = 0, severity_err = nil, &block) ⇒ Object
103
104
105
106
107
|
# File 'lib/rbbt/util/python/run.rb', line 103
def self.run_log(mod = nil, imports = nil, severity = 0, severity_err = nil, &block)
Log.trap_std("Python STDOUT", "Python STDERR", severity, severity_err) do
run(mod, imports, &block)
end
end
|
.run_log_stderr(mod = nil, imports = nil, severity = 0, &block) ⇒ Object
109
110
111
112
113
|
# File 'lib/rbbt/util/python/run.rb', line 109
def self.run_log_stderr(mod = nil, imports = nil, severity = 0, &block)
Log.trap_stderr("Python STDERR", severity) do
run(mod, imports, &block)
end
end
|
.run_simple(mod = nil, imports = nil, &block) ⇒ Object
Also known as:
run
92
93
94
95
96
97
|
# File 'lib/rbbt/util/python/run.rb', line 92
def self.run_simple(mod = nil, imports = nil, &block)
self.synchronize do
RbbtPython.process_paths
run_direct(mod, imports, &block)
end
end
|
.run_threaded(mod = nil, imports = nil, &block) ⇒ Object
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/rbbt/util/python/run.rb', line 78
def self.run_threaded(mod = nil, imports = nil, &block)
run_in_thread do
if Hash === imports
pyimport mod, **imports
elsif imports.nil?
pyimport mod
else
pyfrom mod, :import => imports
end
end if mod
run_in_thread(&block)
end
|
.save_script_result_json(file) ⇒ Object
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/rbbt/util/python/script.rb', line 68
def self.save_script_result_json(file)
<<-EOF
# Save
try: result
except NameError: result = None
if result is not None:
import json
file = open('#{file}', 'w', encoding='utf-8')
# dump information to that file
file.write(json.dumps(result))
file.flush
file.close
EOF
end
|
.save_script_result_pickle(file) ⇒ Object
Also known as:
save_script_result
48
49
50
51
52
53
54
55
56
57
58
59
60
|
# File 'lib/rbbt/util/python/script.rb', line 48
def self.save_script_result_pickle(file)
<<-EOF
# Save
try: result
except NameError: result = None
if result is not None:
import pickle
file = open('#{file}', 'wb')
# dump information to that file
pickle.dump(result, file)
EOF
end
|
.script(text, variables = {}) ⇒ Object
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/rbbt/util/python/script.rb', line 93
def self.script(text, variables = {})
if variables.any?
variable_definitions, tmp_files = load_script_variables(variables)
text = variable_definitions + "\n# Script\n" + text
end
TmpFile.with_file do |tmp_file|
text += save_script_result(tmp_file)
Log.debug "Running python script:\n#{text.dup}"
path_env = RbbtPython.paths * ":"
CMD.cmd_log("env PYTHONPATH=#{path_env} python", {in: text})
tmp_files.each{|file| Open.rm_rf file } if tmp_files
if Open.exists?(tmp_file)
load_result(tmp_file)
end
end
end
|
.stop_thread ⇒ Object
57
58
59
60
61
62
|
# File 'lib/rbbt/util/python/run.rb', line 57
def self.stop_thread
self.synchronize do
QUEUE_IN.push :stop
end if self.thread && self.thread.alive?
self.thread.join if self.thread
end
|
.synchronize(&block) ⇒ Object
13
14
15
|
# File 'lib/rbbt/util/python/run.rb', line 13
def self.synchronize(&block)
MUTEX.synchronize &block
end
|
.tsv2df(tsv) ⇒ Object
11
12
13
14
15
16
17
18
|
# File 'lib/rbbt/util/python/util.rb', line 11
def self.tsv2df(tsv)
df = nil
RbbtPython.run_direct 'pandas' do
df = pandas.DataFrame.new(tsv.values, columns: tsv.fields, index: tsv.keys)
df.columns.name = tsv.key_field
end
df
end
|