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.
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
@@ -1,39 +1,38 @@
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'
3
+ # A quick way to active <em>Legacy Mode</em> for a project. Requiring
4
+ # +'rubypython/legacy' automatically activates +RubyPython.legacy_mode+ on
5
+ # the project.
8
6
  #
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
7
+ # This mode may be phased out for RubyPython 1.0.
8
+ #
9
+ # === Default
10
+ # require 'rubypython'
11
+ #
12
+ # RubyPython.session do
13
+ # string = RubyPython.import 'string'
14
+ # ascii_letters = string.ascii_letters
15
+ # puts ascii_letters.isalpha # => True
16
+ # puts ascii_letters.rubify.isalpha # throws NoMethodError
17
+ # end
18
+ #
19
+ # === Legacy Mode
20
+ # require 'rubypython/legacy'
21
+ #
22
+ # RubyPython.session do
23
+ # string = RubyPython.import 'string'
24
+ # ascii_letters = string.ascii_letters
25
+ # puts ascii_letters.isalpha # throws NoMethodError
26
+ # end
28
27
  module RubyPython::LegacyMode
29
- class << self
30
- def setup_legacy
31
- RubyPython.legacy_mode = true
32
- end
28
+ # Enables +RubyPython.legacy_mode+.
29
+ def self.setup_legacy
30
+ RubyPython.legacy_mode = true
31
+ end
33
32
 
34
- def teardown_legacy
35
- RubyPython.legacy_mode = false
36
- end
33
+ # Disables +RubyPython.legacy_mode+.
34
+ def self.teardown_legacy
35
+ RubyPython.legacy_mode = false
37
36
  end
38
37
  end
39
38
 
@@ -1,47 +1,56 @@
1
1
  require 'ffi'
2
2
  require 'rubypython/python'
3
3
 
4
- module RubyPython
5
- #Contains Python C API macros reimplmented in Ruby. For internal use only.
6
- module Macros
7
- def self.Py_TYPE(pObjPointer)
8
- pStruct = Python::PyObjectStruct.new pObjPointer
9
- pStruct[:ob_type]
10
- end
4
+ # Contains Python C API macros reimplemented in Ruby. For internal use only.
5
+ module RubyPython::Macros #:nodoc:
6
+ # Returns the reference count for the provided pointer.
7
+ def self.Py_REFCNT(pObjPointer)
8
+ pStruct = RubyPython::Python::PyObjectStruct.new pObjPointer
9
+ pStruct[:ob_refcnt]
10
+ end
11
11
 
12
- def self.PyObject_TypeCheck(pObject, pTypePointer)
13
- if Py_TYPE(pObject) == pTypePointer
14
- 1
15
- else
16
- 0
17
- end
18
- end
12
+ # Returns the object type for the provided pointer.
13
+ def self.Py_TYPE(pObjPointer)
14
+ pStruct = RubyPython::Python::PyObjectStruct.new pObjPointer
15
+ pStruct[:ob_type]
16
+ end
19
17
 
20
- def self.Py_True
21
- Python.Py_TrueStruct.to_ptr
22
- end
18
+ # This has been modified from the C API macro to allow for multiple
19
+ # pointer objects to be passed. It simplifies a number of checks.
20
+ def self.PyObject_TypeCheck(pObject, pTypePointer)
21
+ type = self.Py_TYPE(pObject)
23
22
 
24
- def self.Py_False
25
- Python.Py_ZeroStruct.to_ptr
23
+ [ pTypePointer ].flatten.each do |pointer|
24
+ return 1 if type == pointer
26
25
  end
27
26
 
28
- def self.Py_None
29
- Python.Py_NoneStruct.to_ptr
30
- end
27
+ return 0
28
+ end
31
29
 
32
- def self.Py_RETURN_FALSE
33
- Python.Py_IncRef(self.Py_False)
34
- self.Py_False
35
- end
30
+ def self.Py_True
31
+ RubyPython::Python.Py_TrueStruct.to_ptr
32
+ end
36
33
 
