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
data/lib/rubypython/legacy.rb
CHANGED
@@ -1,39 +1,38 @@
|
|
1
1
|
require 'rubypython'
|
2
2
|
|
3
|
-
#A quick way to
|
4
|
-
#'rubypython/legacy' automatically activates legacy_mode
|
5
|
-
#
|
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
|
-
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
# Enables +RubyPython.legacy_mode+.
|
29
|
+
def self.setup_legacy
|
30
|
+
RubyPython.legacy_mode = true
|
31
|
+
end
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
# Disables +RubyPython.legacy_mode+.
|
34
|
+
def self.teardown_legacy
|
35
|
+
RubyPython.legacy_mode = false
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
data/lib/rubypython/macros.rb
CHANGED
@@ -1,47 +1,56 @@
|
|
1
1
|
require 'ffi'
|
2
2
|
require 'rubypython/python'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
25
|
-
|
23
|
+
[ pTypePointer ].flatten.each do |pointer|
|
24
|
+
return 1 if type == pointer
|
26
25
|
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
27
|
+
return 0
|
28
|
+
end
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
30
|
+
def self.Py_True
|
31
|
+
RubyPython::Python.Py_TrueStruct.to_ptr
|
32
|
+
end
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
34
|
+
def self.Py_False
|
35
|
+
RubyPython::Python.Py_ZeroStruct.to_ptr
|
36
|
+
end
|
41
37
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
data/lib/rubypython/operators.rb
CHANGED
@@ -1,118 +1,120 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
module
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
71
|
-
|
72
|
-
|
73
|
-
]
|
74
|
-
|
75
|
-
|
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
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
-
|
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
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
89
|
+
# Delegates object indexed access to the wrapped \Python object.
|
90
|
+
def [](index)
|
91
|
+
self.__getitem__ index
|
92
|
+
end
|
94
93
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
99
|
+
# Delegates membership testing to \Python.
|
100
|
+
def include?(item)
|
101
|
+
self.__contains__(item).rubify
|
102
|
+
end
|
104
103
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
104
|
+
# Delegates Comparison to \Python.
|
105
|
+
def <=>(other)
|
106
|
+
RubyPython::PyMain.cmp(self, other)
|
107
|
+
end
|
109
108
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
data/lib/rubypython/options.rb
CHANGED
@@ -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
|
-
|
8
|
-
|
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
|
-
#
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
#
|
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
|
-
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
|
36
|
-
|
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
|
-
|
42
|
-
|
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!(
|
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
|
-
#
|
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
|
-
|
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
|