rubypython 0.5.3 → 0.6.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.
@@ -1,29 +1,8 @@
1
1
  require 'rubypython'
2
2
 
3
- # A quick way to active <em>Legacy Mode</em> for a project. Requiring
3
+ # A quick way to activate <em>Legacy Mode</em> for a project. Requiring
4
4
  # +'rubypython/legacy' automatically activates +RubyPython.legacy_mode+ on
5
- # the project.
6
- #
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
5
+ # the project. This mode is deprecated and will be removed.
27
6
  module RubyPython::LegacyMode
28
7
  # Enables +RubyPython.legacy_mode+.
29
8
  def self.setup_legacy
@@ -106,13 +106,17 @@ module RubyPython::Operators
106
106
  RubyPython::PyMain.cmp(self, other)
107
107
  end
108
108
 
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
109
+ class << self
110
+ # Called by RubyPython when the interpreter is started or stopped so
111
+ # that the necessary preparation or cleanup can be done. For internal
112
+ # use only.
113
+ def python_interpreter_update(status)
114
+ case status
115
+ when :stop
116
+ @@operator = nil
117
+ end
115
118
  end
119
+ private :python_interpreter_update
116
120
  end
117
121
 
118
122
  # Aliases eql? to == for Python objects.
@@ -63,15 +63,16 @@ module RubyPython
63
63
  end
64
64
 
65
65
  # Called by RubyPython when the interpreter is started or stopped so
66
- # that the neccesary preperation or cleanup can be done. For internal
66
+ # that the neccesary preparation or cleanup can be done. For internal
67
67
  # use only.
68
- def update(status)
68
+ def python_interpreter_update(status)
69
69
  case status
70
70
  when :stop
71
71
  @main = nil
72
72
  @builtin = nil
73
73
  end
74
74
  end
75
+ private :python_interpreter_update
75
76
  end
76
77
 
77
78
  # The accessible instance of PyMainClass.
@@ -35,12 +35,13 @@ class RubyPython::PyObject # :nodoc: all
35
35
  # Called by RubyPython when the interpreter is started or stopped so
36
36
  # that the necessary preparation or cleanup can be done. For internal
37
37
  # use only.
38
- def update(status)
38
+ def python_interpreter_update(status)
39
39
  case status
40
40
  when :stop
41
41
  current_pointers.clear
42
42
  end
43
43
  end
44
+ private :python_interpreter_update
44
45
  end
45
46
 
46
47
  self.current_pointers = {}
@@ -1,198 +1,195 @@
1
1
  require 'ffi'
2
- require 'rubypython/options'
3
- require 'rubypython/pythonexec'
2
+ require 'thread'
3
+ require 'rubypython/interpreter'
4
4
 
5
5
  module RubyPython
6
- unless defined? PYTHON_RB
7
- PYTHON_RB = __FILE__
8
- PYTHON_RB.freeze
6
+ # This module will hold the loaded RubyPython interpreter.
7
+ module Python #:nodoc: all
9
8
  end
10
-
11
- module Python; end
12
9
  end