37
- def self.Py_RETURN_TRUE
38
- Python.Py_IncRef(self.Py_True)
39
- self.Py_True
40
- end
34
+ def self.Py_False
35
+ RubyPython::Python.Py_ZeroStruct.to_ptr
36
+ end
41
37
 
42
- def self.Py_RETURN_NONE
43
- Python.Py_IncRef(self.Py_None)
44
- self.Py_None
45
- end
38
+ def self.Py_None
39
+ RubyPython::Python.Py_NoneStruct.to_ptr
40
+ end
41
+
42
+ def self.Py_RETURN_FALSE
43
+ RubyPython::Python.Py_IncRef(self.Py_False)
44
+ self.Py_False
45
+ end
46
+
47
+ def self.Py_RETURN_TRUE
48
+ RubyPython::Python.Py_IncRef(self.Py_True)
49
+ self.Py_True
50
+ end
51
+
52
+ def self.Py_RETURN_NONE
53
+ RubyPython::Python.Py_IncRef(self.Py_None)
54
+ self.Py_None
46
55
  end
47
56
  end
@@ -1,118 +1,120 @@
1
- module RubyPython
2
- #A mixin module to provide method delegation to a proxy class. This is done
3
- #either by delegating to methods defined on the wrapped object or by using the
4
- #Python _operator_ module. A large number of the methods are dynamically
5
- #generated and so their documentation is not provided here. In general all
6
- #operators that can be overloaded are delegated.
7
- module Operators
8
- #Provides access to the Python _operator_ module.
9
- #@return[RubyPython::RubyPyModule]
10
- def self.operator_
11
- @@operator ||= RubyPython.import('operator')
12
- end
13
-
14
- #Creates a method to delegate a binary operation. The result of the
15
- #operation will follow the conversion rules appropriate to the current mode
16
- #of operation as set by {RubyPython.legacy_mode}.
17
- #@param[Symbol, String] rname The name of the Ruby method for this operation
18
- #@param[String] pname The name of the Python magic method to which this
19
- #method should be delegated.
20
- def self.bin_op rname, pname
21
- define_method rname.to_sym do |other|
22
- self.__send__ pname, other
23
- end
24
- end
1
+ # A mixin module to provide method delegation to a proxy class. This is done
2
+ # either by delegating to methods defined on the wrapped object or by using
3
+ # the \Python _operator_ module. A large number of the methods are
4
+ # dynamically generated and so their documentation is not provided here. In
5
+ # general all operators that can be overloaded are delegated.
6
+ module RubyPython::Operators
7
+ # Provides access to the \Python _operator_ module.
8
+ def self.operator_
9
+ @@operator ||= RubyPython.import('operator')
10
+ end
25
11
 
26
- #Creates a method to delegate a relational operator. The result of the
27
- #delegated method will always be converted to a Ruby type so that simple
28
- #boolean testing may occur. These methods are implemented with calls the
29
- #_operator_ module.
30
- #@param[Symbol, String] rname The name of the Ruby method for this operation
31
- #@param[String] pname The name of the Python magic method to which this
32
- #method should be delegated.
33
- def self.rel_op rname, pname
34
- define_method rname.to_sym do |other|
35
- Operators.operator_.__send__(pname, self, other).rubify
36
- end
12
+ # Creates a method to delegate a binary operation. The result of the
13
+ # operation will follow the conversion rules appropriate to the current
14
+ # mode of operation as set by {RubyPython.legacy_mode}.
15
+ # [rname] The name of the Ruby method for this operation. Can be either a
16
+ # Symbol or a String.
17
+ # [pname] The name of the \Python magic method to which this method should
18
+ # be delegated.
19
+ def self.bin_op(rname, pname)
20
+ define_method rname.to_sym do |other|
21
+ self.__send__(pname, other)
37
22
  end
23
+ end
38
24
 
