rubypython 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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