rubypython 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
- data/History.rdoc +32 -0
- data/Manifest.txt +2 -5
- data/lib/rubypython.rb +73 -59
- data/lib/rubypython/conversion.rb +7 -5
- data/lib/rubypython/interpreter.rb +250 -0
- data/lib/rubypython/legacy.rb +2 -23
- data/lib/rubypython/operators.rb +10 -6
- data/lib/rubypython/pymainclass.rb +3 -2
- data/lib/rubypython/pyobject.rb +2 -1
- data/lib/rubypython/python.rb +185 -188
- data/lib/rubypython/rubypyproxy.rb +1 -1
- data/lib/rubypython/tuple.rb +10 -0
- data/spec/conversion_spec.rb +10 -2
- data/spec/python_helpers/basics.py +3 -0
- data/spec/rubypython_spec.rb +0 -24
- data/spec/spec_helper.rb +2 -0
- metadata +122 -122
- metadata.gz.sig +0 -0
- data/.gitignore +0 -13
- data/.hgignore +0 -14
- data/.hgtags +0 -9
- data/lib/rubypython/options.rb +0 -66
- data/lib/rubypython/pythonexec.rb +0 -145
data/lib/rubypython/legacy.rb
CHANGED
@@ -1,29 +1,8 @@
|
|
1
1
|
require 'rubypython'
|
2
2
|
|
3
|
-
# A quick way to
|
3
|
+
# A quick way to activate <em>Legacy Mode</em> for a project. Requiring
|
4
4
|
# +'rubypython/legacy' automatically activates +RubyPython.legacy_mode+ on
|
5
|
-
# the project.
|
6
|
-
#
|
7
|
-
# This mode may be phased out for RubyPython 1.0.
|
8
|
-
#
|
9
|
-
# === Default
|
10
|
-
# require 'rubypython'
|
11
|
-
#
|
12
|
-
# RubyPython.session do
|
13
|
-
# string = RubyPython.import 'string'
|
14
|
-
# ascii_letters = string.ascii_letters
|
15
|
-
# puts ascii_letters.isalpha # => True
|
16
|
-
# puts ascii_letters.rubify.isalpha # throws NoMethodError
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# === Legacy Mode
|
20
|
-
# require 'rubypython/legacy'
|
21
|
-
#
|
22
|
-
# RubyPython.session do
|
23
|
-
# string = RubyPython.import 'string'
|
24
|
-
# ascii_letters = string.ascii_letters
|
25
|
-
# puts ascii_letters.isalpha # throws NoMethodError
|
26
|
-
# end
|
5
|
+
# the project. This mode is deprecated and will be removed.
|
27
6
|
module RubyPython::LegacyMode
|
28
7
|
# Enables +RubyPython.legacy_mode+.
|
29
8
|
def self.setup_legacy
|
data/lib/rubypython/operators.rb
CHANGED
@@ -106,13 +106,17 @@ module RubyPython::Operators
|
|
106
106
|
RubyPython::PyMain.cmp(self, other)
|
107
107
|
end
|
108
108
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
109
|
+
class << self
|
110
|
+
# Called by RubyPython when the interpreter is started or stopped so
|
111
|
+
# that the necessary preparation or cleanup can be done. For internal
|
112
|
+
# use only.
|
113
|
+
def python_interpreter_update(status)
|
114
|
+
case status
|
115
|
+
when :stop
|
116
|
+
@@operator = nil
|
117
|
+
end
|
115
118
|
end
|
119
|
+
private :python_interpreter_update
|
116
120
|
end
|
117
121
|
|
118
122
|
# Aliases eql? to == for Python objects.
|
@@ -63,15 +63,16 @@ module RubyPython
|
|
63
63
|
end
|
64
64
|
|
65
65
|
# Called by RubyPython when the interpreter is started or stopped so
|
66
|
-
# that the neccesary
|
66
|
+
# that the neccesary preparation or cleanup can be done. For internal
|
67
67
|
# use only.
|
68
|
-
def
|
68
|
+
def python_interpreter_update(status)
|
69
69
|
case status
|
70
70
|
when :stop
|
71
71
|
@main = nil
|
72
72
|
@builtin = nil
|
73
73
|
end
|
74
74
|
end
|
75
|
+
private :python_interpreter_update
|
75
76
|
end
|
76
77
|
|
77
78
|
# The accessible instance of PyMainClass.
|
data/lib/rubypython/pyobject.rb
CHANGED
@@ -35,12 +35,13 @@ class RubyPython::PyObject # :nodoc: all
|
|
35
35
|
# Called by RubyPython when the interpreter is started or stopped so
|
36
36
|
# that the necessary preparation or cleanup can be done. For internal
|
37
37
|
# use only.
|
38
|
-
def
|
38
|
+
def python_interpreter_update(status)
|
39
39
|
case status
|
40
40
|
when :stop
|
41
41
|
current_pointers.clear
|
42
42
|
end
|
43
43
|
end
|
44
|
+
private :python_interpreter_update
|
44
45
|
end
|
45
46
|
|
46
47
|
self.current_pointers = {}
|
data/lib/rubypython/python.rb
CHANGED
@@ -1,198 +1,195 @@
|
|
1
1
|
require 'ffi'
|
2
|
-
require '
|
3
|
-
require 'rubypython/
|
2
|
+
require 'thread'
|
3
|
+
require 'rubypython/interpreter'
|
4
4
|
|
5
5
|
module RubyPython
|
6
|
-
|
7
|
-
|
8
|
-
PYTHON_RB.freeze
|
6
|
+
# This module will hold the loaded RubyPython interpreter.
|
7
|
+
module Python #:nodoc: all
|
9
8
|
end
|
10
|
-
|
11
|
-
module Python; end
|
12
9
|
end
|
13
10
|
|
14
|
-
|
15
|
-
#
|
16
|
-
#
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
93
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
11
|
+
class RubyPython::Interpreter
|
12
|
+
# Infects the provided module with the Python FFI. Once a single module
|
13
|
+
# has been infected, the #infect! method is removed from
|
14
|
+
# RubyPython::Interpreter.
|
15
|
+
def infect!(mod)
|
16
|
+
Mutex.new.synchronize do
|
17
|
+
self.class.class_eval do
|
18
|
+
undef :infect!
|
19
|
+
end
|
20
|
+
|
21
|
+
mod.extend FFI::Library
|
22
|
+
# FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL
|
23
|
+
mod.ffi_lib_flags :lazy, :global
|
24
|
+
mod.ffi_lib self.library
|
25
|
+
|
26
|
+
# This class is a little bit of a hack to extract the address of
|
27
|
+
# global structs. If someone knows a better way please let me know.
|
28
|
+
mod.module_eval do
|
29
|
+
self.const_set :DummyStruct, Class.new(FFI::Struct)
|
30
|
+
self::DummyStruct.layout :dummy_var, :int
|
31
|
+
|
32
|
+
self.const_set(:PY_FILE_INPUT, 257)
|
33
|
+
self.const_set(:PY_EVAL_INPUT, 258)
|
34
|
+
self.const_set(:METH_VARARGS, 0x0001)
|
35
|
+
|
36
|
+
# Function methods & constants
|
37
|
+
attach_function :PyCFunction_New, [:pointer, :pointer], :pointer
|
38
|
+
callback :PyCFunction, [:pointer, :pointer], :pointer
|
39
|
+
|
40
|
+
attach_function :PyRun_String, [:string, :int, :pointer, :pointer], :pointer
|
41
|
+
attach_function :PyRun_SimpleString, [:string], :pointer
|
42
|
+
attach_function :Py_CompileString, [:string, :string, :int], :pointer
|
43
|
+
attach_function :PyEval_EvalCode, [:pointer, :pointer, :pointer], :pointer
|
44
|
+
attach_function :PyErr_SetString, [:pointer, :string], :void
|
45
|
+
|
46
|
+
# Python interpreter startup and shutdown
|
47
|
+
attach_function :Py_IsInitialized, [], :int
|
48
|
+
attach_function :Py_Initialize, [], :void
|
49
|
+
attach_function :Py_Finalize, [], :void
|
50
|
+
|
51
|
+
# Module methods
|
52
|
+
attach_function :PyImport_ImportModule, [:string], :pointer
|
53
|
+
|
54
|
+
# Object Methods
|
55
|
+
attach_function :PyObject_HasAttrString, [:pointer, :string], :int
|
56
|
+
attach_function :PyObject_GetAttrString, [:pointer, :string], :pointer
|
57
|
+
attach_function :PyObject_SetAttrString, [:pointer, :string, :pointer], :int
|
58
|
+
attach_function :PyObject_Dir, [:pointer], :pointer
|
59
|
+
|
60
|
+
attach_function :PyObject_Compare, [:pointer, :pointer], :int
|
61
|
+
|
62
|
+
attach_function :PyObject_Call, [:pointer, :pointer, :pointer], :pointer
|
63
|
+
attach_function :PyObject_CallObject, [:pointer, :pointer], :pointer
|
64
|
+
attach_function :PyCallable_Check, [:pointer], :int
|
65
|
+
|
66
|
+
### Python To Ruby Conversion
|
67
|
+
# String Methods
|
68
|
+
attach_function :PyString_AsString, [:pointer], :string
|
69
|
+
attach_function :PyString_FromString, [:string], :pointer
|
70
|
+
attach_function :PyString_AsStringAndSize, [:pointer, :pointer, :pointer], :int
|
71
|
+
attach_function :PyString_FromStringAndSize, [:buffer_in, :ssize_t], :pointer
|
72
|
+
|
73
|
+
# List Methods
|
74
|
+
attach_function :PyList_GetItem, [:pointer, :int], :pointer
|
75
|
+
attach_function :PyList_Size, [:pointer], :int
|
76
|
+
attach_function :PyList_New, [:int], :pointer
|
77
|
+
attach_function :PyList_SetItem, [:pointer, :int, :pointer], :void
|
78
|
+
|
79
|
+
# Integer Methods
|
80
|
+
attach_function :PyInt_AsLong, [:pointer], :long
|
81
|
+
attach_function :PyInt_FromLong, [:long], :pointer
|
82
|
+
|
83
|
+
attach_function :PyLong_AsLong, [:pointer], :long
|
84
|
+
attach_function :PyLong_FromLong, [:pointer], :long
|
85
|
+
|
86
|
+
# Float Methods
|
87
|
+
attach_function :PyFloat_AsDouble, [:pointer], :double
|
88
|
+
attach_function :PyFloat_FromDouble, [:double], :pointer
|
89
|
+
|
90
|
+
# Tuple Methods
|
91
|
+
attach_function :PySequence_List, [:pointer], :pointer
|
92
|
+
attach_function :PySequence_Tuple, [:pointer], :pointer
|
93
|
+
attach_function :PyTuple_Pack, [:int, :varargs], :pointer
|
94
|
+
|
95
|
+
# Dict/Hash Methods
|
96
|
+
attach_function :PyDict_Next, [:pointer, :pointer, :pointer, :pointer], :int
|
97
|
+
attach_function :PyDict_New, [], :pointer
|
98
|
+
attach_function :PyDict_SetItem, [:pointer, :pointer, :pointer], :int
|
99
|
+
attach_function :PyDict_Contains, [:pointer, :pointer], :int
|
100
|
+
attach_function :PyDict_GetItem, [:pointer, :pointer], :pointer
|
101
|
+
|
102
|
+
# Error Methods
|
103
|
+
attach_variable :PyExc_Exception, self::DummyStruct.by_ref
|
104
|
+
attach_variable :PyExc_StopIteration, self::DummyStruct.by_ref
|
105
|
+
attach_function :PyErr_SetNone, [:pointer], :void
|
106
|
+
attach_function :PyErr_Fetch, [:pointer, :pointer, :pointer], :void
|
107
|
+
attach_function :PyErr_Occurred, [], :pointer
|
108
|
+
attach_function :PyErr_Clear, [], :void
|
109
|
+
|
110
|
+
# Reference Counting
|
111
|
+
attach_function :Py_IncRef, [:pointer], :void
|
112
|
+
attach_function :Py_DecRef, [:pointer], :void
|
113
|
+
|
114
|
+
# Type Objects
|
115
|
+
# attach_variable :PyBaseObject_Type, self::DummyStruct.by_value # built-in 'object'
|
116
|
+
# attach_variable :PyBaseString_Type, self::DummyStruct.by_value
|
117
|
+
# attach_variable :PyBool_Type, self::DummyStruct.by_value
|
118
|
+
# attach_variable :PyBuffer_Type, self::DummyStruct.by_value
|
119
|
+
# attach_variable :PyByteArrayIter_Type, self::DummyStruct.by_value
|
120
|
+
# attach_variable :PyByteArray_Type, self::DummyStruct.by_value
|
121
|
+
attach_variable :PyCFunction_Type, self::DummyStruct.by_value
|
122
|
+
# attach_variable :PyCObject_Type, self::DummyStruct.by_value
|
123
|
+
# attach_variable :PyCallIter_Type, self::DummyStruct.by_value
|
124
|
+
# attach_variable :PyCapsule_Type, self::DummyStruct.by_value
|
125
|
+
# attach_variable :PyCell_Type, self::DummyStruct.by_value
|
126
|
+
# attach_variable :PyClassMethod_Type, self::DummyStruct.by_value
|
127
|
+
attach_variable :PyClass_Type, self::DummyStruct.by_value
|
128
|
+
# attach_variable :PyCode_Type, self::DummyStruct.by_value
|
129
|
+
# attach_variable :PyComplex_Type, self::DummyStruct.by_value
|
130
|
+
# attach_variable :PyDictItems_Type, self::DummyStruct.by_value
|
131
|
+
# attach_variable :PyDictIterItem_Type, self::DummyStruct.by_value
|
132
|
+
# attach_variable :PyDictIterKey_Type, self::DummyStruct.by_value
|
133
|
+
# attach_variable :PyDictIterValue_Type, self::DummyStruct.by_value
|
134
|
+
# attach_variable :PyDictKeys_Type, self::DummyStruct.by_value
|
135
|
+
# attach_variable :PyDictProxy_Type, self::DummyStruct.by_value
|
136
|
+
# attach_variable :PyDictValues_Type, self::DummyStruct.by_value
|
137
|
+
attach_variable :PyDict_Type, self::DummyStruct.by_value
|
138
|
+
# attach_variable :PyEllipsis_Type, self::DummyStruct.by_value
|
139
|
+
# attach_variable :PyEnum_Type, self::DummyStruct.by_value
|
140
|
+
# attach_variable :PyFile_Type, self::DummyStruct.by_value
|
141
|
+
attach_variable :PyFloat_Type, self::DummyStruct.by_value
|
142
|
+
# attach_variable :PyFrame_Type, self::DummyStruct.by_value
|
143
|
+
# attach_variable :PyFrozenSet_Type, self::DummyStruct.by_value
|
144
|
+
attach_variable :PyFunction_Type, self::DummyStruct.by_value
|
145
|
+
# attach_variable :PyGen_Type, self::DummyStruct.by_value
|
146
|
+
# attach_variable :PyGetSetDescr_Type, self::DummyStruct.by_value
|
147
|
+
# attach_variable :PyInstance_Type, self::DummyStruct.by_value
|
148
|
+
attach_variable :PyInt_Type, self::DummyStruct.by_value
|
149
|
+
attach_variable :PyList_Type, self::DummyStruct.by_value
|
150
|
+
attach_variable :PyLong_Type, self::DummyStruct.by_value
|
151
|
+
# attach_variable :PyMemberDescr_Type, self::DummyStruct.by_value
|
152
|
+
# attach_variable :PyMemoryView_Type, self::DummyStruct.by_value
|
153
|
+
attach_variable :PyMethod_Type, self::DummyStruct.by_value
|
154
|
+
# attach_variable :PyModule_Type, self::DummyStruct.by_value
|
155
|
+
# attach_variable :PyNullImporter_Type, self::DummyStruct.by_value
|
156
|
+
# attach_variable :PyProperty_Type, self::DummyStruct.by_value
|
157
|
+
# attach_variable :PyRange_Type, self::DummyStruct.by_value
|
158
|
+
# attach_variable :PyReversed_Type, self::DummyStruct.by_value
|
159
|
+
# attach_variable :PySTEntry_Type, self::DummyStruct.by_value
|
160
|
+
# attach_variable :PySeqIter_Type, self::DummyStruct.by_value
|
161
|
+
# attach_variable :PySet_Type, self::DummyStruct.by_value
|
162
|
+
# attach_variable :PySlice_Type, self::DummyStruct.by_value
|
163
|
+
# attach_variable :PyStaticMethod_Type, self::DummyStruct.by_value
|
164
|
+
attach_variable :PyString_Type, self::DummyStruct.by_value
|
165
|
+
# attach_variable :PySuper_Type, self::DummyStruct.by_value # built-in 'super'
|
166
|
+
# attach_variable :PyTraceBack_Type, self::DummyStruct.by_value
|
167
|
+
attach_variable :PyTuple_Type, self::DummyStruct.by_value
|
168
|
+
attach_variable :PyType_Type, self::DummyStruct.by_value
|
169
|
+
# attach_variable :PyUnicode_Type, self::DummyStruct.by_value
|
170
|
+
# attach_variable :PyWrapperDescr_Type, self::DummyStruct.by_value
|
171
|
+
|
172
|
+
attach_variable :Py_TrueStruct, :_Py_TrueStruct, self::DummyStruct.by_value
|
173
|
+
attach_variable :Py_ZeroStruct, :_Py_ZeroStruct, self::DummyStruct.by_value
|
174
|
+
attach_variable :Py_NoneStruct, :_Py_NoneStruct, self::DummyStruct.by_value
|
175
|
+
|
176
|
+
# This is an implementation of the basic structure of a Python PyObject
|
177
|
+
# struct. The C struct is actually much larger, but since we only access
|
178
|
+
# the first two data members via FFI and always deal with struct
|
179
|
+
# pointers there is no need to mess around with the rest of the object.
|
180
|
+
self.const_set :PyObjectStruct, Class.new(FFI::Struct)
|
181
|
+
self::PyObjectStruct.layout :ob_refcnt, :ssize_t,
|
182
|
+
:ob_type, :pointer
|
183
|
+
|
184
|
+
# This struct is used when defining Python methods.
|
185
|
+
self.const_set :PyMethodDef, Class.new(FFI::Struct)
|
186
|
+
self::PyMethodDef.layout :ml_name, :pointer,
|
187
|
+
:ml_meth, :PyCFunction,
|
188
|
+
:ml_flags, :int,
|
189
|
+
:ml_doc, :pointer
|
190
|
+
end
|
189
191
|
|
190
|
-
# This struct is used when defining Python methods.
|
191
|
-
class PyMethodDef < FFI::Struct
|
192
|
-
layout :ml_name, :pointer,
|
193
|
-
:ml_meth, :PyCFunction,
|
194
|
-
:ml_flags, :int,
|
195
|
-
:ml_doc, :pointer
|
196
192
|
end
|
197
193
|
end
|
194
|
+
private :infect!
|
198
195
|
end
|