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