rubypython 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format d
data/History.markdown CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.3.2 2011-02-02
2
+ * Major Enhancements
3
+ * Allow procs and methods to be passed to Ruby.
4
+ * Allow configuration of the loaded Python library.
5
+
1
6
  ## 0.3.1 2011-01-19
2
7
  * Compatability Updates
3
8
  * Cleanup of code which finds Python library thanks to Austin Ziegler.
data/License.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 Zach Raines
1
+ Copyright (c) 2008-2011 Zach Raines
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt CHANGED
@@ -4,29 +4,34 @@ Manifest.txt
4
4
  PostInstall.txt
5
5
  README.markdown
6
6
  Rakefile
7
+ .rspec
8
+ lib/rubypython
7
9
  lib/rubypython.rb
8
10
  lib/rubypython/blankobject.rb
11
+ lib/rubypython/conversion.rb
12
+ lib/rubypython/core_ext
9
13
  lib/rubypython/core_ext/string.rb
10
- lib/rubypython/pythonerror.rb
14
+ lib/rubypython/legacy.rb
11
15
  lib/rubypython/macros.rb
12
- lib/rubypython/conversion.rb
13
16
  lib/rubypython/operators.rb
14
- lib/rubypython/pyobject.rb
17
+ lib/rubypython/options.rb
15
18
  lib/rubypython/pymainclass.rb
19
+ lib/rubypython/pyobject.rb
16
20
  lib/rubypython/python.rb
21
+ lib/rubypython/pythonerror.rb
17
22
  lib/rubypython/rubypyproxy.rb
18
23
  lib/rubypython/version.rb
19
- lib/rubypython/legacy.rb
24
+ spec/callback_spec.rb
25
+ spec/conversion_spec.rb
26
+ spec/legacy_spec.rb
20
27
  spec/pymainclass_spec.rb
21
28
  spec/pyobject_spec.rb
22
29
  spec/python_helpers
23
30
  spec/python_helpers/objects.py
31
+ spec/python_helpers/objects.pyc
24
32
  spec/pythonerror_spec.rb
33
+ spec/refcnt_spec.rb
25
34
  spec/rubypyclass_spec.rb
26
35
  spec/rubypyproxy_spec.rb
27
36
  spec/rubypython_spec.rb
28
- spec/refcnt_spec.rb
29
- spec/conversion_spec.rb
30
- spec/legacy_spec.rb
31
- spec/spec.opts
32
37
  spec/spec_helper.rb
data/README.markdown CHANGED
@@ -1,6 +1,6 @@
1
1
  # RubyPython
2
2
 