13
10
 
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
35
- end
36
-
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
11
+ class RubyPython::Interpreter
12
+ # Infects the provided module with the Python FFI. Once a single module
13
+ # has been infected, the #infect! method is removed from
14
+ # RubyPython::Interpreter.
15
+ def infect!(mod)
16
+ Mutex.new.synchronize do
17
+ self.class.class_eval do
18
+ undef :infect!
19
+ end
20
+
21
+ mod.extend FFI::Library
22
+ # FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL
23
+ mod.ffi_lib_flags :lazy, :global
24
+ mod.ffi_lib self.library
25
+
26
+ # This class is a little bit of a hack to extract the address of
27
+ # global structs. If someone knows a better way please let me know.
28
+ mod.module_eval do
29
+ self.const_set :DummyStruct, Class.new(FFI::Struct)
30
+ self::DummyStruct.layout :dummy_var, :int
31
+
32
+ self.const_set(:PY_FILE_INPUT, 257)
33
+ self.const_set(:PY_EVAL_INPUT, 258)
34
+ self.const_set(:METH_VARARGS, 0x0001)
35
+
36
+ # Function methods & constants
37
+ attach_function :PyCFunction_New, [:pointer, :pointer], :pointer
38
+ callback :PyCFunction, [:pointer, :pointer], :pointer
39
+
40
+ attach_function :PyRun_String, [:string, :int, :pointer, :pointer], :pointer
41
+ attach_function :PyRun_SimpleString, [:string], :pointer
42
+ attach_function :Py_CompileString, [:string, :string, :int], :pointer
43
+ attach_function :PyEval_EvalCode, [:pointer, :pointer, :pointer], :pointer
44
+ attach_function :PyErr_SetString, [:pointer, :string], :void
45
+
46
+ # Python interpreter startup and shutdown
47
+ attach_function :Py_IsInitialized, [], :int
48
+ attach_function :Py_Initialize, [], :void
49
+ attach_function :Py_Finalize, [], :void
50
+
51
+ # Module methods
52
+ attach_function :PyImport_ImportModule, [:string], :pointer
53
+
54
+ # Object Methods
55
+ attach_function :PyObject_HasAttrString, [:pointer, :string], :int
56
+ attach_function :PyObject_GetAttrString, [:pointer, :string], :pointer
57
+ attach_function :PyObject_SetAttrString, [:pointer, :string, :pointer], :int
58
+ attach_function :PyObject_Dir, [:pointer], :pointer
59
+
60
+ attach_function :PyObject_Compare, [:pointer, :pointer], :int
61
+
62
+ attach_function :PyObject_Call, [:pointer, :pointer, :pointer], :pointer
63
+ attach_function :PyObject_CallObject, [:pointer, :pointer], :pointer
64
+ attach_function :PyCallable_Check, [:pointer], :int
65
+
66
+ ### Python To Ruby Conversion
67
+ # String Methods
68
+ attach_function :PyString_AsString, [:pointer], :string
69
+ attach_function :PyString_FromString, [:string], :pointer
70
+ attach_function :PyString_AsStringAndSize, [:pointer, :pointer, :pointer], :int
71
+ attach_function :PyString_FromStringAndSize, [:buffer_in, :ssize_t], :pointer
72
+
73
+ # List Methods
74
+ attach_function :PyList_GetItem, [:pointer, :int], :pointer
75
+ attach_function :PyList_Size, [:pointer], :int
76
+ attach_function :PyList_New, [:int], :pointer
77
+ attach_function :PyList_SetItem, [:pointer, :int, :pointer], :void
78
+
79
+ # Integer Methods
80
+ attach_function :PyInt_AsLong, [:pointer], :long
81
+ attach_function :PyInt_FromLong, [:long], :pointer
82
+
83
+ attach_function :PyLong_AsLong, [:pointer], :long
84
+ attach_function :PyLong_FromLong, [:pointer], :long
85
+
86
+ # Float Methods
87
+ attach_function :PyFloat_AsDouble, [:pointer], :double
88
+ attach_function :PyFloat_FromDouble, [:double], :pointer
89
+
90
+ # Tuple Methods
91
+ attach_function :PySequence_List, [:pointer], :pointer
92
+ attach_function :PySequence_Tuple, [:pointer], :pointer
93
+ attach_function :PyTuple_Pack, [:int, :varargs], :pointer
94
+
95
+ # Dict/Hash Methods
96
+ attach_function :PyDict_Next, [:pointer, :pointer, :pointer, :pointer], :int
97
+ attach_function :PyDict_New, [], :pointer
98
+ attach_function :PyDict_SetItem, [:pointer, :pointer, :pointer], :int
99
+ attach_function :PyDict_Contains, [:pointer, :pointer], :int
100
+ attach_function :PyDict_GetItem, [:pointer, :pointer], :pointer
101
+
102
+ # Error Methods
103
+ attach_variable :PyExc_Exception, self::DummyStruct.by_ref
104
+ attach_variable :PyExc_StopIteration, self::DummyStruct.by_ref
105
+ attach_function :PyErr_SetNone, [:pointer], :void
106
+ attach_function :PyErr_Fetch, [:pointer, :pointer, :pointer], :void
107
+ attach_function :PyErr_Occurred, [], :pointer
108
+ attach_function :PyErr_Clear, [], :void
109
+
110
+ # Reference Counting
111
+ attach_function :Py_IncRef, [:pointer], :void
112
+ attach_function :Py_DecRef, [:pointer], :void
113
+
114
+ # Type Objects
115
+ # attach_variable :PyBaseObject_Type, self::DummyStruct.by_value # built-in 'object'
116
+ # attach_variable :PyBaseString_Type, self::DummyStruct.by_value
117
+ # attach_variable :PyBool_Type, self::DummyStruct.by_value
118
+ # attach_variable :PyBuffer_Type, self::DummyStruct.by_value
119
+ # attach_variable :PyByteArrayIter_Type, self::DummyStruct.by_value
120
+ # attach_variable :PyByteArray_Type, self::DummyStruct.by_value
121
+ attach_variable :PyCFunction_Type, self::DummyStruct.by_value
122
+ # attach_variable :PyCObject_Type, self::DummyStruct.by_value
123
+ # attach_variable :PyCallIter_Type, self::DummyStruct.by_value
124
+ # attach_variable :PyCapsule_Type, self::DummyStruct.by_value
125
+ # attach_variable :PyCell_Type, self::DummyStruct.by_value
126
+ # attach_variable :PyClassMethod_Type, self::DummyStruct.by_value
127
+ attach_variable :PyClass_Type, self::DummyStruct.by_value
128
+ # attach_variable :PyCode_Type, self::DummyStruct.by_value
129
+ # attach_variable :PyComplex_Type, self::DummyStruct.by_value
130
+ # attach_variable :PyDictItems_Type, self::DummyStruct.by_value
131
+ # attach_variable :PyDictIterItem_Type, self::DummyStruct.by_value
132
+ # attach_variable :PyDictIterKey_Type, self::DummyStruct.by_value
133
+ # attach_variable :PyDictIterValue_Type, self::DummyStruct.by_value
134
+ # attach_variable :PyDictKeys_Type, self::DummyStruct.by_value
135
+ # attach_variable :PyDictProxy_Type, self::DummyStruct.by_value
136
+ # attach_variable :PyDictValues_Type, self::DummyStruct.by_value
137
+ attach_variable :PyDict_Type, self::DummyStruct.by_value
138
+ # attach_variable :PyEllipsis_Type, self::DummyStruct.by_value
139
+ # attach_variable :PyEnum_Type, self::DummyStruct.by_value
140
+ # attach_variable :PyFile_Type, self::DummyStruct.by_value
141
+ attach_variable :PyFloat_Type, self::DummyStruct.by_value
142
+ # attach_variable :PyFrame_Type, self::DummyStruct.by_value
143
+ # attach_variable :PyFrozenSet_Type, self::DummyStruct.by_value
144
+ attach_variable :PyFunction_Type, self::DummyStruct.by_value
145
+ # attach_variable :PyGen_Type, self::DummyStruct.by_value
146
+ # attach_variable :PyGetSetDescr_Type, self::DummyStruct.by_value
147
+ # attach_variable :PyInstance_Type, self::DummyStruct.by_value
148
+ attach_variable :PyInt_Type, self::DummyStruct.by_value
149
+ attach_variable :PyList_Type, self::DummyStruct.by_value
150
+ attach_variable :PyLong_Type, self::DummyStruct.by_value
151
+ # attach_variable :PyMemberDescr_Type, self::DummyStruct.by_value
152
+ # attach_variable :PyMemoryView_Type, self::DummyStruct.by_value
153
+ attach_variable :PyMethod_Type, self::DummyStruct.by_value
154
+ # attach_variable :PyModule_Type, self::DummyStruct.by_value
155
+ # attach_variable :PyNullImporter_Type, self::DummyStruct.by_value
156
+ # attach_variable :PyProperty_Type, self::DummyStruct.by_value
157
+ # attach_variable :PyRange_Type, self::DummyStruct.by_value
158
+ # attach_variable :PyReversed_Type, self::DummyStruct.by_value
159
+ # attach_variable :PySTEntry_Type, self::DummyStruct.by_value
160
+ # attach_variable :PySeqIter_Type, self::DummyStruct.by_value
161
+ # attach_variable :PySet_Type, self::DummyStruct.by_value
162
+ # attach_variable :PySlice_Type, self::DummyStruct.by_value
163
+ # attach_variable :PyStaticMethod_Type, self::DummyStruct.by_value
164
+ attach_variable :PyString_Type, self::DummyStruct.by_value
165
+ # attach_variable :PySuper_Type, self::DummyStruct.by_value # built-in 'super'
166
+ # attach_variable :PyTraceBack_Type, self::DummyStruct.by_value
167
+ attach_variable :PyTuple_Type, self::DummyStruct.by_value
168
+ attach_variable :PyType_Type, self::DummyStruct.by_value
169
+ # attach_variable :PyUnicode_Type, self::DummyStruct.by_value
170
+ # attach_variable :PyWrapperDescr_Type, self::DummyStruct.by_value
171
+
172
+ attach_variable :Py_TrueStruct, :_Py_TrueStruct, self::DummyStruct.by_value
173
+ attach_variable :Py_ZeroStruct, :_Py_ZeroStruct, self::DummyStruct.by_value
174
+ attach_variable :Py_NoneStruct, :_Py_NoneStruct, self::DummyStruct.by_value
175
+
176
+ # This is an implementation of the basic structure of a Python PyObject
177
+ # struct. The C struct is actually much larger, but since we only access
178
+ # the first two data members via FFI and always deal with struct
179
+ # pointers there is no need to mess around with the rest of the object.
180
+ self.const_set :PyObjectStruct, Class.new(FFI::Struct)
181
+ self::PyObjectStruct.layout :ob_refcnt, :ssize_t,
182
+ :ob_type, :pointer
183
+
184
+ # This struct is used when defining Python methods.
185
+ self.const_set :PyMethodDef, Class.new(FFI::Struct)
186
+ self::PyMethodDef.layout :ml_name, :pointer,
187
+ :ml_meth, :PyCFunction,
188
+ :ml_flags, :int,
189
+ :ml_doc, :pointer
190
+ end
189
191
 
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
192
  end
197
193
  end
194
+ private :infect!
198
195
  end