rubypython 0.3.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +3 -0
- data/.gemtest +0 -0
- data/.gitignore +13 -0
- data/.hgignore +14 -0
- data/.hgtags +7 -0
- data/.rspec +1 -1
- data/Contributors.rdoc +9 -0
- data/History.rdoc +148 -0
- data/{License.txt → License.rdoc} +7 -1
- data/Manifest.txt +15 -10
- data/PostInstall.txt +11 -4
- data/README.rdoc +272 -0
- data/Rakefile +107 -22
- data/autotest/discover.rb +1 -0
- data/lib/rubypython.rb +214 -120
- data/lib/rubypython/blankobject.rb +16 -14
- data/lib/rubypython/conversion.rb +242 -173
- data/lib/rubypython/legacy.rb +30 -31
- data/lib/rubypython/macros.rb +43 -34
- data/lib/rubypython/operators.rb +103 -101
- data/lib/rubypython/options.rb +41 -44
- data/lib/rubypython/pygenerator.rb +61 -0
- data/lib/rubypython/pymainclass.rb +46 -29
- data/lib/rubypython/pyobject.rb +193 -177
- data/lib/rubypython/python.rb +189 -176
- data/lib/rubypython/pythonerror.rb +54 -63
- data/lib/rubypython/pythonexec.rb +123 -0
- data/lib/rubypython/rubypyproxy.rb +213 -137
- data/lib/rubypython/type.rb +20 -0
- data/spec/basic_spec.rb +50 -0
- data/spec/callback_spec.rb +7 -17
- data/spec/conversion_spec.rb +7 -21
- data/spec/legacy_spec.rb +1 -16
- data/spec/pymainclass_spec.rb +6 -15
- data/spec/pyobject_spec.rb +39 -64
- data/spec/python_helpers/basics.py +20 -0
- data/spec/python_helpers/objects.py +24 -20
- data/spec/pythonerror_spec.rb +5 -17
- data/spec/refcnt_spec.rb +4 -10
- data/spec/rubypyclass_spec.rb +1 -11
- data/spec/rubypyproxy_spec.rb +45 -54
- data/spec/rubypython_spec.rb +45 -57
- data/spec/spec_helper.rb +49 -33
- metadata +87 -63
- data.tar.gz.sig +0 -0
- data/History.markdown +0 -97
- data/README.markdown +0 -105
- data/lib/rubypython/core_ext/string.rb +0 -7
- data/lib/rubypython/version.rb +0 -9
- data/spec/python_helpers/objects.pyc +0 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
require "rubypython/python"
|
2
|
+
require "rubypython/conversion"
|
3
|
+
require 'rubypython/macros'
|
4
|
+
require 'rubypython/conversion'
|
5
|
+
require 'rubypython/pyobject'
|
6
|
+
require "rubypython/pymainclass"
|
7
|
+
require "rubypython/rubypyproxy"
|
8
|
+
|
9
|
+
if defined? Fiber
|
10
|
+
module RubyPython
|
11
|
+
class << self
|
12
|
+
# Creates a \Python generator object called +rubypython_generator+
|
13
|
+
# that accepts a callback and yields to it.
|
14
|
+
#
|
15
|
+
# *Note*: This method only exists in the RubyPython if the Fiber
|
16
|
+
# exists.
|
17
|
+
def generator_type
|
18
|
+
@generator_type ||= lambda do
|
19
|
+
code = <<-EOM
|
20
|
+
def rubypython_generator(callback):
|
21
|
+
while True:
|
22
|
+
yield callback()
|
23
|
+
EOM
|
24
|
+
|
25
|
+
globals = PyObject.new({ "__builtins__" => PyMain.builtin.pObject, })
|
26
|
+
empty_hash = PyObject.new({})
|
27
|
+
ptr = Python.PyRun_String(code, Python::PY_FILE_INPUT, globals.pointer, empty_hash.pointer)
|
28
|
+
ptr = Python.PyRun_String("rubypython_generator", Python::PY_EVAL_INPUT, globals.pointer, empty_hash.pointer)
|
29
|
+
raise PythonError.handle_error if PythonError.error?
|
30
|
+
RubyPyProxy.new(PyObject.new(ptr))
|
31
|
+
end.call
|
32
|
+
end
|
33
|
+
|
34
|
+
# Creates a Ruby lambda that acts like a \Python generator. Uses
|
35
|
+
# +RubyPython.generator_type+ and Fiber to work the generator as a
|
36
|
+
# coroutine.
|
37
|
+
#
|
38
|
+
# *Note*: This method only exists in the RubyPython if the Fiber
|
39
|
+
# exists.
|
40
|
+
def generator
|
41
|
+
return lambda do |*args|
|
42
|
+
fib = Fiber.new do
|
43
|
+
yield *args
|
44
|
+
Python.PyErr_SetNone(Python.PyExc_StopIteration)
|
45
|
+
FFI::Pointer::NULL
|
46
|
+
end
|
47
|
+
generator_type.__call__(lambda { fib.resume })
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Performs a +Fiber.yield+ with the provided arguments, continuing the
|
52
|
+
# coroutine execution of the generator.
|
53
|
+
#
|
54
|
+
# *Note*: This method only exists in the RubyPython if the Fiber
|
55
|
+
# exists.
|
56
|
+
def yield(*args)
|
57
|
+
Fiber.yield(*args)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -2,35 +2,46 @@ require 'rubypython/blankobject'
|
|
2
2
|
require 'singleton'
|
3
3
|
|
4
4
|
module RubyPython
|
5
|
-
# A singleton object providing access to the
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
5
|
+
# A singleton object providing access to the \Python <tt>__main__</tt> and
|
6
|
+
# <tt>__builtin__</tt> modules. This can be conveniently accessed through
|
7
|
+
# +PyMain+. The <tt>__main__</tt> namespace is searched before the
|
8
|
+
# <tt>__builtin__</tt> namespace. As such, naming clashes will be resolved
|
9
|
+
# in that order.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
11
|
+
# RubyPython::PyMain.dir("dir") # => ['__add__', '__class__', … ]
|
12
|
+
#
|
13
|
+
# === Block Syntax
|
14
|
+
# PyMainClass provides experimental block support for called methods. A
|
13
15
|
# block may be passed to a method call and the object returned by the
|
14
16
|
# function call will be passed as an argument to the block.
|
15
|
-
|
17
|
+
#
|
18
|
+
# RubyPython::PyMain.dir("dir") { |a| a.rubify.map { |e| e.to_sym } }
|
19
|
+
# # => [:__add__, :__class__, :__contains__, … ]
|
20
|
+
class PyMainClass < RubyPython::BlankObject
|
16
21
|
include Singleton
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def main
|
22
|
-
@main||=RubyPython.import "__main__"
|
22
|
+
|
23
|
+
# Returns a proxy object wrapping the \Python <tt>__main__</tt> namespace.
|
24
|
+
def main
|
25
|
+
@main ||= RubyPython.import "__main__"
|
23
26
|
end
|
24
|
-
|
25
|
-
|
26
|
-
#
|
27
|
+
|
28
|
+
# Returns a proxy object wrapping the \Python <tt>__builtin__</tt>
|
29
|
+
# namespace.
|
27
30
|
def builtin
|
28
|
-
@builtin||=RubyPython.import "__builtin__"
|
31
|
+
@builtin ||= RubyPython.import "__builtin__"
|
29
32
|
end
|
30
33
|
|
31
|
-
#Delegates any method calls on this object to the Python
|
32
|
-
|
33
|
-
|
34
|
+
# Delegates any method calls on this object to the \Python
|
35
|
+
# <tt>__main__</tt> or <tt>__builtin__</tt> namespaces, in that order. If
|
36
|
+
# a block is provided, the result of calling the \Python method will be
|
37
|
+
# yielded as an argument to the block.
|
38
|
+
#
|
39
|
+
# [name] The name of the \Python method or function to call.
|
40
|
+
# [args] The arguments to pass to the \Python method.
|
41
|
+
# [block] A block to execute with the result of calling the \Python
|
42
|
+
# method. If a block is provided, the result of the block is returned,
|
43
|
+
# not the result of the \Python method.
|
44
|
+
def method_missing(name, *args, &block)
|
34
45
|
proxy = if main.respond_to?(name)
|
35
46
|
main
|
36
47
|
elsif builtin.respond_to?(name)
|
@@ -41,22 +52,28 @@ module RubyPython
|
|
41
52
|
result = if proxy.is_real_method?(name)
|
42
53
|
proxy.__send__(name, *args)
|
43
54
|
else
|
44
|
-
proxy.__send__(:method_missing, name
|
55
|
+
proxy.__send__(:method_missing, name, *args)
|
45
56
|
end
|
46
|
-
|
57
|
+
|
58
|
+
if block
|
59
|
+
block.call(result)
|
60
|
+
else
|
61
|
+
result
|
62
|
+
end
|
47
63
|
end
|
48
64
|
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
65
|
+
# Called by RubyPython when the interpreter is started or stopped so
|
66
|
+
# that the neccesary preperation or cleanup can be done. For internal
|
67
|
+
# use only.
|
52
68
|
def update(status)
|
53
|
-
|
69
|
+
case status
|
70
|
+
when :stop
|
54
71
|
@main = nil
|
55
72
|
@builtin = nil
|
56
73
|
end
|
57
74
|
end
|
58
|
-
|
59
75
|
end
|
60
76
|
|
61
|
-
|
77
|
+
# The accessible instance of PyMainClass.
|
78
|
+
PyMain = RubyPython::PyMainClass.instance
|
62
79
|
end
|
data/lib/rubypython/pyobject.rb
CHANGED
@@ -3,213 +3,229 @@ require 'rubypython/macros'
|
|
3
3
|
require 'rubypython/conversion'
|
4
4
|
require 'ffi'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
class
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
6
|
+
# This object is an opaque wrapper around the C Py…Object types used by the
|
7
|
+
# \Python C API.
|
8
|
+
#
|
9
|
+
# This class is *only* for RubyPython internal use.
|
10
|
+
class RubyPython::PyObject # :nodoc: all
|
11
|
+
# This class wraps C <tt>Py…Object</tt>s so that the RubyPython::Python
|
12
|
+
# reference count is automatically decreased when the Ruby object
|
13
|
+
# referencing them goes out of scope.
|
14
|
+
class AutoPyPointer < FFI::AutoPointer # :nodoc:
|
15
|
+
class << self
|
16
|
+
# Keeps track of which objects are associated with the currently
|
17
|
+
# running RubyPython::Python interpreter, so that RubyPython knows not
|
18
|
+
# to try to decrease the reference counts of the others when garbage
|
19
|
+
# collecting.
|
20
|
+
attr_accessor :current_pointers
|
21
|
+
|
22
|
+
# When used along with the FFI Library method is executed whenever a
|
23
|
+
# pointer is garbage collected so that cleanup can be done. In our
|
24
|
+
# case we decrease the reference count of the held pointer as long as
|
25
|
+
# the object is still good. There is really no reason the end-user
|
26
|
+
# would need to the use this method directly.
|
27
|
+
def release(pointer)
|
28
|
+
obj_id = pointer.object_id
|
29
|
+
deleted = @current_pointers.delete(obj_id)
|
30
|
+
if deleted and (RubyPython::Python.Py_IsInitialized != 0)
|
31
|
+
RubyPython::Python.Py_DecRef pointer
|
33
32
|
end
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
# Called by RubyPython when the interpreter is started or stopped so
|
36
|
+
# that the necessary preparation or cleanup can be done. For internal
|
37
|
+
# use only.
|
38
|
+
def update(status)
|
39
|
+
case status
|
40
|
+
when :stop
|
41
|
+
current_pointers.clear
|
41
42
|
end
|
42
43
|
end
|
43
|
-
|
44
|
-
self.current_pointers = {}
|
45
44
|
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
#@param [FFI::Pointer, other] pointer objects passed in to the constructor
|
51
|
-
# are just assigned to the pointer attribute of the instance. All other
|
52
|
-
# objects are converted via {Conversion.rtopObject} before being assigned.
|
53
|
-
def initialize(rObject)
|
54
|
-
if rObject.kind_of? FFI::AutoPointer
|
55
|
-
new_pointer = FFI::Pointer.new rObject
|
56
|
-
@pointer = AutoPyPointer.new new_pointer
|
57
|
-
xIncref
|
58
|
-
elsif rObject.kind_of? FFI::Pointer
|
59
|
-
@pointer = AutoPyPointer.new rObject
|
60
|
-
else
|
61
|
-
@pointer = AutoPyPointer.new Conversion.rtopObject(rObject)
|
62
|
-
end
|
63
|
-
AutoPyPointer.current_pointers[@pointer.object_id] = true
|
64
|
-
end
|
46
|
+
self.current_pointers = {}
|
47
|
+
end
|
65
48
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
49
|
+
# The AutoPyPointer object which represents the RubyPython::Python
|
50
|
+
# Py…Object.
|
51
|
+
attr_reader :pointer
|
52
|
+
|
53
|
+
# [rObject] FFI Pointer objects passed into the constructor are wrapped in
|
54
|
+
# an AutoPyPointer and assigned to the +#pointer+ attribute. Other objects
|
55
|
+
# are converted, if possible, from their Ruby types to their \Python types
|
56
|
+
# and wrapped in an AutoPyPointer. The conversion is done with
|
57
|
+
# +RubyPython::Conversion.rtopObject+.
|
58
|
+
def initialize(rObject)
|
59
|
+
if rObject.kind_of? FFI::AutoPointer
|
60
|
+
new_pointer = FFI::Pointer.new rObject
|
61
|
+
@pointer = AutoPyPointer.new new_pointer
|
62
|
+
xIncref
|
63
|
+
elsif rObject.kind_of? FFI::Pointer
|
64
|
+
@pointer = AutoPyPointer.new rObject
|
65
|
+
else
|
66
|
+
@pointer = AutoPyPointer.new RubyPython::Conversion.rtopObject(rObject)
|
67
|
+
end
|
68
|
+
AutoPyPointer.current_pointers[@pointer.object_id] = true
|
69
|
+
end
|
71
70
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
71
|
+
# Attempts to convert the wrapped object to a native ruby type. Returns
|
72
|
+
# either the Ruby object or the unmodified \Python object.
|
73
|
+
def rubify
|
74
|
+
RubyPython::Conversion.ptorObject @pointer
|
75
|
+
end
|
78
76
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
77
|
+
# Tests whether the wrapped \Python object has a given attribute. Returns
|
78
|
+
# +true+ if the attribute exists.
|
79
|
+
# [attrName] The name of the attribute to look up.
|
80
|
+
def hasAttr(attrName)
|
81
|
+
RubyPython::Python.PyObject_HasAttrString(@pointer, attrName) == 1
|
82
|
+
end
|
86
83
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
Python.PyObject_SetAttrString(@pointer, attrName, rbPyAttr.pointer) != -1
|
94
|
-
end
|
84
|
+
# Retrieves an object from the wrapped \Python object.
|
85
|
+
# [attrName] The name of the attribute to fetch.
|
86
|
+
def getAttr(attrName)
|
87
|
+
pyAttr = RubyPython::Python.PyObject_GetAttrString(@pointer, attrName)
|
88
|
+
self.class.new pyAttr
|
89
|
+
end
|
95
90
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
91
|
+
# Sets an attribute of the wrapped \Python object. Returns +true+ if the
|
92
|
+
# attribute was successfully set.
|
93
|
+
# [attrName] The name of the attribute to set.
|
94
|
+
# [rbPyAttr] A PyObject wrapper around the value that we wish to set the
|
95
|
+
# attribute to.
|
96
|
+
def setAttr(attrName, rbPyAttr)
|
97
|
+
RubyPython::Python.PyObject_SetAttrString(@pointer, attrName, rbPyAttr.pointer) != -1
|
98
|
+
end
|
105
99
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
100
|
+
# Calls the wrapped \Python object with the supplied arguments and keyword
|
101
|
+
# arguments. Returns a PyObject wrapper around the returned object, which
|
102
|
+
# may be +NULL+.
|
103
|
+
# [rbPyArgs] A PyObject wrapping a Tuple of the supplied arguments.
|
104
|
+
# [rbPyKeywords] A PyObject wrapping a Dict of keyword arguments.
|
105
|
+
def callObjectKeywords(rbPyArgs, rbPyKeywords)
|
106
|
+
pyReturn = RubyPython::Python.PyObject_Call(@pointer, rbPyArgs.pointer, rbPyKeywords.pointer)
|
107
|
+
self.class.new pyReturn
|
108
|
+
end
|
112
109
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
110
|
+
# Calls the wrapped \Python object with the supplied arguments. Returns a
|
111
|
+
# PyObject wrapper around the returned object, which may be +NULL+.
|
112
|
+
# [rbPyArgs] A PyObject wrapping a Tuple of the supplied arguments.
|
113
|
+
def callObject(rbPyArgs)
|
114
|
+
pyReturn = RubyPython::Python.PyObject_CallObject(@pointer, rbPyArgs.pointer)
|
115
|
+
self.class.new pyReturn
|
116
|
+
end
|
118
117
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
118
|
+
# Decrease the reference count of the wrapped object.
|
119
|
+
def xDecref
|
120
|
+
AutoPyPointer.release(@pointer)
|
121
|
+
@pointer.free
|
122
|
+
nil
|
123
|
+
end
|
123
124
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
125
|
+
# Increase the reference count of the wrapped object
|
126
|
+
def xIncref
|
127
|
+
RubyPython::Python.Py_IncRef @pointer
|
128
|
+
nil
|
129
|
+
end
|
128
130
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
Python.PyFunction_Type,
|
134
|
-
Python.PyMethod_Type,
|
135
|
-
Python.PyCFunction_Type
|
136
|
-
].each do |type|
|
137
|
-
return true if Macros.PyObject_TypeCheck(@pointer, type.to_ptr) != 0
|
138
|
-
end
|
131
|
+
# Tests whether the wrapped object is +NULL+.
|
132
|
+
def null?
|
133
|
+
@pointer.null?
|
134
|
+
end
|
139
135
|
|
140
|
-
|
141
|
-
|
136
|
+
# Performs a compare on two Python objects. Returns a value similar to
|
137
|
+
# that of the spaceship operator (<=>).
|
138
|
+
def cmp(other)
|
139
|
+
RubyPython::Python.PyObject_Compare @pointer, other.pointer
|
140
|
+
end
|
142
141
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
142
|
+
# Tests whether the wrapped object is a function or a method. This is not
|
143
|
+
# the same as #callable? as many other \Python objects are callable.
|
144
|
+
def function_or_method?
|
145
|
+
check = RubyPython::Macros.PyObject_TypeCheck(@pointer, [
|
146
|
+
RubyPython::Python.PyFunction_Type.to_ptr,
|
147
|
+
RubyPython::Python.PyCFunction_Type.to_ptr,
|
148
|
+
RubyPython::Python.PyMethod_Type.to_ptr
|
149
|
+
])
|
150
|
+
check != 0
|
151
|
+
end
|
152
|
+
|
153
|
+
# Is the wrapped object callable?
|
154
|
+
def callable?
|
155
|
+
RubyPython::Python.PyCallable_Check(@pointer) != 0
|
156
|
+
end
|
147
157
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
isTypeObj or isClassObj
|
158
|
+
# Returns the 'directory' of the RubyPython::Python object; similar to #methods in
|
159
|
+
# Ruby.
|
160
|
+
def dir
|
161
|
+
return self.class.new(RubyPython::Python.PyObject_Dir(@pointer)).rubify.map do |x|
|
162
|
+
x.to_sym
|
154
163
|
end
|
164
|
+
end
|
155
165
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
166
|
+
# Tests whether the wrapped object is a RubyPython::Python class (both new
|
167
|
+
# and old style).
|
168
|
+
def class?
|
169
|
+
check = RubyPython::Macros.PyObject_TypeCheck(@pointer, [
|
170
|
+
RubyPython::Python.PyClass_Type.to_ptr,
|
171
|
+
RubyPython::Python.PyType_Type.to_ptr
|
172
|
+
])
|
173
|
+
check != 0
|
174
|
+
end
|
175
|
+
|
176
|
+
# Manipulates the supplied PyObject instance such that it is suitable to
|
177
|
+
# passed to #callObject or #callObjectKeywords. If +rbObject+ is a tuple
|
178
|
+
# then the argument passed in is returned. If it is a list then the list
|
179
|
+
# is converted to a tuple. Otherwise returns a tuple with one element:
|
180
|
+
# +rbObject+.
|
181
|
+
# [rbObject] The argument to be turned into a Tuple.
|
182
|
+
def self.makeTuple(rbObject)
|
183
|
+
pTuple = nil
|
172
184
|
|
173
|
-
|
185
|
+
if RubyPython::Macros.PyObject_TypeCheck(rbObject.pointer, RubyPython::Python.PyList_Type.to_ptr) != 0
|
186
|
+
pTuple = RubyPython::Python.PySequence_Tuple(rbObject.pointer)
|
187
|
+
elsif RubyPython::Macros.PyObject_TypeCheck(rbObject.pointer, RubyPython::Python.PyTuple_Type.to_ptr) != 0
|
188
|
+
pTuple = rbObject.pointer
|
189
|
+
else
|
190
|
+
pTuple = RubyPython::Python.PyTuple_Pack(1, :pointer, rbObject.pointer)
|
174
191
|
end
|
175
192
|
|
176
|
-
|
177
|
-
|
178
|
-
def self.newList(*args)
|
179
|
-
rbList = self.new Python.PyList_New(args.length)
|
193
|
+
self.new pTuple
|
194
|
+
end
|
180
195
|
|
181
|
-
|
182
|
-
|
183
|
-
|
196
|
+
# Wraps up the supplied arguments in a \Python List.
|
197
|
+
def self.newList(*args)
|
198
|
+
rbList = self.new RubyPython::Python.PyList_New(args.length)
|
184
199
|
|
185
|
-
|
200
|
+
args.each_with_index do |el, i|
|
201
|
+
el.xIncref # PyList_SetItem steals references!
|
202
|
+
RubyPython::Python.PyList_SetItem rbList.pointer, i, el.pointer
|
186
203
|
end
|
187
204
|
|
188
|
-
|
189
|
-
|
190
|
-
def self.convert(*args)
|
191
|
-
args.map! do |arg|
|
192
|
-
if arg.kind_of? PyObject
|
193
|
-
arg
|
194
|
-
elsif arg.kind_of? RubyPyProxy
|
195
|
-
arg.pObject
|
196
|
-
else
|
197
|
-
PyObject.new arg
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
205
|
+
rbList
|
206
|
+
end
|
201
207
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
208
|
+
# Converts the supplied arguments to PyObject instances.
|
209
|
+
def self.convert(*args)
|
210
|
+
args.map do |arg|
|
211
|
+
if arg.kind_of? RubyPython::PyObject
|
212
|
+
arg
|
213
|
+
elsif arg.kind_of? RubyPython::RubyPyProxy
|
214
|
+
arg.pObject
|
215
|
+
else
|
216
|
+
RubyPython::PyObject.new arg
|
217
|
+
end
|
211
218
|
end
|
212
|
-
|
213
219
|
end
|
214
220
|
|
221
|
+
# Takes an array of wrapped \Python objects and wraps them in a Tuple such
|
222
|
+
# that they may be passed to #callObject.
|
223
|
+
# [args] An array of PyObjects; the arguments to be inserted into the
|
224
|
+
# Tuple.
|
225
|
+
def self.buildArgTuple(*args)
|
226
|
+
pList = newList(*args)
|
227
|
+
pTuple = makeTuple(pList)
|
228
|
+
pList.xDecref
|
229
|
+
pTuple
|
230
|
+
end
|
215
231
|
end
|