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,123 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # A class that represents a \Python executable.
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # End users may get the instance that represents the current running \Python
         
     | 
| 
      
 4 
     | 
    
         
            +
            # interpreter (from +RubyPython.python+), but should not directly
         
     | 
| 
      
 5 
     | 
    
         
            +
            # instantiate this class.
         
     | 
| 
      
 6 
     | 
    
         
            +
            class RubyPython::PythonExec
         
     | 
| 
      
 7 
     | 
    
         
            +
              # Based on the name of or path to the \Python executable provided, will
         
     | 
| 
      
 8 
     | 
    
         
            +
              # determine:
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              # * The full path to the \Python executable.
         
     | 
| 
      
 11 
     | 
    
         
            +
              # * The version of \Python being run.
         
     | 
| 
      
 12 
     | 
    
         
            +
              # * The system prefix.
         
     | 
| 
      
 13 
     | 
    
         
            +
              # * The main loadable \Python library for this version.
         
     | 
| 
      
 14 
     | 
    
         
            +
              def initialize(python_executable)
         
     | 
| 
      
 15 
     | 
    
         
            +
                @python = python_executable || "python"
         
     | 
| 
      
 16 
     | 
    
         
            +
                @python = %x(#{@python} -c "import sys; print sys.executable").chomp
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                @version = run_command 'import sys; print "%d.%d" % sys.version_info[:2]'
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                @realname = @python.dup
         
     | 
| 
      
 21 
     | 
    
         
            +
                if @realname !~ /#{@version}$/
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @realname = "#{@python}#{@version}"
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
                @basename = File.basename(@realname)
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                @sys_prefix = run_command 'import sys; print sys.prefix'
         
     | 
| 
      
 27 
     | 
    
         
            +
                @library = find_python_lib
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def find_python_lib
         
     | 
| 
      
 31 
     | 
    
         
            +
                # By default, the library name will be something like
         
     | 
| 
      
 32 
     | 
    
         
            +
                # libpython2.6.so, but that won't always work.
         
     | 
| 
      
 33 
     | 
    
         
            +
                libbase = "#{FFI::Platform::LIBPREFIX}#{@basename}"
         
     | 
| 
      
 34 
     | 
    
         
            +
                libext = FFI::Platform::LIBSUFFIX
         
     | 
| 
      
 35 
     | 
    
         
            +
                libname = "#{libbase}.#{libext}"
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                # We may need to look in multiple locations for Python, so let's
         
     | 
| 
      
 38 
     | 
    
         
            +
                # build this as an array.
         
     | 
| 
      
 39 
     | 
    
         
            +
                locations = [ File.join(@sys_prefix, "lib", libname) ]
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                if FFI::Platform.mac?
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # On the Mac, let's add a special case that has even a different
         
     | 
| 
      
 43 
     | 
    
         
            +
                  # libname. This may not be fully useful on future versions of OS
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # X, but it should work on 10.5 and 10.6. Even if it doesn't, the
         
     | 
| 
      
 45 
     | 
    
         
            +
                  # next step will (/usr/lib/libpython<version>.dylib is a symlink
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # to the correct location).
         
     | 
| 
      
 47 
     | 
    
         
            +
                  locations << File.join(@sys_prefix, "Python")
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # Let's also look in the location that was originally set in this
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # library:
         
     | 
| 
      
 50 
     | 
    
         
            +
                  File.join(@sys_prefix, "lib", "#{@realname}", "config", libname)
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                if FFI::Platform.unix?
         
     | 
| 
      
 54 
     | 
    
         
            +
                  # On Unixes, let's look in some standard alternative places, too.
         
     | 
| 
      
 55 
     | 
    
         
            +
                  # Just in case. Some Unixes don't include a .so symlink when they
         
     | 
| 
      
 56 
     | 
    
         
            +
                  # should, so let's look for the base case of .so.1, too.
         
     | 
| 
      
 57 
     | 
    
         
            +
                  [ libname, "#{libname}.1" ].each do |name|
         
     | 
| 
      
 58 
     | 
    
         
            +
                    locations << File.join("/opt/local/lib", name)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    locations << File.join("/opt/lib", name)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    locations << File.join("/usr/local/lib", name)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    locations << File.join("/usr/lib", name)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                # Let's add alternative extensions; again, just in case.
         
     | 
| 
      
 66 
     | 
    
         
            +
                locations.dup.each do |location|
         
     | 
| 
      
 67 
     | 
    
         
            +
                  path = File.dirname(location)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  base = File.basename(location, ".#{libext}")
         
     | 
| 
      
 69 
     | 
    
         
            +
                  locations << File.join(path, "#{base}.so")    # Standard Unix
         
     | 
| 
      
 70 
     | 
    
         
            +
                  locations << File.join(path, "#{base}.dylib") # Mac OS X
         
     | 
| 
      
 71 
     | 
    
         
            +
                  locations << File.join(path, "#{base}.dll")   # Windows
         
     | 
| 
      
 72 
     | 
    
         
            +
                  locations << File.join(path, "#{base}.a")     # Non-DLL
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                # Remove redundant locations
         
     | 
| 
      
 76 
     | 
    
         
            +
                locations.uniq!
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                library = nil
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                locations.each do |location|
         
     | 
| 
      
 81 
     | 
    
         
            +
                  if File.exists? location
         
     | 
| 
      
 82 
     | 
    
         
            +
                    library = location
         
     | 
| 
      
 83 
     | 
    
         
            +
                    break
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                library
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
              private :find_python_lib
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
              # The python executable to use.
         
     | 
| 
      
 92 
     | 
    
         
            +
              attr_reader :python
         
     | 
| 
      
 93 
     | 
    
         
            +
              # The real name of the python executable (with version).
         
     | 
| 
      
 94 
     | 
    
         
            +
              attr_reader :realname
         
     | 
| 
      
 95 
     | 
    
         
            +
              # The sys.prefix for Python.
         
     | 
| 
      
 96 
     | 
    
         
            +
              attr_reader :sys_prefix
         
     | 
| 
      
 97 
     | 
    
         
            +
              # The Python library.
         
     | 
| 
      
 98 
     | 
    
         
            +
              attr_reader :library
         
     | 
| 
      
 99 
     | 
    
         
            +
              #  The version
         
     | 
| 
      
 100 
     | 
    
         
            +
              attr_reader :version
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
              # Run a Python command-line command.
         
     | 
| 
      
 103 
     | 
    
         
            +
              def run_command(command)
         
     | 
| 
      
 104 
     | 
    
         
            +
                %x(#{@python} -c '#{command}').chomp if @python
         
     | 
| 
      
 105 
     | 
    
         
            +
              end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
              def to_s
         
     | 
| 
      
 108 
     | 
    
         
            +
                @realname
         
     | 
| 
      
 109 
     | 
    
         
            +
              end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
              def inspect
         
     | 
| 
      
 112 
     | 
    
         
            +
                if @python
         
     | 
| 
      
 113 
     | 
    
         
            +
                  "#<#{realname} #{sys_prefix}>"
         
     | 
| 
      
 114 
     | 
    
         
            +
                else
         
     | 
| 
      
 115 
     | 
    
         
            +
                  "#<invalid interpreter>"
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
              end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
              def invalidate!
         
     | 
| 
      
 120 
     | 
    
         
            +
                @python = @version = @realname = @sys_prefix = @library = nil
         
     | 
| 
      
 121 
     | 
    
         
            +
              end
         
     | 
| 
      
 122 
     | 
    
         
            +
              private :invalidate!
         
     | 
| 
      
 123 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -5,69 +5,80 @@ require 'rubypython/operators' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            require 'rubypython/blankobject'
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            module RubyPython
         
     | 
| 
       8 
     | 
    
         
            -
              # 
     | 
| 
       9 
     | 
    
         
            -
              # 
     | 
| 
       10 
     | 
    
         
            -
              #method calls to  
     | 
| 
       11 
     | 
    
         
            -
              # 
     | 
| 
       12 
     | 
    
         
            -
              #will decrement its objects reference count when it is garbage collected.
         
     | 
| 
      
 8 
     | 
    
         
            +
              # In most cases, users will interact with RubyPyProxy objects that hold
         
     | 
| 
      
 9 
     | 
    
         
            +
              # references to active objects in the \Python interpreter. RubyPyProxy
         
     | 
| 
      
 10 
     | 
    
         
            +
              # delegates method calls to \Python objects, wrapping and returning the
         
     | 
| 
      
 11 
     | 
    
         
            +
              # results as RubyPyProxy objects.
         
     | 
| 
       13 
12 
     | 
    
         
             
              #
         
     | 
| 
       14 
     | 
    
         
            -
              # 
     | 
| 
       15 
     | 
    
         
            -
              #is  
     | 
| 
      
 13 
     | 
    
         
            +
              # The allocation, deallocation, and reference counting on RubyPyProxy
         
     | 
| 
      
 14 
     | 
    
         
            +
              # objects is automatic: RubyPython takes care of it all. When the object
         
     | 
| 
      
 15 
     | 
    
         
            +
              # is garbage collected, the instance will automatically decrement its
         
     | 
| 
      
 16 
     | 
    
         
            +
              # object reference count.
         
     | 
| 
       16 
17 
     | 
    
         
             
              #
         
     | 
| 
       17 
     | 
    
         
            -
              # 
     | 
| 
       18 
     | 
    
         
            -
               
     | 
| 
       19 
     | 
    
         
            -
              #Any method which is forwarded to a Python object may be called with 
         
     | 
| 
       20 
     | 
    
         
            -
              #a block. The result of the method will passed as the argument to 
         
     | 
| 
       21 
     | 
    
         
            -
              #that block.
         
     | 
| 
      
 18 
     | 
    
         
            +
              # [NOTE:]  All RubyPyProxy objects become invalid when the \Python
         
     | 
| 
      
 19 
     | 
    
         
            +
              #          interpreter is halted.
         
     | 
| 
       22 
20 
     | 
    
         
             
              #
         
     | 
| 
       23 
     | 
    
         
            -
               
     | 
| 
       24 
     | 
    
         
            -
              # 
     | 
| 
       25 
     | 
    
         
            -
              # 
     | 
| 
       26 
     | 
    
         
            -
              # 
     | 
| 
       27 
     | 
    
         
            -
              #  irb(main):003:1*     2*f.rubify
         
     | 
| 
       28 
     | 
    
         
            -
              #  irb(main):004:1> end
         
     | 
| 
       29 
     | 
    
         
            -
              #  => 20.0
         
     | 
| 
       30 
     | 
    
         
            -
              #  irb(main):005:0> RubyPython.stop
         
     | 
| 
       31 
     | 
    
         
            -
              #  => true
         
     | 
| 
      
 21 
     | 
    
         
            +
              # == Calling Methods With Blocks
         
     | 
| 
      
 22 
     | 
    
         
            +
              # Any method which is forwarded to a \Python object may be called with a
         
     | 
| 
      
 23 
     | 
    
         
            +
              # block. The result of the method will passed as the argument to that
         
     | 
| 
      
 24 
     | 
    
         
            +
              # block.
         
     | 
| 
       32 
25 
     | 
    
         
             
              #
         
     | 
| 
      
 26 
     | 
    
         
            +
              #   RubyPython.run do
         
     | 
| 
      
 27 
     | 
    
         
            +
              #     sys = RubyPython.import 'sys'
         
     | 
| 
      
 28 
     | 
    
         
            +
              #     sys.version { |v| v.rubify.split(' ') }
         
     | 
| 
      
 29 
     | 
    
         
            +
              #   end
         
     | 
| 
      
 30 
     | 
    
         
            +
              #   # => [ "2.6.1", … ]
         
     | 
| 
      
 31 
     | 
    
         
            +
              #   
         
     | 
| 
      
 32 
     | 
    
         
            +
              # == Passing Procs and Methods to \Python Methods
         
     | 
| 
      
 33 
     | 
    
         
            +
              # RubyPython supports passing Proc and Method objects to \Python methods.
         
     | 
| 
      
 34 
     | 
    
         
            +
              # The Proc or Method object must be passed explicitly. As seen above,
         
     | 
| 
      
 35 
     | 
    
         
            +
              # supplying a block to a method will result in the return value of the
         
     | 
| 
      
 36 
     | 
    
         
            +
              # method call being passed to the block.
         
     | 
| 
       33 
37 
     | 
    
         
             
              #
         
     | 
| 
       34 
     | 
    
         
            -
              # 
     | 
| 
       35 
     | 
    
         
            -
               
     | 
| 
       36 
     | 
    
         
            -
              # 
     | 
| 
       37 
     | 
    
         
            -
              # 
     | 
| 
       38 
     | 
    
         
            -
              #seen above, supplying a block to a method will result in the return 
         
     | 
| 
       39 
     | 
    
         
            -
              #value of the method call being passed to the block.
         
     | 
| 
      
 38 
     | 
    
         
            +
              # When a Proc or Method is supplied as a callback, then arguments that it
         
     | 
| 
      
 39 
     | 
    
         
            +
              # will be called with will be wrapped \Python objects. It will therefore
         
     | 
| 
      
 40 
     | 
    
         
            +
              # typically be necessary to write a wrapper around any Ruby callback that
         
     | 
| 
      
 41 
     | 
    
         
            +
              # requires native Ruby objects.
         
     | 
| 
       40 
42 
     | 
    
         
             
              #
         
     | 
| 
       41 
     | 
    
         
            -
              # 
     | 
| 
       42 
     | 
    
         
            -
              # 
     | 
| 
       43 
     | 
    
         
            -
              #
         
     | 
| 
       44 
     | 
    
         
            -
              #@example Passing a Proc to Python
         
     | 
| 
       45 
     | 
    
         
            -
              #  #Python Code
         
     | 
| 
       46 
     | 
    
         
            -
              #  def apply_callback(callback, argument):
         
     | 
| 
       47 
     | 
    
         
            -
              #    return callback(argument)
         
     | 
| 
       48 
     | 
    
         
            -
              #
         
     | 
| 
       49 
     | 
    
         
            -
              #  #IRB Session
         
     | 
| 
       50 
     | 
    
         
            -
              #  irb(main):001:0> RubyPython.start
         
     | 
| 
       51 
     | 
    
         
            -
              #  => true
         
     | 
| 
       52 
     | 
    
         
            -
              #  irb(main):002:0> sys = RubyPython.import 'sys'
         
     | 
| 
       53 
     | 
    
         
            -
              #  => <module 'sys' (built-in)>
         
     | 
| 
       54 
     | 
    
         
            -
              #  irb(main):003:0> sys.path.append('.')
         
     | 
| 
       55 
     | 
    
         
            -
              #  => None
         
     | 
| 
       56 
     | 
    
         
            -
              #  irb(main):004:0> sample = RubyPython.import 'sample'
         
     | 
| 
       57 
     | 
    
         
            -
              #  => <module 'sample' from './sample.pyc'>
         
     | 
| 
       58 
     | 
    
         
            -
              #  irb(main):005:0> callback = Proc.new do |arg|
         
     | 
| 
       59 
     | 
    
         
            -
              #  irb(main):006:1*   arg * 2
         
     | 
| 
       60 
     | 
    
         
            -
              #  irb(main):007:1> end
         
     | 
| 
       61 
     | 
    
         
            -
              #  => #<Proc:0x000001018df490@(irb):5>
         
     | 
| 
       62 
     | 
    
         
            -
              #  irb(main):008:0> sample.apply_callback(callback, 21).rubify
         
     | 
| 
       63 
     | 
    
         
            -
              #  => 42
         
     | 
| 
       64 
     | 
    
         
            -
              #  irb(main):009:0> RubyPython.stop
         
     | 
| 
      
 43 
     | 
    
         
            +
              #   # Python Code: sample.py
         
     | 
| 
      
 44 
     | 
    
         
            +
              #   def apply_callback(callback, argument):
         
     | 
| 
      
 45 
     | 
    
         
            +
              #     return callback(argument)
         
     | 
| 
       65 
46 
     | 
    
         
             
              #
         
     | 
| 
      
 47 
     | 
    
         
            +
              #   # IRB Session
         
     | 
| 
      
 48 
     | 
    
         
            +
              #   >> RubyPython.start
         
     | 
| 
      
 49 
     | 
    
         
            +
              #   => true
         
     | 
| 
      
 50 
     | 
    
         
            +
              #   >> sys = RubyPython.import 'sys'
         
     | 
| 
      
 51 
     | 
    
         
            +
              #   => <module 'sys' (built-in)>
         
     | 
| 
      
 52 
     | 
    
         
            +
              #   >> sys.path.append('.')
         
     | 
| 
      
 53 
     | 
    
         
            +
              #   => None
         
     | 
| 
      
 54 
     | 
    
         
            +
              #   >> sample = RubyPython.import 'sample'
         
     | 
| 
      
 55 
     | 
    
         
            +
              #   => <module 'sample' from './sample.pyc'>
         
     | 
| 
      
 56 
     | 
    
         
            +
              #   >> callback = Proc.new { |arg| arg * 2 }
         
     | 
| 
      
 57 
     | 
    
         
            +
              #   => # <Proc:0x000001018df490@(irb):5>
         
     | 
| 
      
 58 
     | 
    
         
            +
              #   >> sample.apply_callback(callback, 21).rubify
         
     | 
| 
      
 59 
     | 
    
         
            +
              #   => 42
         
     | 
| 
      
 60 
     | 
    
         
            +
              #   >> RubyPython.stop
         
     | 
| 
      
 61 
     | 
    
         
            +
              #   => true
         
     | 
| 
       66 
62 
     | 
    
         
             
              class RubyPyProxy < BlankObject
         
     | 
| 
       67 
63 
     | 
    
         
             
                include Operators
         
     | 
| 
       68 
64 
     | 
    
         | 
| 
       69 
65 
     | 
    
         
             
                attr_reader :pObject
         
     | 
| 
       70 
66 
     | 
    
         | 
| 
      
 67 
     | 
    
         
            +
                # Creates a \Python proxy for the provided Ruby object.
         
     | 
| 
      
 68 
     | 
    
         
            +
                #
         
     | 
| 
      
 69 
     | 
    
         
            +
                # Only the following Ruby types can be represented in \Python:
         
     | 
| 
      
 70 
     | 
    
         
            +
                # * String
         
     | 
| 
      
 71 
     | 
    
         
            +
                # * Array
         
     | 
| 
      
 72 
     | 
    
         
            +
                # * Hash
         
     | 
| 
      
 73 
     | 
    
         
            +
                # * Fixnum
         
     | 
| 
      
 74 
     | 
    
         
            +
                # * Bignum
         
     | 
| 
      
 75 
     | 
    
         
            +
                # * Float
         
     | 
| 
      
 76 
     | 
    
         
            +
                # * Symbol (as a String)
         
     | 
| 
      
 77 
     | 
    
         
            +
                # * Proc
         
     | 
| 
      
 78 
     | 
    
         
            +
                # * Method
         
     | 
| 
      
 79 
     | 
    
         
            +
                # * +true+ (as True)
         
     | 
| 
      
 80 
     | 
    
         
            +
                # * +false+ (as False)
         
     | 
| 
      
 81 
     | 
    
         
            +
                # * +nil+ (as None)
         
     | 
| 
       71 
82 
     | 
    
         
             
                def initialize(pObject)
         
     | 
| 
       72 
83 
     | 
    
         
             
                  if pObject.kind_of? PyObject
         
     | 
| 
       73 
84 
     | 
    
         
             
                    @pObject = pObject
         
     | 
| 
         @@ -76,12 +87,12 @@ module RubyPython 
     | 
|
| 
       76 
87 
     | 
    
         
             
                  end
         
     | 
| 
       77 
88 
     | 
    
         
             
                end
         
     | 
| 
       78 
89 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
                #Handles the job of wrapping up anything returned by a  
     | 
| 
       80 
     | 
    
         
            -
                #instance. The behavior differs depending on the value of
         
     | 
| 
       81 
     | 
    
         
            -
                # 
     | 
| 
       82 
     | 
    
         
            -
                #object is wrapped by an instance of  
     | 
| 
       83 
     | 
    
         
            -
                #active, RubyPython first attempts to convert the returned object to a
         
     | 
| 
       84 
     | 
    
         
            -
                #native Ruby type, and then only wraps the object if this fails.
         
     | 
| 
      
 90 
     | 
    
         
            +
                # Handles the job of wrapping up anything returned by a RubyPyProxy
         
     | 
| 
      
 91 
     | 
    
         
            +
                # instance. The behavior differs depending on the value of
         
     | 
| 
      
 92 
     | 
    
         
            +
                # +RubyPython.legacy_mode+. If legacy mode is inactive, every returned
         
     | 
| 
      
 93 
     | 
    
         
            +
                # object is wrapped by an instance of +RubyPyProxy+. If legacy mode is
         
     | 
| 
      
 94 
     | 
    
         
            +
                # active, RubyPython first attempts to convert the returned object to a
         
     | 
| 
      
 95 
     | 
    
         
            +
                # native Ruby type, and then only wraps the object if this fails.
         
     | 
| 
       85 
96 
     | 
    
         
             
                def _wrap(pyobject)
         
     | 
| 
       86 
97 
     | 
    
         
             
                  if pyobject.class?
         
     | 
| 
       87 
98 
     | 
    
         
             
                    RubyPyClass.new(pyobject)
         
     | 
| 
         @@ -93,28 +104,45 @@ module RubyPython 
     | 
|
| 
       93 
104 
     | 
    
         
             
                rescue Conversion::UnsupportedConversion => exc
         
     | 
| 
       94 
105 
     | 
    
         
             
                  RubyPyProxy.new pyobject
         
     | 
| 
       95 
106 
     | 
    
         
             
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
                private :_wrap
         
     | 
| 
       96 
108 
     | 
    
         | 
| 
       97 
109 
     | 
    
         
             
                reveal(:respond_to?)
         
     | 
| 
       98 
110 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
                # 
     | 
| 
      
 111 
     | 
    
         
            +
                # The standard Ruby +#respond_to?+ method has been renamed to allow
         
     | 
| 
      
 112 
     | 
    
         
            +
                # RubyPython to query if the proxied \Python object supports the method
         
     | 
| 
      
 113 
     | 
    
         
            +
                # desired. Setter methods (e.g., +foo=+) are always supported.
         
     | 
| 
       100 
114 
     | 
    
         
             
                alias :is_real_method? :respond_to?
         
     | 
| 
       101 
115 
     | 
    
         | 
| 
       102 
     | 
    
         
            -
                #RubyPython checks the attribute dictionary of the wrapped object
         
     | 
| 
       103 
     | 
    
         
            -
                # 
     | 
| 
       104 
     | 
    
         
            -
                # 
     | 
| 
       105 
     | 
    
         
            -
                #respond_to? method has been aliased to is_real_method?. 
     | 
| 
      
 116 
     | 
    
         
            +
                # RubyPython checks the attribute dictionary of the wrapped object to
         
     | 
| 
      
 117 
     | 
    
         
            +
                # check whether it will respond to a method call. This should not return
         
     | 
| 
      
 118 
     | 
    
         
            +
                # false positives but it may return false negatives. The built-in Ruby
         
     | 
| 
      
 119 
     | 
    
         
            +
                # respond_to? method has been aliased to is_real_method?.
         
     | 
| 
       106 
120 
     | 
    
         
             
                def respond_to?(mname)
         
     | 
| 
       107 
121 
     | 
    
         
             
                  return true if is_real_method?(mname)
         
     | 
| 
       108 
122 
     | 
    
         
             
                  mname = mname.to_s
         
     | 
| 
       109 
     | 
    
         
            -
                  return true if mname 
     | 
| 
      
 123 
     | 
    
         
            +
                  return true if mname =~ /=$/
         
     | 
| 
       110 
124 
     | 
    
         
             
                  @pObject.hasAttr(mname)
         
     | 
| 
       111 
125 
     | 
    
         
             
                end
         
     | 
| 
       112 
126 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
                # 
     | 
| 
      
 127 
     | 
    
         
            +
                # Delegates method calls to proxied \Python objects.
         
     | 
| 
      
 128 
     | 
    
         
            +
                #
         
     | 
| 
      
 129 
     | 
    
         
            +
                # == Delegation Rules
         
     | 
| 
      
 130 
     | 
    
         
            +
                # 1. If the method ends with a question-mark (e.g., +nil?+), it can only
         
     | 
| 
      
 131 
     | 
    
         
            +
                #    be a Ruby method on RubyPyProxy. Attempt to reveal it (RubyPyProxy
         
     | 
| 
      
 132 
     | 
    
         
            +
                #    is a BlankObject) and call it.
         
     | 
| 
      
 133 
     | 
    
         
            +
                # 2. If the method ends with equals signs (e.g., +value=+) it's a setter
         
     | 
| 
      
 134 
     | 
    
         
            +
                #    and we can always set an attribute on a \Python object.
         
     | 
| 
      
 135 
     | 
    
         
            +
                # 3. If the method ends with an exclamation point (e.g., +foo!+) we are
         
     | 
| 
      
 136 
     | 
    
         
            +
                #    attempting to call a method with keyword arguments.
         
     | 
| 
      
 137 
     | 
    
         
            +
                # 4. The Python method or value will be called, if it's callable.
         
     | 
| 
      
 138 
     | 
    
         
            +
                # 5. RubyPython will wrap the return value in a RubyPyProxy object
         
     | 
| 
      
 139 
     | 
    
         
            +
                #    (unless legacy_mode has been turned on).
         
     | 
| 
      
 140 
     | 
    
         
            +
                # 6. If a block has been provided, the wrapped return value will be
         
     | 
| 
      
 141 
     | 
    
         
            +
                #    passed into the block.
         
     | 
| 
       114 
142 
     | 
    
         
             
                def method_missing(name, *args, &block)
         
     | 
| 
       115 
143 
     | 
    
         
             
                  name = name.to_s
         
     | 
| 
       116 
144 
     | 
    
         | 
| 
       117 
     | 
    
         
            -
                  if 
     | 
| 
      
 145 
     | 
    
         
            +
                  if name =~ /\?$/
         
     | 
| 
       118 
146 
     | 
    
         
             
                    begin
         
     | 
| 
       119 
147 
     | 
    
         
             
                      RubyPyProxy.reveal(name.to_sym)
         
     | 
| 
       120 
148 
     | 
    
         
             
                      return self.__send__(name.to_sym, *args, &block)
         
     | 
| 
         @@ -124,24 +152,17 @@ module RubyPython 
     | 
|
| 
       124 
152 
     | 
    
         
             
                    end
         
     | 
| 
       125 
153 
     | 
    
         
             
                  end
         
     | 
| 
       126 
154 
     | 
    
         | 
| 
      
 155 
     | 
    
         
            +
                  kwargs = false
         
     | 
| 
       127 
156 
     | 
    
         | 
| 
       128 
     | 
    
         
            -
                  if 
     | 
| 
       129 
     | 
    
         
            -
                     
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
                   
     | 
| 
       132 
     | 
    
         
            -
                     
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
                  if(!@pObject.hasAttr(name) and !setter)
         
     | 
| 
       136 
     | 
    
         
            -
                    raise NoMethodError.new(name)
         
     | 
| 
      
 157 
     | 
    
         
            +
                  if name =~ /=$/
         
     | 
| 
      
 158 
     | 
    
         
            +
                    return @pObject.setAttr(name.chomp('='),
         
     | 
| 
      
 159 
     | 
    
         
            +
                                            PyObject.convert(*args).first)
         
     | 
| 
      
 160 
     | 
    
         
            +
                  elsif name =~ /!$/
         
     | 
| 
      
 161 
     | 
    
         
            +
                    kwargs = true
         
     | 
| 
      
 162 
     | 
    
         
            +
                    name.chomp! "!"
         
     | 
| 
       137 
163 
     | 
    
         
             
                  end
         
     | 
| 
       138 
164 
     | 
    
         | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
                  args = PyObject.convert(*args)
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                  if setter
         
     | 
| 
       143 
     | 
    
         
            -
                    return @pObject.setAttr(name, args[0]) 
         
     | 
| 
       144 
     | 
    
         
            -
                  end
         
     | 
| 
      
 165 
     | 
    
         
            +
                  raise NoMethodError.new(name) if !@pObject.hasAttr(name)
         
     | 
| 
       145 
166 
     | 
    
         | 
| 
       146 
167 
     | 
    
         
             
                  pFunc = @pObject.getAttr(name)
         
     | 
| 
       147 
168 
     | 
    
         | 
| 
         @@ -149,77 +170,108 @@ module RubyPython 
     | 
|
| 
       149 
170 
     | 
    
         
             
                    if args.empty? and pFunc.class?
         
     | 
| 
       150 
171 
     | 
    
         
             
                      pReturn = pFunc
         
     | 
| 
       151 
172 
     | 
    
         
             
                    else
         
     | 
| 
      
 173 
     | 
    
         
            +
                      if kwargs and args.last.is_a?(Hash)
         
     | 
| 
      
 174 
     | 
    
         
            +
                        pKeywords = PyObject.convert(args.pop).first
         
     | 
| 
      
 175 
     | 
    
         
            +
                      end
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                      orig_args = args
         
     | 
| 
      
 178 
     | 
    
         
            +
                      args = PyObject.convert(*args)
         
     | 
| 
       152 
179 
     | 
    
         
             
                      pTuple = PyObject.buildArgTuple(*args)
         
     | 
| 
       153 
     | 
    
         
            -
                      pReturn =  
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
      
 180 
     | 
    
         
            +
                      pReturn = if pKeywords
         
     | 
| 
      
 181 
     | 
    
         
            +
                        pFunc.callObjectKeywords(pTuple, pKeywords)
         
     | 
| 
      
 182 
     | 
    
         
            +
                      else
         
     | 
| 
      
 183 
     | 
    
         
            +
                        pFunc.callObject(pTuple)
         
     | 
| 
      
 184 
     | 
    
         
            +
                      end
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                      # Clean up unused Python vars instead of waiting on Ruby's GC to
         
     | 
| 
      
 187 
     | 
    
         
            +
                      # do it.
         
     | 
| 
      
 188 
     | 
    
         
            +
                      pFunc.xDecref
         
     | 
| 
      
 189 
     | 
    
         
            +
                      pTuple.xDecref
         
     | 
| 
      
 190 
     | 
    
         
            +
                      pKeywords.xDecref if pKeywords
         
     | 
| 
      
 191 
     | 
    
         
            +
                      orig_args.each_with_index do |arg, i|
         
     | 
| 
      
 192 
     | 
    
         
            +
                        # Only decref objects that were created in PyObject.convert.
         
     | 
| 
      
 193 
     | 
    
         
            +
                        if !arg.kind_of?(RubyPython::PyObject) and !arg.kind_of?(RubyPython::RubyPyProxy)
         
     | 
| 
      
 194 
     | 
    
         
            +
                          args[i].xDecref
         
     | 
| 
      
 195 
     | 
    
         
            +
                        end
         
     | 
| 
       156 
196 
     | 
    
         
             
                      end
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
                      raise PythonError.handle_error if PythonError.error?
         
     | 
| 
       157 
199 
     | 
    
         
             
                    end
         
     | 
| 
       158 
200 
     | 
    
         
             
                  else
         
     | 
| 
       159 
201 
     | 
    
         
             
                    pReturn = pFunc
         
     | 
| 
       160 
202 
     | 
    
         
             
                  end
         
     | 
| 
       161 
203 
     | 
    
         | 
| 
       162 
     | 
    
         
            -
                   
     | 
| 
      
 204 
     | 
    
         
            +
                  result = _wrap(pReturn)
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
                  if block
         
     | 
| 
      
 207 
     | 
    
         
            +
                    block.call(result)
         
     | 
| 
      
 208 
     | 
    
         
            +
                  else
         
     | 
| 
      
 209 
     | 
    
         
            +
                    result
         
     | 
| 
      
 210 
     | 
    
         
            +
                  end
         
     | 
| 
       163 
211 
     | 
    
         
             
                end
         
     | 
| 
       164 
212 
     | 
    
         | 
| 
       165 
     | 
    
         
            -
                #RubyPython will attempt to translate the wrapped object into a native
         
     | 
| 
       166 
     | 
    
         
            -
                #Ruby object. This will only succeed for simple  
     | 
| 
      
 213 
     | 
    
         
            +
                # RubyPython will attempt to translate the wrapped object into a native
         
     | 
| 
      
 214 
     | 
    
         
            +
                # Ruby object. This will only succeed for simple built-in type.
         
     | 
| 
       167 
215 
     | 
    
         
             
                def rubify
         
     | 
| 
       168 
216 
     | 
    
         
             
                  @pObject.rubify
         
     | 
| 
       169 
217 
     | 
    
         
             
                end
         
     | 
| 
       170 
218 
     | 
    
         | 
| 
       171 
     | 
    
         
            -
                #Returns the  
     | 
| 
       172 
     | 
    
         
            -
                #object's  
     | 
| 
       173 
     | 
    
         
            -
                #
         
     | 
| 
       174 
     | 
    
         
            -
                #@return [String]
         
     | 
| 
      
 219 
     | 
    
         
            +
                # Returns the String representation of the wrapped object via a call to
         
     | 
| 
      
 220 
     | 
    
         
            +
                # the object's <tt>__repr__</tt> method, or the +repr+ method in PyMain.
         
     | 
| 
       175 
221 
     | 
    
         
             
                def inspect
         
     | 
| 
       176 
222 
     | 
    
         
             
                  self.__repr__.rubify
         
     | 
| 
       177 
223 
     | 
    
         
             
                rescue PythonError, NoMethodError
         
     | 
| 
       178 
224 
     | 
    
         
             
                  RubyPython::PyMain.repr(self).rubify
         
     | 
| 
       179 
225 
     | 
    
         
             
                end
         
     | 
| 
       180 
226 
     | 
    
         | 
| 
       181 
     | 
    
         
            -
                #Returns the string representation of the wrapped object via a call to 
     | 
| 
       182 
     | 
    
         
            -
                #object's  
     | 
| 
       183 
     | 
    
         
            -
                #
         
     | 
| 
       184 
     | 
    
         
            -
                #@return [String]
         
     | 
| 
      
 227 
     | 
    
         
            +
                # Returns the string representation of the wrapped object via a call to
         
     | 
| 
      
 228 
     | 
    
         
            +
                # the object's <tt>__str__</tt> method or the +str+ method in PyMain.
         
     | 
| 
       185 
229 
     | 
    
         
             
                def to_s
         
     | 
| 
       186 
230 
     | 
    
         
             
                  self.__str__.rubify
         
     | 
| 
       187 
231 
     | 
    
         
             
                rescue PythonError, NoMethodError
         
     | 
| 
       188 
232 
     | 
    
         
             
                  RubyPython::PyMain.str(self).rubify
         
     | 
| 
       189 
233 
     | 
    
         
             
                end
         
     | 
| 
       190 
234 
     | 
    
         | 
| 
       191 
     | 
    
         
            -
                #Converts the wrapped Python object to a Ruby Array. Note that this 
     | 
| 
       192 
     | 
    
         
            -
                #one level, so a nested array will remain a proxy object. 
     | 
| 
       193 
     | 
    
         
            -
                #objects which have an  
     | 
| 
      
 235 
     | 
    
         
            +
                # Converts the wrapped \Python object to a Ruby Array. Note that this
         
     | 
| 
      
 236 
     | 
    
         
            +
                # only converts one level, so a nested array will remain a proxy object.
         
     | 
| 
      
 237 
     | 
    
         
            +
                # Only wrapped objects which have an <tt>__iter__</tt> method may be
         
     | 
| 
      
 238 
     | 
    
         
            +
                # converted using +to_a+.
         
     | 
| 
      
 239 
     | 
    
         
            +
                #
         
     | 
| 
      
 240 
     | 
    
         
            +
                # Note that for \Python Dict objects, this method returns what you would
         
     | 
| 
      
 241 
     | 
    
         
            +
                # get in \Python, not in Ruby: +a_dict.to_a+ returns an array of the
         
     | 
| 
      
 242 
     | 
    
         
            +
                # dictionary's keys.
         
     | 
| 
       194 
243 
     | 
    
         
             
                #
         
     | 
| 
       195 
     | 
    
         
            -
                # 
     | 
| 
       196 
     | 
    
         
            -
                # 
     | 
| 
       197 
     | 
    
         
            -
                # 
     | 
| 
       198 
     | 
    
         
            -
                 
     | 
| 
       199 
     | 
    
         
            -
                 
     | 
| 
       200 
     | 
    
         
            -
                # 
     | 
| 
       201 
     | 
    
         
            -
                # 
     | 
| 
       202 
     | 
    
         
            -
                # 
     | 
| 
       203 
     | 
    
         
            -
                # 
     | 
| 
       204 
     | 
    
         
            -
                # 
     | 
| 
       205 
     | 
    
         
            -
                # 
     | 
| 
       206 
     | 
    
         
            -
                #    irb(main):004:0> a_list.to_a
         
     | 
| 
       207 
     | 
    
         
            -
                #    => [1, 'a', 2, 'b']
         
     | 
| 
       208 
     | 
    
         
            -
                #    irb(main):005:0> RubyPython.stop
         
     | 
| 
       209 
     | 
    
         
            -
                #    => true
         
     | 
| 
       210 
     | 
    
         
            -
                #    
         
     | 
| 
       211 
     | 
    
         
            -
                #@example Dict
         
     | 
| 
       212 
     | 
    
         
            -
                #    irb(main):001:0> RubyPython.start
         
     | 
| 
       213 
     | 
    
         
            -
                #    => true
         
     | 
| 
       214 
     | 
    
         
            -
                #    irb(main):002:0> a_dict = RubyPython::RubyPyProxy.new({1 => '2', :three => [4,5]})
         
     | 
| 
       215 
     | 
    
         
            -
                #    => {1: '2', 'three': [4, 5]}
         
     | 
| 
       216 
     | 
    
         
            -
                #    irb(main):003:0> a_dict.kind_of? RubyPython::RubyPyProxy
         
     | 
| 
       217 
     | 
    
         
            -
                #    => true
         
     | 
| 
       218 
     | 
    
         
            -
                #    irb(main):004:0> a_dict.to_a
         
     | 
| 
       219 
     | 
    
         
            -
                #    => [1, 'three']
         
     | 
| 
       220 
     | 
    
         
            -
                #    irb(main):005:0> RubyPython.stop
         
     | 
| 
       221 
     | 
    
         
            -
                #    => true
         
     | 
| 
      
 244 
     | 
    
         
            +
                # === List #to_a Returns an Array
         
     | 
| 
      
 245 
     | 
    
         
            +
                #   >> RubyPython.start
         
     | 
| 
      
 246 
     | 
    
         
            +
                #   => true
         
     | 
| 
      
 247 
     | 
    
         
            +
                #   >> list = RubyPython::RubyPyProxy.new([1, 'a', 2, 'b'])
         
     | 
| 
      
 248 
     | 
    
         
            +
                #   => [1, 'a', 2, 'b']
         
     | 
| 
      
 249 
     | 
    
         
            +
                #   >> list.kind_of? RubyPython::RubyPyProxy
         
     | 
| 
      
 250 
     | 
    
         
            +
                #   => true
         
     | 
| 
      
 251 
     | 
    
         
            +
                #   >> list.to_a
         
     | 
| 
      
 252 
     | 
    
         
            +
                #   => [1, 'a', 2, 'b']
         
     | 
| 
      
 253 
     | 
    
         
            +
                #   >> RubyPython.stop
         
     | 
| 
      
 254 
     | 
    
         
            +
                #   => true
         
     | 
| 
       222 
255 
     | 
    
         
             
                #
         
     | 
| 
      
 256 
     | 
    
         
            +
                # === Dict #to_a Returns An Array of Keys
         
     | 
| 
      
 257 
     | 
    
         
            +
                #   >> RubyPython.start
         
     | 
| 
      
 258 
     | 
    
         
            +
                #   => true
         
     | 
| 
      
 259 
     | 
    
         
            +
                #   >> dict = RubyPython::RubyPyProxy.new({1 => '2', :three => [4,5]})
         
     | 
| 
      
 260 
     | 
    
         
            +
                #   => {1: '2', 'three': [4, 5]}
         
     | 
| 
      
 261 
     | 
    
         
            +
                #   >> dict.kind_of? RubyPython::RubyPyProxy
         
     | 
| 
      
 262 
     | 
    
         
            +
                #   => true
         
     | 
| 
      
 263 
     | 
    
         
            +
                #   >> dict.to_a
         
     | 
| 
      
 264 
     | 
    
         
            +
                #   => [1, 'three']
         
     | 
| 
      
 265 
     | 
    
         
            +
                #   >> RubyPython.stop
         
     | 
| 
      
 266 
     | 
    
         
            +
                #   => true
         
     | 
| 
      
 267 
     | 
    
         
            +
                #
         
     | 
| 
      
 268 
     | 
    
         
            +
                # === Non-Array Values Do Not Convert
         
     | 
| 
      
 269 
     | 
    
         
            +
                #   >> RubyPython.start
         
     | 
| 
      
 270 
     | 
    
         
            +
                #   => true
         
     | 
| 
      
 271 
     | 
    
         
            +
                #   >> item = RubyPython::RubyPyProxy.new(42)
         
     | 
| 
      
 272 
     | 
    
         
            +
                #   => 42
         
     | 
| 
      
 273 
     | 
    
         
            +
                #   >> item.to_a
         
     | 
| 
      
 274 
     | 
    
         
            +
                #   NoMethodError: __iter__
         
     | 
| 
       223 
275 
     | 
    
         
             
                def to_a
         
     | 
| 
       224 
276 
     | 
    
         
             
                  iter = self.__iter__
         
     | 
| 
       225 
277 
     | 
    
         
             
                  ary = []
         
     | 
| 
         @@ -231,30 +283,54 @@ module RubyPython 
     | 
|
| 
       231 
283 
     | 
    
         
             
                  ary
         
     | 
| 
       232 
284 
     | 
    
         
             
                end
         
     | 
| 
       233 
285 
     | 
    
         | 
| 
       234 
     | 
    
         
            -
             
     | 
| 
      
 286 
     | 
    
         
            +
                # Returns the methods on the \Python object by calling the +dir+
         
     | 
| 
      
 287 
     | 
    
         
            +
                # built-in.
         
     | 
| 
      
 288 
     | 
    
         
            +
                def methods
         
     | 
| 
      
 289 
     | 
    
         
            +
                  pObject.dir.map { |x| x.to_sym }
         
     | 
| 
      
 290 
     | 
    
         
            +
                end
         
     | 
| 
       235 
291 
     | 
    
         | 
| 
       236 
     | 
    
         
            -
             
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
             
     | 
| 
      
 292 
     | 
    
         
            +
                # Creates a PyEnumerable for this object. The object must have the
         
     | 
| 
      
 293 
     | 
    
         
            +
                # <tt>__iter__</tt> method.
         
     | 
| 
      
 294 
     | 
    
         
            +
                def to_enum
         
     | 
| 
      
 295 
     | 
    
         
            +
                  PyEnumerable.new(@pObject)
         
     | 
| 
      
 296 
     | 
    
         
            +
                end
         
     | 
| 
       239 
297 
     | 
    
         
             
              end
         
     | 
| 
       240 
298 
     | 
    
         | 
| 
       241 
     | 
    
         
            -
              #A class to wrap Python  
     | 
| 
       242 
     | 
    
         
            -
               
     | 
| 
      
 299 
     | 
    
         
            +
              # A class to wrap \Python modules. It behaves exactly the same as
         
     | 
| 
      
 300 
     | 
    
         
            +
              # RubyPyProxy. It is just here for Bookkeeping and aesthetics.
         
     | 
| 
      
 301 
     | 
    
         
            +
              class RubyPyModule < RubyPyProxy; end
         
     | 
| 
       243 
302 
     | 
    
         | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
       245 
     | 
    
         
            -
             
     | 
| 
      
 303 
     | 
    
         
            +
              # A class to wrap \Python classes.
         
     | 
| 
      
 304 
     | 
    
         
            +
              class RubyPyClass < RubyPyProxy
         
     | 
| 
      
 305 
     | 
    
         
            +
                # Create an instance of the wrapped class. This is a workaround for the
         
     | 
| 
      
 306 
     | 
    
         
            +
                # fact that \Python classes are meant to be callable.
         
     | 
| 
       246 
307 
     | 
    
         
             
                def new(*args)
         
     | 
| 
       247 
308 
     | 
    
         
             
                  args = PyObject.convert(*args)
         
     | 
| 
       248 
309 
     | 
    
         
             
                  pTuple = PyObject.buildArgTuple(*args)
         
     | 
| 
       249 
310 
     | 
    
         
             
                  pReturn = @pObject.callObject(pTuple)
         
     | 
| 
       250 
     | 
    
         
            -
                  if PythonError.error?
         
     | 
| 
       251 
     | 
    
         
            -
                    raise PythonError.handle_error
         
     | 
| 
       252 
     | 
    
         
            -
                  end
         
     | 
| 
      
 311 
     | 
    
         
            +
                  raise PythonError.handle_error if PythonError.error?
         
     | 
| 
       253 
312 
     | 
    
         
             
                  RubyPyInstance.new pReturn
         
     | 
| 
       254 
313 
     | 
    
         
             
                end
         
     | 
| 
       255 
314 
     | 
    
         
             
              end
         
     | 
| 
       256 
315 
     | 
    
         | 
| 
       257 
     | 
    
         
            -
              #An object representing an instance of a Python  
     | 
| 
       258 
     | 
    
         
            -
               
     | 
| 
      
 316 
     | 
    
         
            +
              # An object representing an instance of a \Python class. It behaves
         
     | 
| 
      
 317 
     | 
    
         
            +
              # exactly the same as RubyPyProxy. It is just here for Bookkeeping and
         
     | 
| 
      
 318 
     | 
    
         
            +
              # aesthetics.
         
     | 
| 
      
 319 
     | 
    
         
            +
              class RubyPyInstance < RubyPyProxy; end
         
     | 
| 
      
 320 
     | 
    
         
            +
             
     | 
| 
      
 321 
     | 
    
         
            +
              # An object representing a Python enumerable object.
         
     | 
| 
      
 322 
     | 
    
         
            +
              class PyEnumerable < RubyPyProxy
         
     | 
| 
      
 323 
     | 
    
         
            +
                include Enumerable
         
     | 
| 
      
 324 
     | 
    
         
            +
             
     | 
| 
      
 325 
     | 
    
         
            +
                def each
         
     | 
| 
      
 326 
     | 
    
         
            +
                  iter = self.__iter__
         
     | 
| 
      
 327 
     | 
    
         
            +
                  loop do
         
     | 
| 
      
 328 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 329 
     | 
    
         
            +
                      yield iter.next
         
     | 
| 
      
 330 
     | 
    
         
            +
                    rescue RubyPython::PythonError => exc
         
     | 
| 
      
 331 
     | 
    
         
            +
                      return if exc.message =~ /StopIteration/
         
     | 
| 
      
 332 
     | 
    
         
            +
                    end
         
     | 
| 
      
 333 
     | 
    
         
            +
                  end
         
     | 
| 
      
 334 
     | 
    
         
            +
                end
         
     | 
| 
       259 
335 
     | 
    
         
             
              end
         
     | 
| 
       260 
336 
     | 
    
         
             
            end
         
     |