rubypython 0.3.2 → 0.5.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/.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
|