rubypython 0.3.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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