lib/rubypython/rubypyproxy.rb in rubypython-0.6.2 vs lib/rubypython/rubypyproxy.rb in rubypython-0.6.3
- old
+ new
@@ -86,20 +86,14 @@
@pObject = PyObject.new pObject
end
end
# Handles the job of wrapping up anything returned by a RubyPyProxy
- # instance. The behavior differs depending on the value of
- # +RubyPython.legacy_mode+. If legacy mode is inactive, every returned
- # object is wrapped by an instance of +RubyPyProxy+. If legacy mode is
- # active, RubyPython first attempts to convert the returned object to a
- # native Ruby type, and then only wraps the object if this fails.
+ # instance. Every returned # object is wrapped by an instance of +RubyPyProxy+
def _wrap(pyobject)
if pyobject.class?
RubyPyClass.new(pyobject)
- elsif RubyPython.__send__ :legacy_mode?
- pyobject.rubify
else
RubyPyProxy.new(pyobject)
end
rescue Conversion::UnsupportedConversion => exc
RubyPyProxy.new pyobject
@@ -134,11 +128,10 @@
# and we can always set an attribute on a \Python object.
# 3. If the method ends with an exclamation point (e.g., +foo!+) we are
# attempting to call a method with keyword arguments.
# 4. The Python method or value will be called, if it's callable.
# 5. RubyPython will wrap the return value in a RubyPyProxy object
- # (unless legacy_mode has been turned on).
# 6. If a block has been provided, the wrapped return value will be
# passed into the block.
def method_missing(name, *args, &block)
name = name.to_s
@@ -154,11 +147,11 @@
kwargs = false
if name =~ /=$/
return @pObject.setAttr(name.chomp('='),
- PyObject.convert(*args).first)
+ PyObject.new(args.pop))
elsif name =~ /!$/
kwargs = true
name.chomp! "!"
end
@@ -169,35 +162,14 @@
if pFunc.callable?
if args.empty? and pFunc.class?
pReturn = pFunc
else
if kwargs and args.last.is_a?(Hash)
- pKeywords = PyObject.convert(args.pop).first
+ pKeywords = PyObject.new args.pop
end
-
- orig_args = args
- args = PyObject.convert(*args)
- pTuple = PyObject.buildArgTuple(*args)
- pReturn = if pKeywords
- pFunc.callObjectKeywords(pTuple, pKeywords)
- else
- pFunc.callObject(pTuple)
- end
-
- # Clean up unused Python vars instead of waiting on Ruby's GC to
- # do it.
+ pReturn = _method_call(pFunc, args, pKeywords)
pFunc.xDecref
- pTuple.xDecref
- pKeywords.xDecref if pKeywords
- orig_args.each_with_index do |arg, i|
- # Only decref objects that were created in PyObject.convert.
- if !arg.kind_of?(RubyPython::PyObject) and !arg.kind_of?(RubyPython::RubyPyProxy)
- args[i].xDecref
- end
- end
-
- raise PythonError.handle_error if PythonError.error?
end
else
pReturn = pFunc
end
@@ -208,14 +180,37 @@
else
result
end
end
+ #Handles the of calling a wrapped callable Python object at a higher level
+ #than +PyObject#callObject+. For internal use only.
+ def _method_call(pFunc, args, pKeywords)
+ pTuple = PyObject.buildArgTuple(*args)
+ pReturn = if pKeywords
+ pFunc.callObjectKeywords(pTuple, pKeywords)
+ else
+ pFunc.callObject(pTuple)
+ end
+
+ # Clean up unused Python vars instead of waiting on Ruby's GC to
+ # do it.
+ pTuple.xDecref
+ pKeywords.xDecref if pKeywords
+ raise PythonError.handle_error if PythonError.error?
+ pReturn
+ end
+ private :_method_call
+
# RubyPython will attempt to translate the wrapped object into a native
# Ruby object. This will only succeed for simple built-in type.
def rubify
- @pObject.rubify
+ converted = @pObject.rubify
+ if converted.kind_of? ::FFI::Pointer
+ converted = self.class.new converted
+ end
+ converted
end
# Returns the String representation of the wrapped object via a call to
# the object's <tt>__repr__</tt> method, or the +repr+ method in PyMain.
def inspect
@@ -303,13 +298,10 @@
# A class to wrap \Python classes.
class RubyPyClass < RubyPyProxy
# Create an instance of the wrapped class. This is a workaround for the
# fact that \Python classes are meant to be callable.
def new(*args)
- args = PyObject.convert(*args)
- pTuple = PyObject.buildArgTuple(*args)
- pReturn = @pObject.callObject(pTuple)
- raise PythonError.handle_error if PythonError.error?
+ pReturn = _method_call(@pObject, args, nil)
RubyPyInstance.new pReturn
end
end
# An object representing an instance of a \Python class. It behaves