rubypython 0.3.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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,185 +1,198 @@
1
1
  require 'ffi'
2
- require 'open3'
3
2
  require 'rubypython/options'
3
+ require 'rubypython/pythonexec'
4
4
 
5
5
  module RubyPython
6
- #Check to see whether the Python Library has been loaded yet. If not
7
- #then we dfer loading the library until this file has been reloaded.
8
- if @loaded
9
- #This module provides access to the Python C API functions via the Ruby ffi
10
- #gem. Documentation for these functions may be found [here](http://docs.python.org/c-api/). Likewise the FFI gem documentation may be found [here](http://rdoc.info/projects/ffi/ffi).
11
- module Python
12
- extend FFI::Library
13
-
14
- PYTHON_EXE = RubyPython.options[:python_exe] || 'python'
15
- # This much we can assume works without anything special at all.
16
- PYTHON_VERSION = Open3.popen3("#{PYTHON_EXE} --version") { |i,o,e| e.read }.chomp.split[1].to_f
17
- PYTHON_NAME = "python#{PYTHON_VERSION}"
18
- LIB_NAME = "#{FFI::Platform::LIBPREFIX}#{PYTHON_NAME}"
19
- LIB_EXT = FFI::Platform::LIBSUFFIX
20
- PYTHON_SYS_PREFIX = %x{#{PYTHON_NAME} -c "import sys; print(sys.prefix)"}.chomp
21
-
22
- # Here's where we run into problems, as not everything works quite the
23
- # way we expect it to.
24
- #
25
- # The default libname will be something like libpython2.6.so (or .dylib)
26
- # or maybe even python2.6.dll on Windows.
27
- libname = "#{LIB_NAME}.#{LIB_EXT}"
28
-
29
- # We may need to look in multiple locations for Python, so let's build
30
- # this as an array.
31
- locations = [ File.join(PYTHON_SYS_PREFIX, "lib", libname) ]
32
-
33
- if FFI::Platform.mac?
34
- # On the Mac, let's add a special case that has even a different
35
- # libname. This may not be fully useful on future versions of OS X,
36
- # but it should work on 10.5 and 10.6. Even if it doesn't, the next
37
- # step will (/usr/lib/libpython<version>.dylib is a symlink to the
38
- # correct location).
39
- locations << File.join(PYTHON_SYS_PREFIX, "Python")
40
- # Let's also look in the location that was originally set in this
41
- # library:
42
- File.join(PYTHON_SYS_PREFIX, "lib", "#{PYTHON_NAME}", "config",
43
- libname)
44
- end
45
-
46
- if FFI::Platform.unix?
47
- # On Unixes, let's look in alternative places, too. Just in case.
48
- locations << File.join("/opt/local/lib", libname)
49
- locations << File.join("/opt/lib", libname)
50
- locations << File.join("/usr/local/lib", libname)
51
- locations << File.join("/usr/lib", libname)
52
- end
53
-
54
- # Get rid of redundant locations.
55
- locations.uniq!
56
-
57
- dyld_flags = FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL
58
- exceptions = []
59
-
60
- locations.each do |location|
61
- begin
62
- @ffi_libs = [ FFI::DynamicLibrary.open(location, dyld_flags) ]
63
- LIB = location
64
- break
65
- rescue LoadError => ex
66
- @ffi_libs = nil
67
- exceptions << ex
68
- end
69
- end
70
-
71
- raise exceptions.first if @ffi_libs.nil?
72
-
73
- #The class is a little bit of a hack to extract the address of global
74
- #structs. If someone knows a better way please let me know.
75
- class DummyStruct < FFI::Struct
76
- layout :dummy_var, :int
77
- end
78
-
79
- #Python interpreter startup and shutdown
80
- attach_function :Py_IsInitialized, [], :int
81
- attach_function :Py_Initialize, [], :void
82
- attach_function :Py_Finalize, [], :void
83
-
84
- #Module methods
85
- attach_function :PyImport_ImportModule, [:string], :pointer
86
-
87
- #Object Methods
88
- attach_function :PyObject_HasAttrString, [:pointer, :string], :int
89
- attach_function :PyObject_GetAttrString, [:pointer, :string], :pointer
90
- attach_function :PyObject_SetAttrString, [:pointer, :string, :pointer], :int
91
-
92
- attach_function :PyObject_Compare, [:pointer, :pointer], :int
93
-
94
- attach_function :PyObject_CallObject, [:pointer, :pointer], :pointer
95
- attach_function :PyCallable_Check, [:pointer], :int
96
-
97
- ###Python To Ruby Conversion
98
- #String Methods
99
- attach_function :PyString_AsString, [:pointer], :string
100
- attach_function :PyString_FromString, [:string], :pointer
101
-
102
- #List Methods
103
- attach_function :PyList_GetItem, [:pointer, :int], :pointer
104
- attach_function :PyList_Size, [:pointer], :int
105
- attach_function :PyList_New, [:int], :pointer
106
- attach_function :PyList_SetItem, [:pointer, :int, :pointer], :void
107
-
108
- #Integer Methods
109
- attach_function :PyInt_AsLong, [:pointer], :long
110
- attach_function :PyInt_FromLong, [:long], :pointer
111
-
112
- attach_function :PyLong_AsLong, [:pointer], :long
113
- attach_function :PyLong_FromLong, [:pointer], :long
114
-
115
- #Float Methods
116
- attach_function :PyFloat_AsDouble, [:pointer], :double
117
- attach_function :PyFloat_FromDouble, [:double], :pointer
118
-
119
- #Tuple Methods
120
- attach_function :PySequence_List, [:pointer], :pointer
121
- attach_function :PySequence_Tuple, [:pointer], :pointer
122
- attach_function :PyTuple_Pack, [:int, :varargs], :pointer
123
-
124
- #Dict/Hash Methods
125
- attach_function :PyDict_Next, [:pointer, :pointer, :pointer, :pointer], :int
126
- attach_function :PyDict_New, [], :pointer
127
- attach_function :PyDict_SetItem, [:pointer, :pointer, :pointer], :int
128
- attach_function :PyDict_Contains, [:pointer, :pointer], :int
129
- attach_function :PyDict_GetItem, [:pointer, :pointer], :pointer
130
-
131
- #Function Constants
132
- METH_VARARGS = 1
133
- attach_function :PyCFunction_New, [:pointer, :pointer], :pointer
134
- callback :PyCFunction, [:pointer, :pointer], :pointer
135
-
136
- #Error Methods
137
- attach_function :PyErr_Fetch, [:pointer, :pointer, :pointer], :void
138
- attach_function :PyErr_Occurred, [], :pointer
139
- attach_function :PyErr_Clear, [], :void
140
-
141
- #Reference Counting
142
- attach_function :Py_IncRef, [:pointer], :void
143
- attach_function :Py_DecRef, [:pointer], :void
144
-
145
- #Type Objects
146
- attach_variable :PyString_Type, DummyStruct.by_value
147
- attach_variable :PyList_Type, DummyStruct.by_value
148
- attach_variable :PyInt_Type, DummyStruct.by_value
149
- attach_variable :PyLong_Type, DummyStruct.by_value
150
- attach_variable :PyFloat_Type, DummyStruct.by_value
151
- attach_variable :PyTuple_Type, DummyStruct.by_value
152
- attach_variable :PyDict_Type, DummyStruct.by_value
153
- attach_variable :PyFunction_Type, DummyStruct.by_value
154
- attach_variable :PyCFunction_Type, DummyStruct.by_value
155
- attach_variable :PyMethod_Type, DummyStruct.by_value
156
- attach_variable :PyType_Type, DummyStruct.by_value
157
- attach_variable :PyClass_Type, DummyStruct.by_value
158
-
159
- attach_variable :Py_TrueStruct, :_Py_TrueStruct, DummyStruct.by_value
160
- attach_variable :Py_ZeroStruct, :_Py_ZeroStruct, DummyStruct.by_value
161
- attach_variable :Py_NoneStruct, :_Py_NoneStruct, DummyStruct.by_value
162
-
163
- #This is an implementation of the basic structure of a Python PyObject
164
- #struct. The C struct is actually much larger, but since we only access
165
- #the first two data members via FFI and always deal with struct pointers
166
- #there is no need to mess around with the rest of the object.
167
- class PyObjectStruct < FFI::Struct
168
- layout :ob_refcnt, :int,
169
- :ob_type, :pointer
170
- end
171
-
172
- #This struct is used when defining Python methods.
173
- class PyMethodDef < FFI::Struct
174
- layout :ml_name, :pointer,
175
- :ml_meth, :PyCFunction,
176
- :ml_flags, :int,
177
- :ml_doc, :pointer
178
- end
6
+ unless defined? PYTHON_RB
7
+ PYTHON_RB = __FILE__
8
+ PYTHON_RB.freeze
9
+ end
10
+
11
+ module Python; end
12
+ end
179
13
 
14
+ if RubyPython.load_ffi?
15
+ # This module provides access to the \Python C API functions via the Ruby
16
+ # FFI gem.
17
+ #
18
+ # === Documentation
19
+ # * {Python C API}[http://docs.python.org/c-api/]
20
+ # * {Ruby FFI}[http://rdoc.info/projects/ffi/ffi]
21
+ module RubyPython::Python # :nodoc: all
22
+ extend FFI::Library
23
+
24
+ EXEC = RubyPython::PythonExec.new(RubyPython.options[:python_exe])
25
+
26
+ PYTHON_LIB = EXEC.library
27
+ # FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL
28
+ ffi_lib_flags :lazy, :global
29
+ ffi_lib EXEC.library
30
+
31
+ # The class is a little bit of a hack to extract the address of global
32
+ # structs. If someone knows a better way please let me know.
33
+ class DummyStruct < FFI::Struct # :nodoc:
34
+ layout :dummy_var, :int
180
35
  end
181
36
 
182
- else
183
- module Python; end
37
+ PY_FILE_INPUT = 257
38
+ PY_EVAL_INPUT = 258
39
+
40
+ # Function methods & constants
41
+ METH_VARARGS = 0x0001
42
+ attach_function :PyCFunction_New, [:pointer, :pointer], :pointer
43
+ callback :PyCFunction, [:pointer, :pointer], :pointer
44
+
45
+ attach_function :PyRun_String, [:string, :int, :pointer, :pointer], :pointer
46
+ attach_function :PyRun_SimpleString, [:string], :pointer
47
+ attach_function :Py_CompileString, [:string, :string, :int], :pointer
48
+ attach_function :PyEval_EvalCode, [:pointer, :pointer, :pointer], :pointer
49
+ attach_function :PyErr_SetString, [:pointer, :string], :void
50
+
51
+ # Python interpreter startup and shutdown
52
+ attach_function :Py_IsInitialized, [], :int
53
+ attach_function :Py_Initialize, [], :void
54
+ attach_function :Py_Finalize, [], :void
55
+
56
+ # Module methods
57
+ attach_function :PyImport_ImportModule, [:string], :pointer
58
+
59
+ # Object Methods
60
+ attach_function :PyObject_HasAttrString, [:pointer, :string], :int
61
+ attach_function :PyObject_GetAttrString, [:pointer, :string], :pointer
62
+ attach_function :PyObject_SetAttrString, [:pointer, :string, :pointer], :int
63
+ attach_function :PyObject_Dir, [:pointer], :pointer
64
+
65
+ attach_function :PyObject_Compare, [:pointer, :pointer], :int
66
+
67
+ attach_function :PyObject_Call, [:pointer, :pointer, :pointer], :pointer
68
+ attach_function :PyObject_CallObject, [:pointer, :pointer], :pointer
69
+ attach_function :PyCallable_Check, [:pointer], :int
70
+
71
+ ### Python To Ruby Conversion
72
+ # String Methods
73
+ attach_function :PyString_AsString, [:pointer], :string
74
+ attach_function :PyString_FromString, [:string], :pointer
75
+ attach_function :PyString_AsStringAndSize, [:pointer, :pointer, :pointer], :int
76
+ attach_function :PyString_FromStringAndSize, [:buffer_in, :ssize_t], :pointer
77
+
78
+ # List Methods
79
+ attach_function :PyList_GetItem, [:pointer, :int], :pointer
80
+ attach_function :PyList_Size, [:pointer], :int
81
+ attach_function :PyList_New, [:int], :pointer
82
+ attach_function :PyList_SetItem, [:pointer, :int, :pointer], :void
83
+
84
+ # Integer Methods
85
+ attach_function :PyInt_AsLong, [:pointer], :long
86
+ attach_function :PyInt_FromLong, [:long], :pointer
87
+
88
+ attach_function :PyLong_AsLong, [:pointer], :long
89
+ attach_function :PyLong_FromLong, [:pointer], :long
90
+
91
+ # Float Methods
92
+ attach_function :PyFloat_AsDouble, [:pointer], :double
93
+ attach_function :PyFloat_FromDouble, [:double], :pointer
94
+
95
+ # Tuple Methods
96
+ attach_function :PySequence_List, [:pointer], :pointer
97
+ attach_function :PySequence_Tuple, [:pointer], :pointer
98
+ attach_function :PyTuple_Pack, [:int, :varargs], :pointer
99
+
100
+ # Dict/Hash Methods
101
+ attach_function :PyDict_Next, [:pointer, :pointer, :pointer, :pointer], :int
102
+ attach_function :PyDict_New, [], :pointer
103
+ attach_function :PyDict_SetItem, [:pointer, :pointer, :pointer], :int
104
+ attach_function :PyDict_Contains, [:pointer, :pointer], :int
105
+ attach_function :PyDict_GetItem, [:pointer, :pointer], :pointer
106
+
107
+ # Error Methods
108
+ attach_variable :PyExc_Exception, DummyStruct.by_ref
109
+ attach_variable :PyExc_StopIteration, DummyStruct.by_ref
110
+ attach_function :PyErr_SetNone, [:pointer], :void
111
+ attach_function :PyErr_Fetch, [:pointer, :pointer, :pointer], :void
112
+ attach_function :PyErr_Occurred, [], :pointer
113
+ attach_function :PyErr_Clear, [], :void
114
+
115
+ # Reference Counting
116
+ attach_function :Py_IncRef, [:pointer], :void
117
+ attach_function :Py_DecRef, [:pointer], :void
118
+
119
+ # Type Objects
120
+ # attach_variable :PyBaseObject_Type, DummyStruct.by_value # built-in 'object'
121
+ # attach_variable :PyBaseString_Type, DummyStruct.by_value
122
+ # attach_variable :PyBool_Type, DummyStruct.by_value
123
+ # attach_variable :PyBuffer_Type, DummyStruct.by_value
124
+ # attach_variable :PyByteArrayIter_Type, DummyStruct.by_value
125
+ # attach_variable :PyByteArray_Type, DummyStruct.by_value
126
+ attach_variable :PyCFunction_Type, DummyStruct.by_value
127
+ # attach_variable :PyCObject_Type, DummyStruct.by_value
128
+ # attach_variable :PyCallIter_Type, DummyStruct.by_value
129
+ # attach_variable :PyCapsule_Type, DummyStruct.by_value
130
+ # attach_variable :PyCell_Type, DummyStruct.by_value
131
+ # attach_variable :PyClassMethod_Type, DummyStruct.by_value
132
+ attach_variable :PyClass_Type, DummyStruct.by_value
133
+ # attach_variable :PyCode_Type, DummyStruct.by_value
134
+ # attach_variable :PyComplex_Type, DummyStruct.by_value
135
+ # attach_variable :PyDictItems_Type, DummyStruct.by_value
136
+ # attach_variable :PyDictIterItem_Type, DummyStruct.by_value
137
+ # attach_variable :PyDictIterKey_Type, DummyStruct.by_value
138
+ # attach_variable :PyDictIterValue_Type, DummyStruct.by_value
139
+ # attach_variable :PyDictKeys_Type, DummyStruct.by_value
140
+ # attach_variable :PyDictProxy_Type, DummyStruct.by_value
141
+ # attach_variable :PyDictValues_Type, DummyStruct.by_value
142
+ attach_variable :PyDict_Type, DummyStruct.by_value
143
+ # attach_variable :PyEllipsis_Type, DummyStruct.by_value
144
+ # attach_variable :PyEnum_Type, DummyStruct.by_value
145
+ # attach_variable :PyFile_Type, DummyStruct.by_value
146
+ attach_variable :PyFloat_Type, DummyStruct.by_value
147
+ # attach_variable :PyFrame_Type, DummyStruct.by_value
148
+ # attach_variable :PyFrozenSet_Type, DummyStruct.by_value
149
+ attach_variable :PyFunction_Type, DummyStruct.by_value
150
+ # attach_variable :PyGen_Type, DummyStruct.by_value
151
+ # attach_variable :PyGetSetDescr_Type, DummyStruct.by_value
152
+ # attach_variable :PyInstance_Type, DummyStruct.by_value
153
+ attach_variable :PyInt_Type, DummyStruct.by_value
154
+ attach_variable :PyList_Type, DummyStruct.by_value
155
+ attach_variable :PyLong_Type, DummyStruct.by_value
156
+ # attach_variable :PyMemberDescr_Type, DummyStruct.by_value
157
+ # attach_variable :PyMemoryView_Type, DummyStruct.by_value
158
+ attach_variable :PyMethod_Type, DummyStruct.by_value
159
+ # attach_variable :PyModule_Type, DummyStruct.by_value
160
+ # attach_variable :PyNullImporter_Type, DummyStruct.by_value
161
+ # attach_variable :PyProperty_Type, DummyStruct.by_value
162
+ # attach_variable :PyRange_Type, DummyStruct.by_value
163
+ # attach_variable :PyReversed_Type, DummyStruct.by_value
164
+ # attach_variable :PySTEntry_Type, DummyStruct.by_value
165
+ # attach_variable :PySeqIter_Type, DummyStruct.by_value
166
+ # attach_variable :PySet_Type, DummyStruct.by_value
167
+ # attach_variable :PySlice_Type, DummyStruct.by_value
168
+ # attach_variable :PyStaticMethod_Type, DummyStruct.by_value
169
+ attach_variable :PyString_Type, DummyStruct.by_value
170
+ # attach_variable :PySuper_Type, DummyStruct.by_value # built-in 'super'
171
+ # attach_variable :PyTraceBack_Type, DummyStruct.by_value
172
+ attach_variable :PyTuple_Type, DummyStruct.by_value
173
+ attach_variable :PyType_Type, DummyStruct.by_value
174
+ # attach_variable :PyUnicode_Type, DummyStruct.by_value
175
+ # attach_variable :PyWrapperDescr_Type, DummyStruct.by_value
176
+
177
+ attach_variable :Py_TrueStruct, :_Py_TrueStruct, DummyStruct.by_value
178
+ attach_variable :Py_ZeroStruct, :_Py_ZeroStruct, DummyStruct.by_value
179
+ attach_variable :Py_NoneStruct, :_Py_NoneStruct, DummyStruct.by_value
180
+
181
+ # This is an implementation of the basic structure of a Python PyObject
182
+ # struct. The C struct is actually much larger, but since we only access
183
+ # the first two data members via FFI and always deal with struct
184
+ # pointers there is no need to mess around with the rest of the object.
185
+ class PyObjectStruct < FFI::Struct
186
+ layout :ob_refcnt, :ssize_t,
187
+ :ob_type, :pointer
188
+ end
189
+
190
+ # This struct is used when defining Python methods.
191
+ class PyMethodDef < FFI::Struct
192
+ layout :ml_name, :pointer,
193
+ :ml_meth, :PyCFunction,
194
+ :ml_flags, :int,
195
+ :ml_doc, :pointer
196
+ end
184
197
  end
185
198
  end
@@ -1,78 +1,69 @@
1
1
  require 'rubypython/python'
2
2
  require 'rubypython/macros'
3
3
 
4
+ # Raised when an error occurs in the \Python interpreter.
5
+ class RubyPython::PythonError < RuntimeError
6
+ # Creates the PythonError.
7
+ # [typeName] The class name of the \Python error.
8
+ # [msg] The message attached to the \Python error.
9
+ def initialize(typeName, msg)
10
+ @type = typeName
11
+ super([typeName, msg].join(': '))
12
+ end
4
13
 
5
- module RubyPython
6
-
7
- #Raised when an error occurs in the Python interpreter.
8
- class PythonError < Exception
9
-
10
- #@param [String] typeName the class name of the Python error
11
- #@param [String] msg the message attached to the Python error
12
- def initialize(typeName, msg)
13
- @type = typeName
14
- super([typeName, msg].join(': '))
15
- end
16
-
17
- #This method should be called when an error has occured in the
18
- #Python interpreter. This acts as factory function for PythonError
19
- #objects. The function fetchs calls {fetch} to get the error
20
- #information from the Python interpreter and uses this to build
21
- #a PythonError object. It then calls {clear} to clear the error
22
- #flag of the python interpreter
23
- #@return [PythonError] an error enscapsulating the Python error
24
- def self.handle_error
25
- rbType, rbValue, rbTraceback = fetch()
26
-
27
- if not rbValue.null?
28
- msg = rbValue.getAttr("__str__").callObject PyObject.buildArgTuple
29
- msg = msg.rubify
30
- else
31
- msg = nil
32
- end
33
-
34
- #Decrease the reference count. This will happen anyway when they go
35
- #out of scope but might as well.
36
- rbValue.xDecref
37
- rbTraceback.xDecref
38
- pyName = rbType.getAttr("__name__")
14
+ # This method should be called when an error has occurred in the \Python
15
+ # interpreter. This acts as factory function for PythonError objects. The
16
+ # function fetches calls +#fetch+ to get the error information from the
17
+ # \Python interpreter and uses this to build a PythonError object. It then
18
+ # calls +#clear to clear the error flag in the python interpreter. After
19
+ # the error flag has been cleared, the PythonError object is returned.
20
+ def self.handle_error
21
+ rbType, rbValue, rbTraceback = fetch()
39
22
 
40
- rbType.xDecref
41
- rbName = pyName.rubify
42
- pyName.xDecref
23
+ if not rbValue.null?
24
+ msg = rbValue.getAttr("__str__").callObject RubyPython::PyObject.buildArgTuple
25
+ msg = msg.rubify
26
+ else
27
+ msg = nil
28
+ end
43
29
 
44
- PythonError.clear
30
+ # Decrease the reference count. This will happen anyway when they go out
31
+ # of scope but might as well.
32
+ rbValue.xDecref
33
+ rbTraceback.xDecref
34
+ pyName = rbType.getAttr("__name__")
45
35
 
46
- PythonError.new(rbName, msg)
47
- end
36
+ rbType.xDecref
37
+ rbName = pyName.rubify
38
+ pyName.xDecref
48
39
 
49
- #A wrapper to the Python C API PyErr_Fetch function.
50
- #@return [Array<PyObject>] an array containing three {PyObject} instances.
51
- # representing the Type, Value, and stacktrace of the python
52
- # error respectively.
53
- def self.fetch
54
- typePointer = FFI::MemoryPointer.new :pointer
55
- valuePointer = FFI::MemoryPointer.new :pointer
56
- tracebackPointer = FFI::MemoryPointer.new :pointer
40
+ RubyPython::PythonError.clear
41
+ RubyPython::PythonError.new(rbName, msg)
42
+ end
57
43
 
58
- Python.PyErr_Fetch typePointer, valuePointer, tracebackPointer
44
+ # A wrapper to the \Python C API +PyErr_Fetch+ function. Returns an array
45
+ # with three PyObject instances, representing the Type, the Value, and the
46
+ # stack trace of the Python error.
47
+ def self.fetch
48
+ typePointer = FFI::MemoryPointer.new :pointer
49
+ valuePointer = FFI::MemoryPointer.new :pointer
50
+ tracebackPointer = FFI::MemoryPointer.new :pointer
59
51
 
60
- rbType = PyObject.new typePointer.read_pointer
61
- rbValue = PyObject.new valuePointer.read_pointer
62
- rbTraceback = PyObject.new tracebackPointer.read_pointer
63
- [rbType, rbValue, rbTraceback]
64
- end
52
+ RubyPython::Python.PyErr_Fetch typePointer, valuePointer, tracebackPointer
65
53
 
66
- #Determines whether an error has occured in the python interpreter.
67
- def self.error?
68
- !Python.PyErr_Occurred.null?
69
- end
54
+ rbType = RubyPython::PyObject.new typePointer.read_pointer
55
+ rbValue = RubyPython::PyObject.new valuePointer.read_pointer
56
+ rbTraceback = RubyPython::PyObject.new tracebackPointer.read_pointer
57
+ [rbType, rbValue, rbTraceback]
58
+ end
70
59
 
71
- #Resets the Python interpreter error flag
72
- #@return [void]
73
- def self.clear
74
- Python.PyErr_Clear
75
- end
60
+ # Determines whether an error has occurred in the \Python interpreter.
61
+ def self.error?
62
+ !RubyPython::Python.PyErr_Occurred.null?
63
+ end
76
64
 
65
+ # Resets the \Python interpreter error flag
66
+ def self.clear
67
+ RubyPython::Python.PyErr_Clear
77
68
  end
78
69
  end