39
- #Creates a method to delegate a relational operator. The result of the
40
- #operation will follow the conversion rules appropriate to the current mode
41
- #of operation as set by {RubyPython.legacy_mode}. These methods are
42
- #implemented with calls the _operator_ module.
43
- #@param[Symbol, String] rname The name of the Ruby method for this operation
44
- #@param[String] pname The name of the Python magic method to which this
45
- #method should be delegated.
46
- def self.unary_op rname, pname
47
- define_method rname.to_sym do
48
- Operators.operator_.__send__(pname, self)
49
- end
25
+ # Creates a method to delegate a relational operator. The result of the
26
+ # delegated method will always be converted to a Ruby type so that simple
27
+ # boolean testing may occur. These methods are implemented with calls the
28
+ # _operator_ module.
29
+ #
30
+ # [rname] The name of the Ruby method for this operation. Can be a Symbol
31
+ # or a String.
32
+ # [pname] The name of the \Python magic method to which this method should
33
+ # be delegated.
34
+ def self.rel_op(rname, pname)
35
+ define_method rname.to_sym do |other|
36
+ RubyPython::Operators.operator_.__send__(pname, self, other).rubify
50
37
  end
38
+ end
51
39
 
52
-
53
- [
54
- [:+, '__add__'],
55
- [:-, '__sub__'],
56
- [:*, '__mul__'],
57
- [:/, '__div__'],
58
- [:&, '__and__'],
59
- [:^, '__xor__'],
60
- [:%, '__mod__'],
61
- [:**, '__pow__'],
62
- [:>>, '__rshift__'],
63
- [:<<, '__lshift__'],
64
- [:|, '__or__']
65
- ].each do |args|
66
- bin_op *args
40
+ # Creates a method to delegate a relational operator. The result of the
41
+ # operation will follow the conversion rules appropriate to the current
42
+ # mode of operation as set by {RubyPython.legacy_mode}. These methods are
43
+ # implemented with calls the _operator_ module.
44
+ # [rname] The name of the Ruby method for this operation. Can be a Symbol
45
+ # or a String.
46
+ # [pname] The name of the \Python magic method to which this method should
47
+ # be delegated.
48
+ def self.unary_op(rname, pname)
49
+ define_method rname.to_sym do
50
+ RubyPython::Operators.operator_.__send__(pname, self)
67
51
  end
52
+ end
68
53
 
69
- [
70
- [:~, :__invert__],
71
- [:+@, :__pos__],
72
- [:-@, :__neg__]
73
- ].each do |args|
74
- unary_op *args
75
- end
54
+ [
55
+ [:+, '__add__'],
56
+ [:-, '__sub__'],
57
+ [:*, '__mul__'],
58
+ [:/, '__div__'],
59
+ [:&, '__and__'],
60
+ [:^, '__xor__'],
61
+ [:%, '__mod__'],
62
+ [:**, '__pow__'],
63
+ [:>>, '__rshift__'],
64
+ [:<<, '__lshift__'],
65
+ [:|, '__or__']
66
+ ].each do |args|
67
+ bin_op *args
68
+ end
76
69
 
77
- [
78
- [:==, 'eq'],
79
- [:<, 'lt'],
80
- [:<=, 'le'],
81
- [:>, 'gt'],
82
- [:>=, 'ge'],
83
- [:equal?, 'is_']
84
- ].each do |args|
85
- rel_op *args
86
- end
70
+ [
71
+ [:~, :__invert__],
72
+ [:+@, :__pos__],
73
+ [:-@, :__neg__]
74
+ ].each do |args|
75
+ unary_op *args
76
+ end
87
77
 
88
- alias :eql? :==
78
+ [
79
+ [:==, 'eq'],
80
+ [:<, 'lt'],
81
+ [:<=, 'le'],
82
+ [:>, 'gt'],
83
+ [:>=, 'ge'],
84
+ [:equal?, 'is_']
85
+ ].each do |args|
86
+ rel_op *args
87
+ end
89
88
 
90
- #Delegates object indexed access to the wrapped Python object.
91
- def [](index)
92
- self.__getitem__ index
93
- end
89
+ # Delegates object indexed access to the wrapped \Python object.
90
+ def [](index)
91
+ self.__getitem__ index
92
+ end
94
93
 
95
- #Delegates setting of various indices to the wrapped Python object.
96
- def []=(index, value)
97
- self.__setitem__ index, value
98
- end
94
+ # Delegates setting of various indices to the wrapped \Python object.
95
+ def []=(index, value)
96
+ self.__setitem__ index, value
97
+ end
99
98
 
