rubypython-raspi 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rubypython/interpreter.rb +248 -0
- data/lib/rubypython/tuple.rb +10 -0
- metadata +3 -1
@@ -0,0 +1,248 @@
|
|
1
|
+
# -*- ruby encoding: utf-8 -*-
|
2
|
+
|
3
|
+
class RubyPython::InvalidInterpreter < Exception
|
4
|
+
end
|
5
|
+
|
6
|
+
##
|
7
|
+
# An instance of this class represents information about a particular
|
8
|
+
# \Python interpreter.
|
9
|
+
#
|
10
|
+
# This class represents the current Python interpreter.
|
11
|
+
# A class that represents a \Python executable.
|
12
|
+
#
|
13
|
+
# End users may get the instance that represents the current running \Python
|
14
|
+
# interpreter (from +RubyPython.python+), but should not directly
|
15
|
+
# instantiate this class.
|
16
|
+
class RubyPython::Interpreter
|
17
|
+
|
18
|
+
##
|
19
|
+
# Compare the current Interpreter to the provided Interpreter or
|
20
|
+
# configuration hash. A configuration hash will be converted to an
|
21
|
+
# Interpreter object before being compared.
|
22
|
+
# :python_exe basename is used. If comparing against another Interpreter
|
23
|
+
# object, the Interpreter basename and version are used.
|
24
|
+
def ==(other)
|
25
|
+
other = self.class.new(other) if other.kind_of? Hash
|
26
|
+
return false unless other.kind_of? self.class
|
27
|
+
(self.version == other.version) && (self.version_name == other.version_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Create a new instance of an Interpreter instance describing a particular
|
32
|
+
# \Python executable and shared library.
|
33
|
+
#
|
34
|
+
# Expects a hash that matches the configuration options provided to
|
35
|
+
# RubyPython.start; currently only one value is recognized in that hash:
|
36
|
+
#
|
37
|
+
# * <tt>:python_exe</tt>: Specifies the name of the python executable to
|
38
|
+
# run.
|
39
|
+
def initialize(options = {})
|
40
|
+
@python_exe = options[:python_exe]
|
41
|
+
# Windows: 'C:\\Python27\python.exe'
|
42
|
+
# Mac OS X: '/usr/bin/
|
43
|
+
rc, @python = runpy "import sys; print sys.executable"
|
44
|
+
if rc.exitstatus.nonzero?
|
45
|
+
raise RubyPython::InvalidInterpreter, "An invalid interpreter was specified."
|
46
|
+
end
|
47
|
+
rc, @version = runpy "import sys; print '%d.%d' % sys.version_info[:2]"
|
48
|
+
rc, @sys_prefix = runpy "import sys; print sys.prefix"
|
49
|
+
|
50
|
+
if FFI::Platform.windows?
|
51
|
+
flat_version = @version.tr('.', '')
|
52
|
+
basename = File.basename(@python, '.exe')
|
53
|
+
|
54
|
+
if basename =~ /(?:#{@version}|#{flat_version})$/
|
55
|
+
@version_name = basename
|
56
|
+
else
|
57
|
+
@version_name = "#{basename}#{flat_version}"
|
58
|
+
end
|
59
|
+
else
|
60
|
+
basename = File.basename(@python)
|
61
|
+
|
62
|
+
if basename =~ /#{@version}/
|
63
|
+
@version_name = basename
|
64
|
+
else
|
65
|
+
@version_name = "#{basename}#{@version}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
@library = find_python_lib
|
70
|
+
end
|
71
|
+
|
72
|
+
def find_python_lib
|
73
|
+
# By default, the library name will be something like
|
74
|
+
# libpython2.6.so, but that won't always work.
|
75
|
+
@libbase = "#{FFI::Platform::LIBPREFIX}#{@version_name}"
|
76
|
+
@libext = FFI::Platform::LIBSUFFIX
|
77
|
+
@libname = "#{@libbase}.#{@libext}"
|
78
|
+
|
79
|
+
# We may need to look in multiple locations for Python, so let's
|
80
|
+
# build this as an array.
|
81
|
+
@locations = [ File.join(@sys_prefix, "lib", @libname) ]
|
82
|
+
|
83
|
+
if FFI::Platform.mac?
|
84
|
+
# On the Mac, let's add a special case that has even a different
|
85
|
+
# @libname. This may not be fully useful on future versions of OS
|
86
|
+
# X, but it should work on 10.5 and 10.6. Even if it doesn't, the
|
87
|
+
# next step will (/usr/lib/libpython<version>.dylib is a symlink
|
88
|
+
# to the correct location).
|
89
|
+
@locations << File.join(@sys_prefix, "Python")
|
90
|
+
# Let's also look in the location that was originally set in this
|
91
|
+
# library:
|
92
|
+
File.join(@sys_prefix, "lib", "#{@realname}", "config", @libname)
|
93
|
+
end
|
94
|
+
|
95
|
+
if FFI::Platform.unix?
|
96
|
+
# On Unixes, let's look in some standard alternative places, too.
|
97
|
+
# Just in case. Some Unixes don't include a .so symlink when they
|
98
|
+
# should, so let's look for the base case of .so.1, too.
|
99
|
+
[ @libname, "#{@libname}.1" ].each do |name|
|
100
|
+
@locations << File.join("/opt/local/lib", name)
|
101
|
+
@locations << File.join("/opt/lib", name)
|
102
|
+
@locations << File.join("/usr/local/lib", name)
|
103
|
+
@locations << File.join("/usr/lib", name)
|
104
|
+
@locations << File.join("/opt/local/lib64", name)
|
105
|
+
@locations << File.join("/opt/lib64", name)
|
106
|
+
@locations << File.join("/usr/local/lib64", name)
|
107
|
+
@locations << File.join("/usr/lib64", name)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
if FFI::Platform.windows?
|
112
|
+
# On Windows, the appropriate DLL is usually be found in
|
113
|
+
# %SYSTEMROOT%\system or %SYSTEMROOT%\system32; as a fallback we'll
|
114
|
+
# use C:\Windows\system{,32} as well as the install directory and the
|
115
|
+
# install directory + libs.
|
116
|
+
system_root = File.expand_path(ENV['SYSTEMROOT']).gsub(/\\/, '/')
|
117
|
+
@locations << File.join(system_root, 'system', @libname)
|
118
|
+
@locations << File.join(system_root, 'system32', @libname)
|
119
|
+
@locations << File.join("C:/WINDOWS", "System", @libname)
|
120
|
+
@locations << File.join("C:/WINDOWS", "System32", @libname)
|
121
|
+
@locations << File.join(sys_prefix, @libname)
|
122
|
+
@locations << File.join(sys_prefix, 'libs', @libname)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Let's add alternative extensions; again, just in case.
|
126
|
+
@locations.dup.each do |location|
|
127
|
+
path = File.dirname(location)
|
128
|
+
base = File.basename(location, ".#{@libext}")
|
129
|
+
@locations << File.join(path, "#{base}.so") # Standard Unix
|
130
|
+
@locations << File.join(path, "#{base}.dylib") # Mac OS X
|
131
|
+
@locations << File.join(path, "#{base}.dll") # Windows
|
132
|
+
end
|
133
|
+
|
134
|
+
# Remove redundant locations
|
135
|
+
@locations.uniq!
|
136
|
+
|
137
|
+
library = nil
|
138
|
+
|
139
|
+
@locations.each do |location|
|
140
|
+
if File.exists? location
|
141
|
+
library = location
|
142
|
+
break
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
library
|
147
|
+
end
|
148
|
+
private :find_python_lib
|
149
|
+
|
150
|
+
def valid?
|
151
|
+
if @python.nil? or @python.empty?
|
152
|
+
false
|
153
|
+
elsif @library.nil? or @library.empty?
|
154
|
+
false
|
155
|
+
else
|
156
|
+
true
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# The name of the \Python executable that is used. This is the value of
|
162
|
+
# 'sys.executable' for the \Python interpreter provided in
|
163
|
+
# <tt>:python_exe</tt> or 'python' if it is not provided.
|
164
|
+
#
|
165
|
+
# On Mac OS X Lion (10.7), this value is '/usr/bin/python' for 'python'.
|
166
|
+
attr_reader :python
|
167
|
+
##
|
168
|
+
# The version of the \Python interpreter. This is a decimalized version of
|
169
|
+
# 'sys.version_info[:2]' (such that \Python 2.7.1 is reported as '2.7').
|
170
|
+
attr_reader :version
|
171
|
+
##
|
172
|
+
# The system prefix for the \Python interpreter. This is the value of
|
173
|
+
# 'sys.prefix'.
|
174
|
+
attr_reader :sys_prefix
|
175
|
+
##
|
176
|
+
# The basename of the \Python interpreter with a version number. This is
|
177
|
+
# mostly an intermediate value used to find the shared \Python library,
|
178
|
+
# but /usr/bin/python is often a link to /usr/bin/python2.7 so it may be
|
179
|
+
# of value. Note that this does *not* include the full path to the
|
180
|
+
# interpreter.
|
181
|
+
attr_reader :version_name
|
182
|
+
|
183
|
+
# The \Python library.
|
184
|
+
attr_reader :library
|
185
|
+
|
186
|
+
# Run a Python command-line command.
|
187
|
+
def runpy(command)
|
188
|
+
i = @python || @python_exe || 'python'
|
189
|
+
if FFI::Platform.windows?
|
190
|
+
o = %x(#{i} -c "#{command}" 2> NUL:)
|
191
|
+
else
|
192
|
+
o = %x(#{i} -c "#{command}" 2> /dev/null)
|
193
|
+
end
|
194
|
+
|
195
|
+
[ $?, o.chomp ]
|
196
|
+
end
|
197
|
+
private :runpy
|
198
|
+
|
199
|
+
def inspect(debug = false)
|
200
|
+
if debug
|
201
|
+
debug_s
|
202
|
+
elsif @python
|
203
|
+
"#<#{self.class}: #{python} v#{version} #{sys_prefix} #{version_name}>"
|
204
|
+
else
|
205
|
+
"#<#{self.class}: invalid interpreter>"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def debug_s(format = nil)
|
210
|
+
system = ""
|
211
|
+
system << "windows " if FFI::Platform.windows?
|
212
|
+
system << "mac " if FFI::Platform.mac?
|
213
|
+
system << "unix " if FFI::Platform.unix?
|
214
|
+
system << "unknown " if system.empty?
|
215
|
+
|
216
|
+
case format
|
217
|
+
when :report
|
218
|
+
s = <<-EOS
|
219
|
+
python_exe: #{@python_exe}
|
220
|
+
python: #{@python}
|
221
|
+
version: #{@version}
|
222
|
+
sys_prefix: #{@sys_prefix}
|
223
|
+
version_name: #{@version_name}
|
224
|
+
platform: #{system.chomp}
|
225
|
+
library: #{@library.inspect}
|
226
|
+
libbase: #{@libbase}
|
227
|
+
libext: #{@libext}
|
228
|
+
libname: #{@libname}
|
229
|
+
locations: #{@locations.inspect}
|
230
|
+
EOS
|
231
|
+
else
|
232
|
+
s = "#<#{self.class}: "
|
233
|
+
s << "python_exe=#{@python_exe.inspect} "
|
234
|
+
s << "python=#{@python.inspect} "
|
235
|
+
s << "version=#{@version.inspect} "
|
236
|
+
s << "sys_prefix=#{@sys_prefix.inspect} "
|
237
|
+
s << "version_name=#{@version_name.inspect} "
|
238
|
+
s << system
|
239
|
+
s << "library=#{@library.inspect} "
|
240
|
+
s << "libbase=#{@libbase.inspect} "
|
241
|
+
s << "libext=#{@libext.inspect} "
|
242
|
+
s << "libname=#{@libname.inspect} "
|
243
|
+
s << "locations=#{@locations.inspect}"
|
244
|
+
end
|
245
|
+
|
246
|
+
s
|
247
|
+
end
|
248
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubypython-raspi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -145,6 +145,7 @@ files:
|
|
145
145
|
- lib/rubypython.rb
|
146
146
|
- lib/rubypython/blankobject.rb
|
147
147
|
- lib/rubypython/conversion.rb
|
148
|
+
- lib/rubypython/interpreter.rb
|
148
149
|
- lib/rubypython/legacy.rb
|
149
150
|
- lib/rubypython/macros.rb
|
150
151
|
- lib/rubypython/operators.rb
|
@@ -155,6 +156,7 @@ files:
|
|
155
156
|
- lib/rubypython/pythonerror.rb
|
156
157
|
- lib/rubypython/rubypyproxy.rb
|
157
158
|
- lib/rubypython/type.rb
|
159
|
+
- lib/rubypython/tuple.rb
|
158
160
|
- spec/basic_spec.rb
|
159
161
|
- spec/callback_spec.rb
|
160
162
|
- spec/conversion_spec.rb
|