3
- * [RubyPython](http://raineszm.bitbucket.org/rubypython/)
3
+ * [RubyPython](http://bitbucket.org/raineszm/rubypython/)
4
4
 
5
5
  ## DESCRIPTION:
6
6
 
@@ -17,6 +17,8 @@ provides a means for wrapping and converting Python objects.
17
17
  * Can execute arbitrary methods on imported modules and return the result
18
18
  * Python objects can be treated as Ruby objects!
19
19
  * Python's standard library available to you from within Ruby.
20
+ * Pass Ruby methods and procs as callbacks and call them from within Python code.
21
+ * Specify the python executable to be loaded.
20
22
 
21
23
  ### Known Problems
22
24
 
@@ -75,13 +77,13 @@ The documentation should provide a reasonable description of how to use RubyPyth
75
77
  Starting with version 0.3.x there are two modes of operation: normal and
76
78
  legacy. These are described in the docs.
77
79
 
78
- The most useful to check out [docs](http://raineszm.bitbucket.org/rubypython/) will be those for RubyPython and RubyPython::RubyPyProxy.
80
+ The most useful to check out [docs](http://rubydoc.info/gems/rubypython/) will be those for RubyPython and RubyPython::RubyPyProxy.
79
81
 
80
82
  ## LICENSE:
81
83
 
82
84
  (The MIT License)
83
85
 
84
- Copyright (c) 2008 Zach Raines
86
+ Copyright (c) 2008-2011 Zach Raines
85
87
 
86
88
  Permission is hereby granted, free of charge, to any person obtaining
87
89
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,14 +1,16 @@
1
- require 'spec/rake/spectask'
1
+ require 'rspec/core/rake_task'
2
2
  require 'yard'
3
3
 
4
4
  desc "Run all examples"
5
- Spec::Rake::SpecTask.new('spec') do |t|
6
- t.spec_files = FileList['spec/**/*_spec.rb']
5
+ RSpec::Core::RakeTask.new('spec') do |t|
6
+ t.pattern = 'spec/**/*_spec.rb'
7
+ t.rspec_opts = '-t ~@slow' unless ENV['filter'] == 'none'
7
8
  end
8
9
 
9
10
  desc "Run all examples with RCov"
10
- Spec::Rake::SpecTask.new('spec:rcov') do |t|
11
- t.spec_files = FileList['spec/**/*.rb']
11
+ RSpec::Core::RakeTask.new('spec:rcov') do |t|
12
+ t.pattern = 'spec/**/*.rb'
13
+ t.rspec_opts = '--tag ~slow:true' unless ENV['filter'] == 'none'
12
14
  t.rcov = true
13
15
  t.rcov_opts = ['--exclude', 'spec']
14
16
  end
@@ -65,12 +65,26 @@ module RubyPython
65
65
  Python.PyString_FromString rSymbol.to_s
66
66
  end
67
67
 
68
+ def self.rtopProc(rObj)
69
+ pyMethodDef = Python::PyMethodDef.new
70
+ callback = Proc.new do |py_self, py_args|
71
+ ret = rObj.call(*RubyPyProxy.new(py_args).to_a)
72
+ PyObject.convert(ret)[0].pointer
73
+ end
74
+ pyMethodDef[:ml_name] = FFI::MemoryPointer.from_string "Proc::#{rObj.object_id}"
75
+ pyMethodDef[:ml_meth] = callback
76
+ pyMethodDef[:ml_flags] = Python::METH_VARARGS
77
+ pyMethodDef[:ml_doc] = nil
78
+
79
+ Python::PyCFunction_New pyMethodDef, nil
80
+ end
81
+
68
82
  #If possible converts a ruby type to an equivalent
69
83
  #python native type.
70
84
  #@param rObj a native ruby type
71
85
  #@param [Boolean] is_key whether this object will be used as a key in a
72
86
  # python dict.
73
- #@return [FFI::Pointer] a to a C PyObject\*
87
+ #@return [FFI::Pointer] a pointer to a C PyObject\*
74
88
  #@raise [UnsupportedConversion]
75
89
  def self.rtopObject(rObj, is_key=false)
76
90
  case rObj
@@ -101,6 +115,9 @@ module RubyPython
101
115
  rtopSymbol rObj
102
116
  when nil
103
117
  rtopNone
118
+ when Proc, Method
119
+ raise UnsupportedConversion.new("Python to Ruby callbacks not suppported in legacy mode") if RubyPython.legacy_mode
120
+ rtopProc rObj
104
121
  else
105
122
  raise UnsupportedConversion.new("Unsupported type for RTOP conversion." )
106
123
  end
@@ -1,5 +1,30 @@
1
1
  require 'rubypython'
2
2
 
3
+ #A quick way to activate legacy mode for your project. Requiring
4
+ #'rubypython/legacy' automatically activates legacy_mode as described
5
+ #in the documentation for {RubyPython}. If you wish to run your
6
+ #project in legacy mode you can require 'rubypython/legacy' instead of
7
+ #'rubypython'
8
+ #
9
+ #@example Default Behavior
10
+ # irb(main):001:0> require 'rubypython'
11
+ # => true
12
+ # irb(main):002:0> RubyPython.start
13
+ # => true
14
+ # irb(main):003:0> RubyPython::PyMain.float(42).is_a? RubyPython::RubyPyProxy
15
+ # => true
16
+ # irb(main):004:0> RubyPython.stop
17
+ # => true
18
+ #
19
+ #@example Legacy Mode
20
+ # irb(main):001:0> require 'rubypython/legacy'
21
+ # => true
22
+ # irb(main):002:0> RubyPython.start
23
+ # => true
24
+ # irb(main):003:0> RubyPython::PyMain.float(42).is_a? Float
25
+ # => true
26
+ # irb(main):004:0> RubyPython.stop
27
+ # => true
3
28
  module RubyPython::LegacyMode
4
29
  class << self
5
30
  def setup_legacy
@@ -107,5 +107,12 @@ module RubyPython
107
107
  PyMain.cmp(self, other)
108
108
  end
109
109
 
110
+ #For internal use only. Called by {RubyPython} when the
111
+ #interpreter is started or stopped so that the neccesary
112
+ #preperation or cleanup can be done.
113
+ def self.update(status)
114
+ @@operator = nil if status.equal? :stop
115
+ end
116
+
110
117
  end
111
118
  end
@@ -0,0 +1,69 @@
1
+ module RubyPython
2
+ #A hash for storing RubyPython execution options.
3
+ @options = {}
4
+
5
+ #A list of options which require the Python library to be reloaded.
6
+ NEED_RELOAD = [
7
+ :python_exe,
8
+ :python_lib
9
+ ]
10
+
11
+ class << self
12
+ #Allows one to set options for RubyPython's execution. Parameters
13
+ #may be set either by supplying a hash argument or by supplying
14
+ #a block and calling setters on the provided OpenStruct.
15
+ #@param [Hash] opts a hash of options to set
16
+ #@option opts [String] :python_exe The python executable for
17
+ # the python version you wish to use. Can be anything in your
18
+ # execution path as well as a local or relative path.
19
+ #@option opts [String] :python_lib The full path to the python
20
+ # library you wish to load.
21
+ #@return [Hash] a copy of the new options hash
22
+ #
23
+ #@example
24
+ # irb(main):001:0> RubyPython.run do
25
+ # irb(main):002:1* RubyPython.import('sys').version.rubify.to_f
26
+ # irb(main):003:1> end
27
+ # => 2.7
28
+ # irb(main):004:0> RubyPython.configure :python_exe => 'python2.6'
29
+ # => {:python_exe=>"python2.6"}
30
+ # irb(main):005:0> RubyPython.run do
31
+ # irb(main):006:1* RubyPython.import('sys').version.rubify.to_f
32
+ # irb(main):007:1> end
33
+ # => 2.6
34
+ #
35
+ def configure(opts={})
36
+ old_values = @options.select { |k,v| NEED_RELOAD.include? k }
37
+
38
+ if block_given?
39
+ ostruct = OpenStruct.new @options
40
+ yield ostruct
41
+ @options = Hash[*ostruct.instance_eval do
42
+ @table.map do |k, v|
43
+ [k.to_sym, v]
44
+ end.flatten
45
+ end]
46
+ end
47
+ @options.merge!(opts)
48
+
49
+ @reload = true if NEED_RELOAD.any? { |k| @options[k] != old_values[k] }
50
+ options
51
+ end
52
+
53
+ #Returns a copy of the hash currently being used to determine run
54
+ #options. This allows the user to determine what options have been
55
+ #set. Modification of options should be done via the configure
56
+ #method.
57
+ #@return [Hash] a copy of the current options hash
58
+ def options
59
+ @options.dup
60
+ end
61
+
62
+ #Reset the options hash.
63
+ #@return [void]
64
+ def clear_options
65
+ @options.clear
66
+ end
67
+
68
+ end
69
+ end
@@ -17,13 +17,13 @@ module RubyPython
17
17
  attr_writer :main, :builtin
18
18
 
19
19
  #@return [RubyPyModule] a proxy object wrapping the Python \__main\__
20
- #namespace.
20
+ # namespace.
21
21
  def main
22
22
  @main||=RubyPython.import "__main__"
23
23
  end
24
24
 
25
25
  #@return [RubyPyModule] a proxy object wrapping the Python \__builtin\__
26
- #namespace.
26
+ # namespace.
27
27
  def builtin
28
28
  @builtin||=RubyPython.import "__builtin__"
29
29
  end
@@ -45,6 +45,17 @@ module RubyPython
45
45
  end
46
46
  block ? block.call(result) : result
47
47
  end
48
+
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.
52
+ def update(status)
53
+ if status.equal? :stop
54
+ @main = nil
55
+ @builtin = nil
56
+ end
57
+ end
58
+
48
59
  end
49
60
 
50
61
  PyMain = PyMainClass.instance
@@ -10,8 +10,6 @@ module RubyPython
10
10
  #subclasses.
11
11
  class PyObject
12
12
 
13
- #@private
14
- #
15
13
  #This class wraps C PyObject\*s so that the Python reference count is
16
14
  #automatically decreased when the Ruby object referencing them
17
15
  #goes out of scope.
@@ -33,6 +31,14 @@ module RubyPython
33
31
  Python.Py_DecRef pointer
34
32
  end
35
33
  end
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
41
+ end
36
42
  end
37
43
 
38
44
  self.current_pointers = {}
@@ -123,9 +129,15 @@ module RubyPython
123
129
  #Tests whether the wrapped object is a function or a method. This is not the
124
130
  #same as {#callable?} as many other Python objects are callable.
125
131
  def function_or_method?
126
- isFunc = (Macros.PyObject_TypeCheck(@pointer, Python.PyFunction_Type.to_ptr) != 0)
127
- isMethod = (Macros.PyObject_TypeCheck(@pointer, Python.PyMethod_Type.to_ptr) != 0)
128
- isFunc or isMethod
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
139
+
140
+ false
129
141
  end
130
142
 
131
143
  #Is the wrapped object callable?