100
- #Delegates membership testing to Python.
101
- def include?(item)
102
- self.__contains__(item).rubify
103
- end
99
+ # Delegates membership testing to \Python.
100
+ def include?(item)
101
+ self.__contains__(item).rubify
102
+ end
104
103
 
105
- #Delegates Comparison to Python.
106
- def <=>(other)
107
- PyMain.cmp(self, other)
108
- end
104
+ # Delegates Comparison to \Python.
105
+ def <=>(other)
106
+ RubyPython::PyMain.cmp(self, other)
107
+ end
109
108
 
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
109
+ # Called by RubyPython when the interpreter is started or stopped so that the
110
+ # necessary preparation or cleanup can be done. For internal use only.
111
+ def self.update(status)
112
+ case status
113
+ when :stop
114
+ @@operator = nil
115
115
  end
116
-
117
116
  end
117
+
118
+ # Aliases eql? to == for Python objects.
119
+ alias_method :eql?, :==
118
120
  end
@@ -1,69 +1,66 @@
1
+ require 'ostruct'
2
+
1
3
  module RubyPython
2
- #A hash for storing RubyPython execution options.
4
+ # A hash for storing RubyPython execution options.
3
5
  @options = {}
4
6
 
5
- #A list of options which require the Python library to be reloaded.
6
- NEED_RELOAD = [
7
- :python_exe,
8
- :python_lib
9
- ]
7
+ # A list of options which require the \Python library to be reloaded.
8
+ NEED_RELOAD = [ :python_exe ] #:nodoc
9
+ # 20110316 AZ: This option has been removed because it isn't supported in
10
+ # the current code.
11
+ # :python_lib -> The full path to the python library you wish to load.
10
12
 
11
13
  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
14
+ # Allows one to set options for RubyPython's execution. Parameters may
15
+ # be set either by supplying a hash argument or by supplying a block and
16
+ # calling setters on the provided OpenStruct. Returns a copy of the
17
+ # updated options hash.
18
+ #
19
+ # [options] A Hash of options to set.
22
20
  #
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 }
21
+ # The option currently supported is:
22
+ # [:python_exe] The name of or path to the \Python executable for the
23
+ # version of \Python you wish to use.
24
+ #
25
+ # RubyPython.run do
26
+ # RubyPython.import('sys').version.rubify.to_f # => 2.7
27
+ # end
28
+ #
29
+ # RubyPython.configure :python_exe => 'python2.6'
30
+ # # => { :python_exe => "python2.6" }
31
+ # RubyPython.run do
32
+ # RubyPython.import('sys').version.rubify.to_f # => 2.6
33
+ # end
34
+ #
35
+ # The options hash can also be passed directly to +RubyPython.start+,
36
+ # +RubyPython.session+, or +RubyPython.run+.
37
+ def configure(options = {})
38
+ old_values = Hash[*@options.select { |k, v| NEED_RELOAD.include? k }]
37
39
 
38
40
  if block_given?
39
41
  ostruct = OpenStruct.new @options
40
42
  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]
43
+ olist = ostruct.instance_variable_get('@table').map { |k, v| [ k.to_sym, v ] }
44
+ @options = Hash[*olist]
46
45
  end
47
- @options.merge!(opts)
46
+ @options.merge!(options)
48
47
 
49
48
  @reload = true if NEED_RELOAD.any? { |k| @options[k] != old_values[k] }
50
49
  options
51
50
  end
52
51
 
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
52
+ # Returns a copy of the hash currently being used to determine run
53
+ # options. This allows the user to determine what options have been set.
54
+ # Modification of options should be done via the configure method.
58
55
  def options
59
56
  @options.dup
60
57
  end
61
58
 
62
- #Reset the options hash.
63
- #@return [void]
59
+ # Reset the options hash.
60
+ # @return [void]
64
61
  def clear_options
62
+ @reload = @options.keys.any? { |k| NEED_RELOAD.include? k }
65
63
  @options.clear
66
64
  end
67
-
68
65
  end
69
66
  end