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.
Files changed (51) hide show
  1. data/.autotest +3 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +13 -0
  4. data/.hgignore +14 -0
  5. data/.hgtags +7 -0
  6. data/.rspec +1 -1
  7. data/Contributors.rdoc +9 -0
  8. data/History.rdoc +148 -0
  9. data/{License.txt → License.rdoc} +7 -1
  10. data/Manifest.txt +15 -10
  11. data/PostInstall.txt +11 -4
  12. data/README.rdoc +272 -0
  13. data/Rakefile +107 -22
  14. data/autotest/discover.rb +1 -0
  15. data/lib/rubypython.rb +214 -120
  16. data/lib/rubypython/blankobject.rb +16 -14
  17. data/lib/rubypython/conversion.rb +242 -173
  18. data/lib/rubypython/legacy.rb +30 -31
  19. data/lib/rubypython/macros.rb +43 -34
  20. data/lib/rubypython/operators.rb +103 -101
  21. data/lib/rubypython/options.rb +41 -44
  22. data/lib/rubypython/pygenerator.rb +61 -0
  23. data/lib/rubypython/pymainclass.rb +46 -29
  24. data/lib/rubypython/pyobject.rb +193 -177
  25. data/lib/rubypython/python.rb +189 -176
  26. data/lib/rubypython/pythonerror.rb +54 -63
  27. data/lib/rubypython/pythonexec.rb +123 -0
  28. data/lib/rubypython/rubypyproxy.rb +213 -137
  29. data/lib/rubypython/type.rb +20 -0
  30. data/spec/basic_spec.rb +50 -0
  31. data/spec/callback_spec.rb +7 -17
  32. data/spec/conversion_spec.rb +7 -21
  33. data/spec/legacy_spec.rb +1 -16
  34. data/spec/pymainclass_spec.rb +6 -15
  35. data/spec/pyobject_spec.rb +39 -64
  36. data/spec/python_helpers/basics.py +20 -0
  37. data/spec/python_helpers/objects.py +24 -20
  38. data/spec/pythonerror_spec.rb +5 -17
  39. data/spec/refcnt_spec.rb +4 -10
  40. data/spec/rubypyclass_spec.rb +1 -11
  41. data/spec/rubypyproxy_spec.rb +45 -54
  42. data/spec/rubypython_spec.rb +45 -57
  43. data/spec/spec_helper.rb +49 -33
  44. metadata +87 -63
  45. data.tar.gz.sig +0 -0
  46. data/History.markdown +0 -97
  47. data/README.markdown +0 -105
  48. data/lib/rubypython/core_ext/string.rb +0 -7
  49. data/lib/rubypython/version.rb +0 -9
  50. data/spec/python_helpers/objects.pyc +0 -0
  51. 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 python \_\_main\_\_ and
6
- # \_\_builtin\_\_ modules. This can be conveniently accessed through the
7
- # already instaniated PyMain constant. The \_\_main\_\_ namespace is
8
- # searched before the \_\_builtin\_\_ namespace. As such, naming clashes will
9
- # be resolved in that order.
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
- # ## Block Syntax
12
- # The PyMainClass object provides somewhat experimental block support. A
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
- class PyMainClass < BlankObject
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
- attr_writer :main, :builtin
18
-
19
- #@return [RubyPyModule] a proxy object wrapping the Python \__main\__
20
- # namespace.
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
- #@return [RubyPyModule] a proxy object wrapping the Python \__builtin\__
26
- # namespace.
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 \__main\__ or
32
- #\__builtin\__ namespaces. Method call resolution occurs in that order.
33
- def method_missing(name,*args,&block)
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,*args)
55
+ proxy.__send__(:method_missing, name, *args)
45
56
  end
46
- block ? block.call(result) : result
57
+
58
+ if block
59
+ block.call(result)
60
+ else
61
+ result
62
+ end
47
63
  end
48
64
 
49
- #For internal use only. Called by {RubyPython} when the
50
- #interpreter is started or stopped so that the neccesary
51
- #preperation or cleanup can be done.
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
- if status.equal? :stop
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
- PyMain = PyMainClass.instance
77
+ # The accessible instance of PyMainClass.
78
+ PyMain = RubyPython::PyMainClass.instance
62
79
  end
@@ -3,213 +3,229 @@ require 'rubypython/macros'
3
3
  require 'rubypython/conversion'
4
4
  require 'ffi'
5
5
 
6
- module RubyPython
7
- #This object is an opaque wrapper around the C PyObject\* type used by the
8
- #python C API. This class **should not** be used by the end user. They
9
- #should instead make use of the {RubyPyProxy} class and its
10
- #subclasses.
11
- class PyObject
12
-
13
- #This class wraps C PyObject\*s so that the Python reference count is
14
- #automatically decreased when the Ruby object referencing them
15
- #goes out of scope.
16
- class AutoPyPointer < FFI::AutoPointer
17
- class << self
18
- #Keeps track of which objects are associated with the currently running
19
- #Python interpreter, so that RubyPython knows not to try to decrease the
20
- #reference counts of the others when garbage collecting.
21
- attr_accessor :current_pointers
22
-
23
- #When used along with the FFI Library method is executed whenever a
24
- #pointer is garbage collected so that cleanup can be done. In our case
25
- #we decrease the reference count of the held pointer as long as the
26
- #object is still good. There is really no reason the end-user would need
27
- #to the use this method directly.
28
- def release(pointer)
29
- obj_id = pointer.object_id
30
- if (Python.Py_IsInitialized != 0) and @current_pointers.delete(obj_id)
31
- Python.Py_DecRef pointer
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
- #For internal use only. Called by {RubyPython} when the
37
- #interpreter is started or stopped so that the neccesary
38
- #preperation or cleanup can be done.
39
- def update(status)
40
- current_pointers.clear if status.equal? :stop
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
- #The FFI::Pointer object which represents the Python PyObject\*.
48
- attr_reader :pointer
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
- #Attempts to convert the wrapped object to a native ruby type.
67
- #@return a ruby version of the wrapped object
68
- def rubify
69
- Conversion.ptorObject @pointer
70
- end
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
- #Tests whether the wrapped object has a given attribute
73
- #@param [String] the name of the attribute to look up
74
- #@return [Boolean]
75
- def hasAttr(attrName)
76
- Python.PyObject_HasAttrString(@pointer, attrName) == 1
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
- #Retrieves an object from the wrapped python object
80
- #@param [String] the name of attribute to fetch
81
- #@return [PyObject] a Ruby wrapper around the fetched attribute
82
- def getAttr(attrName)
83
- pyAttr = Python.PyObject_GetAttrString @pointer, attrName
84
- self.class.new pyAttr
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
- #Sets the an attribute of the wrapped Python object
88
- #@param [String] attrName the name of of attribute to set
89
- #@param [PyObject] rbPyAttr a {PyObject} wrapper around the value we wish to
90
- #set the attribute to.
91
- #@return [Boolean] returns true if the attribute is sucessfully set.
92
- def setAttr(attrName, rbPyAttr)
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
- #Calls the wrapped Python object with the supplied arguments.
97
- #@param [PyObject] rbPyArgs a {PyObject} wrapping a tuple of the supplied
98
- #arguments
99
- #@return [PyObject] a {PyObject} wrapper around the returned
100
- #object (this may be NULL).
101
- def callObject(rbPyArgs)
102
- pyReturn = Python.PyObject_CallObject(@pointer, rbPyArgs.pointer)
103
- self.class.new pyReturn
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
- #Decrease the reference count of the wrapped object
107
- #@return [void]
108
- def xDecref
109
- AutoPyPointer.release(@pointer)
110
- @pointer.free
111
- end
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
- #Increase the reference count of the wrapped object
114
- #@return [void]
115
- def xIncref
116
- Python.Py_IncRef @pointer
117
- end
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
- #Tests whether the wrapped object is NULL.
120
- def null?
121
- @pointer.null?
122
- end
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
- #@return [Number]
125
- def cmp(other)
126
- Python.PyObject_Compare @pointer, other.pointer
127
- end
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
- #Tests whether the wrapped object is a function or a method. This is not the
130
- #same as {#callable?} as many other Python objects are callable.
131
- def function_or_method?
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
- false
141
- end
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
- #Is the wrapped object callable?
144
- def callable?
145
- Python.PyCallable_Check(@pointer) != 0
146
- end
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
- #Tests whether the wrapped object is a Python class (both new and old
149
- #style).
150
- def class?
151
- isClassObj = (Macros.PyObject_TypeCheck(@pointer, Python.PyClass_Type.to_ptr) == 1)
152
- isTypeObj = (Macros.PyObject_TypeCheck(@pointer, Python.PyType_Type.to_ptr) == 1)
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
- #Manipulates the supplied {PyObject} instance such that it is suitable to
157
- #passed to {#callObject}. If `rbObject` is a tuple then the argument passed
158
- #in is returned. If it is a list then the list is converted to a tuple.
159
- #Otherwise returns a tuple with one element: `rbObject`.
160
- #@param [PyObject] rbObject the argment to be turned into a tuple.
161
- #@return [PyObject<tuple>]
162
- def self.makeTuple(rbObject)
163
- pTuple = nil
164
-
165
- if Macros.PyObject_TypeCheck(rbObject.pointer, Python.PyList_Type.to_ptr) != 0
166
- pTuple = Python.PySequence_Tuple(rbObject.pointer)
167
- elsif Macros.PyObject_TypeCheck(rbObject.pointer, Python.PyTuple_Type.to_ptr) != 0
168
- pTuple = rbObject.pointer
169
- else
170
- pTuple = Python.PyTuple_Pack(1, :pointer, rbObject.pointer)
171
- end
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
- self.new pTuple
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
- #Wraps up the supplied arguments in Python list.
177
- #@return [PyObject<list>]
178
- def self.newList(*args)
179
- rbList = self.new Python.PyList_New(args.length)
193
+ self.new pTuple
194
+ end
180
195
 
181
- args.each_with_index do |el, i|
182
- Python.PyList_SetItem rbList.pointer, i, el.pointer
183
- end
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
- rbList
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
- #Converts the supplied arguments to PyObject instances.
189
- #@return [Array<PyObject>]
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
- #Takes an array of wrapped Python objects and wraps them in a tuple such
203
- #that they may be passed to {#callObject}.
204
- #@param [Array<PyObject>] args the arguments to be inserted into the tuple.
205
- #@return [PyObject<tuple>]
206
- def self.buildArgTuple(*args)
207
- pList = PyObject.newList(*args)
208
- pTuple = PyObject.makeTuple(pList)
209
- pList.xDecref
210
- pTuple
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