Cython has moved to github.

cython-devel

view Cython/Compiler/TypeSlots.py @ 3091:1a2e04bc1395

remove dependency on structmember.h
author Lisandro Dalcin <dalcinl@gmail.com>
date Thu Mar 11 17:21:13 2010 -0300 (2 years ago)
parents 3650762cf138
children 07dd946da241
line source
1 #
2 # Pyrex - Tables describing slots in the type object
3 # and associated know-how.
4 #
6 import Naming
7 import PyrexTypes
8 import StringEncoding
9 import sys
11 class Signature(object):
12 # Method slot signature descriptor.
13 #
14 # has_dummy_arg boolean
15 # has_generic_args boolean
16 # fixed_arg_format string
17 # ret_format string
18 # error_value string
19 #
20 # The formats are strings made up of the following
21 # characters:
22 #
23 # 'O' Python object
24 # 'T' Python object of the type of 'self'
25 # 'v' void
26 # 'p' void *
27 # 'P' void **
28 # 'i' int
29 # 'b' bint
30 # 'I' int *
31 # 'l' long
32 # 'Z' Py_ssize_t
33 # 's' char *
34 # 'S' char **
35 # 'r' int used only to signal exception
36 # 'B' Py_buffer *
37 # '-' dummy 'self' argument (not used)
38 # '*' rest of args passed as generic Python
39 # arg tuple and kw dict (must be last
40 # char in format string)
42 format_map = {
43 'O': PyrexTypes.py_object_type,
44 'v': PyrexTypes.c_void_type,
45 'p': PyrexTypes.c_void_ptr_type,
46 'P': PyrexTypes.c_void_ptr_ptr_type,
47 'i': PyrexTypes.c_int_type,
48 'b': PyrexTypes.c_bint_type,
49 'I': PyrexTypes.c_int_ptr_type,
50 'l': PyrexTypes.c_long_type,
51 'Z': PyrexTypes.c_py_ssize_t_type,
52 's': PyrexTypes.c_char_ptr_type,
53 'S': PyrexTypes.c_char_ptr_ptr_type,
54 'r': PyrexTypes.c_returncode_type,
55 'B': PyrexTypes.c_py_buffer_ptr_type,
56 # 'T', '-' and '*' are handled otherwise
57 # and are not looked up in here
58 }
60 error_value_map = {
61 'O': "NULL",
62 'i': "-1",
63 'b': "-1",
64 'l': "-1",
65 'r': "-1",
66 'Z': "-1",
67 }
69 def __init__(self, arg_format, ret_format):
70 self.has_dummy_arg = 0
71 self.has_generic_args = 0
72 if arg_format[:1] == '-':
73 self.has_dummy_arg = 1
74 arg_format = arg_format[1:]
75 if arg_format[-1:] == '*':
76 self.has_generic_args = 1
77 arg_format = arg_format[:-1]
78 self.fixed_arg_format = arg_format
79 self.ret_format = ret_format
80 self.error_value = self.error_value_map.get(ret_format, None)
82 def num_fixed_args(self):
83 return len(self.fixed_arg_format)
85 def is_self_arg(self, i):
86 # argument is 'self' for methods or 'class' for classmethods
87 return self.fixed_arg_format[i] == 'T'
89 def fixed_arg_type(self, i):
90 return self.format_map[self.fixed_arg_format[i]]
92 def return_type(self):
93 return self.format_map[self.ret_format]
95 def exception_value(self):
96 return self.error_value_map.get(self.ret_format)
98 def function_type(self):
99 # Construct a C function type descriptor for this signature
100 args = []
101 for i in xrange(self.num_fixed_args()):
102 arg_type = self.fixed_arg_type(i)
103 args.append(PyrexTypes.CFuncTypeArg("", arg_type, None))
104 ret_type = self.return_type()
105 exc_value = self.exception_value()
106 return PyrexTypes.CFuncType(ret_type, args, exception_value = exc_value)
108 def method_flags(self):
109 if self.ret_format == "O":
110 full_args = self.fixed_arg_format
111 if self.has_dummy_arg:
112 full_args = "O" + full_args
113 if full_args in ["O", "T"]:
114 if self.has_generic_args:
115 return [method_varargs, method_keywords]
116 else:
117 return [method_noargs]
118 elif full_args in ["OO", "TO"] and not self.has_generic_args:
119 return [method_onearg]
120 return None
123 class SlotDescriptor(object):
124 # Abstract base class for type slot descriptors.
125 #
126 # slot_name string Member name of the slot in the type object
127 # is_initialised_dynamically Is initialised by code in the module init function
128 # flag Py_TPFLAGS_XXX value indicating presence of slot
129 # py3k Indicates presence of slot in Python 3
130 # py2 Indicates presence of slot in Python 2
131 # ifdef Full #ifdef string that slot is wrapped in. Using this causes py3k, py2 and flags to be ignored.)
133 def __init__(self, slot_name, dynamic = 0, flag = None, py3k = True, py2 = True, ifdef = None):
134 self.slot_name = slot_name
135 self.is_initialised_dynamically = dynamic
136 self.flag = flag
137 self.py3k = py3k
138 self.py2 = py2
139 self.ifdef = ifdef
141 def generate(self, scope, code):
142 if self.is_initialised_dynamically:
143 value = 0
144 else:
145 value = self.slot_code(scope)
146 flag = self.flag
147 py3k = self.py3k
148 py2 = self.py2
149 if self.ifdef:
150 code.putln("#if %s" % self.ifdef)
151 else:
152 if not py3k:
153 code.putln("#if PY_MAJOR_VERSION < 3")
154 elif not py2:
155 code.putln("#if PY_MAJOR_VERSION >= 3")
156 if flag:
157 code.putln("#if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & %s)" % flag)
158 if py3k == '<RESERVED>':
159 code.putln("#if PY_MAJOR_VERSION >= 3")
160 code.putln("0, /*reserved*/")
161 code.putln("#else")
163 code.putln("%s, /*%s*/" % (value, self.slot_name))
164 if py3k == '<RESERVED>':
165 code.putln("#endif")
166 if flag or (not py3k or not py2) or self.ifdef:
167 code.putln("#endif")
169 # Some C implementations have trouble statically
170 # initialising a global with a pointer to an extern
171 # function, so we initialise some of the type slots
172 # in the module init function instead.
174 def generate_dynamic_init_code(self, scope, code):
175 if self.is_initialised_dynamically:
176 value = self.slot_code(scope)
177 if value != "0":
178 code.putln("%s.%s = %s;" % (
179 scope.parent_type.typeobj_cname,
180 self.slot_name,
181 value
182 )
183 )
186 class FixedSlot(SlotDescriptor):
187 # Descriptor for a type slot with a fixed value.
188 #
189 # value string
191 def __init__(self, slot_name, value, py3k=True, py2=True, ifdef=None):
192 SlotDescriptor.__init__(self, slot_name, py3k=py3k, py2=py2, ifdef=ifdef)
193 self.value = value
195 def slot_code(self, scope):
196 return self.value
199 class EmptySlot(FixedSlot):
200 # Descriptor for a type slot whose value is always 0.
202 def __init__(self, slot_name, py3k=True, py2=True, ifdef=None):
203 FixedSlot.__init__(self, slot_name, "0", py3k=py3k, py2=py2, ifdef=ifdef)
206 class MethodSlot(SlotDescriptor):
207 # Type slot descriptor for a user-definable method.
208 #
209 # signature Signature
210 # method_name string The __xxx__ name of the method
211 # default string or None Default value of the slot
213 def __init__(self, signature, slot_name, method_name, default = None, flag = None, py3k=True, py2=True, ifdef=None):
214 SlotDescriptor.__init__(self, slot_name, flag = flag, py3k = py3k, py2=py2, ifdef=ifdef)
215 self.signature = signature
216 self.slot_name = slot_name
217 self.method_name = method_name
218 self.default = default
219 method_name_to_slot[method_name] = self
221 def slot_code(self, scope):
222 entry = scope.lookup_here(self.method_name)
223 if entry and entry.func_cname:
224 return entry.func_cname
225 if self.default is not None:
226 entry = scope.lookup_here(self.default)
227 if entry and entry.func_cname:
228 return entry.func_cname
229 return "0"
232 class InternalMethodSlot(SlotDescriptor):
233 # Type slot descriptor for a method which is always
234 # synthesized by Cython.
235 #
236 # slot_name string Member name of the slot in the type object
238 def __init__(self, slot_name, py2 = True):
239 SlotDescriptor.__init__(self, slot_name, py2 = py2)
241 def slot_code(self, scope):
242 return scope.mangle_internal(self.slot_name)
245 class GCDependentSlot(InternalMethodSlot):
246 # Descriptor for a slot whose value depends on whether
247 # the type participates in GC.
249 def __init__(self, slot_name):
250 InternalMethodSlot.__init__(self, slot_name)
252 def slot_code(self, scope):
253 if not scope.needs_gc():
254 return "0"
255 if not scope.has_pyobject_attrs:
256 # if the type does not have object attributes, it can
257 # delegate GC methods to its parent - iff the parent
258 # functions are defined in the same module
259 parent_type_scope = scope.parent_type.base_type.scope
260 if scope.parent_scope is parent_type_scope.parent_scope:
261 entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name)
262 if entry.visibility != 'extern':
263 return self.slot_code(parent_type_scope)
264 return InternalMethodSlot.slot_code(self, scope)
267 class ConstructorSlot(InternalMethodSlot):
268 # Descriptor for tp_new and tp_dealloc.
270 def __init__(self, slot_name, method):
271 InternalMethodSlot.__init__(self, slot_name)
272 self.method = method
274 def slot_code(self, scope):
275 if scope.parent_type.base_type \
276 and not scope.has_pyobject_attrs \
277 and not scope.lookup_here(self.method):
278 # if the type does not have object attributes, it can
279 # delegate GC methods to its parent - iff the parent
280 # functions are defined in the same module
281 parent_type_scope = scope.parent_type.base_type.scope
282 if scope.parent_scope is parent_type_scope.parent_scope:
283 entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name)
284 if entry.visibility != 'extern':
285 return self.slot_code(parent_type_scope)
286 return InternalMethodSlot.slot_code(self, scope)
289 class SyntheticSlot(InternalMethodSlot):
290 # Type slot descriptor for a synthesized method which
291 # dispatches to one or more user-defined methods depending
292 # on its arguments. If none of the relevant methods are
293 # defined, the method will not be synthesized and an
294 # alternative default value will be placed in the type
295 # slot.
297 def __init__(self, slot_name, user_methods, default_value, py2 = True):
298 InternalMethodSlot.__init__(self, slot_name, py2 = py2)
299 self.user_methods = user_methods
300 self.default_value = default_value
302 def slot_code(self, scope):
303 if scope.defines_any(self.user_methods):
304 return InternalMethodSlot.slot_code(self, scope)
305 else:
306 return self.default_value
309 class TypeFlagsSlot(SlotDescriptor):
310 # Descriptor for the type flags slot.
312 def slot_code(self, scope):
313 value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_NEWBUFFER"
314 if scope.needs_gc():
315 value += "|Py_TPFLAGS_HAVE_GC"
316 return value
319 class DocStringSlot(SlotDescriptor):
320 # Descriptor for the docstring slot.
322 def slot_code(self, scope):
323 if scope.doc is not None:
324 if scope.doc.is_unicode:
325 doc = scope.doc.utf8encode()
326 else:
327 doc = scope.doc.byteencode()
328 return '__Pyx_DOCSTR("%s")' % StringEncoding.escape_byte_string(doc)
329 else:
330 return "0"
333 class SuiteSlot(SlotDescriptor):
334 # Descriptor for a substructure of the type object.
335 #
336 # sub_slots [SlotDescriptor]
338 def __init__(self, sub_slots, slot_type, slot_name):
339 SlotDescriptor.__init__(self, slot_name)
340 self.sub_slots = sub_slots
341 self.slot_type = slot_type
342 substructures.append(self)
344 def substructure_cname(self, scope):
345 return "%s%s_%s" % (Naming.pyrex_prefix, self.slot_name, scope.class_name)
347 def slot_code(self, scope):
348 return "&%s" % self.substructure_cname(scope)
350 def generate_substructure(self, scope, code):
351 code.putln("")
352 code.putln(
353 "static %s %s = {" % (
354 self.slot_type,
355 self.substructure_cname(scope)))
356 for slot in self.sub_slots:
357 slot.generate(scope, code)
358 code.putln("};")
360 substructures = [] # List of all SuiteSlot instances
362 class MethodTableSlot(SlotDescriptor):
363 # Slot descriptor for the method table.
365 def slot_code(self, scope):
366 return scope.method_table_cname
369 class MemberTableSlot(SlotDescriptor):
370 # Slot descriptor for the table of Python-accessible attributes.
372 def slot_code(self, scope):
373 return "0"
376 class GetSetSlot(SlotDescriptor):
377 # Slot descriptor for the table of attribute get & set methods.
379 def slot_code(self, scope):
380 if scope.property_entries:
381 return scope.getset_table_cname
382 else:
383 return "0"
386 class BaseClassSlot(SlotDescriptor):
387 # Slot descriptor for the base class slot.
389 def __init__(self, name):
390 SlotDescriptor.__init__(self, name, dynamic = 1)
392 def generate_dynamic_init_code(self, scope, code):
393 base_type = scope.parent_type.base_type
394 if base_type:
395 code.putln("%s.%s = %s;" % (
396 scope.parent_type.typeobj_cname,
397 self.slot_name,
398 base_type.typeptr_cname))
401 # The following dictionary maps __xxx__ method names to slot descriptors.
403 method_name_to_slot = {}
405 ## The following slots are (or could be) initialised with an
406 ## extern function pointer.
407 #
408 #slots_initialised_from_extern = (
409 # "tp_free",
410 #)
412 #------------------------------------------------------------------------------------------
413 #
414 # Utility functions for accessing slot table data structures
415 #
416 #------------------------------------------------------------------------------------------
418 def get_special_method_signature(name):
419 # Given a method name, if it is a special method,
420 # return its signature, else return None.
421 slot = method_name_to_slot.get(name)
422 if slot:
423 return slot.signature
424 else:
425 return None
427 def get_property_accessor_signature(name):
428 # Return signature of accessor for an extension type
429 # property, else None.
430 return property_accessor_signatures.get(name)
432 def get_base_slot_function(scope, slot):
433 # Returns the function implementing this slot in the baseclass.
434 # This is useful for enabling the compiler to optimize calls
435 # that recursively climb the class hierarchy.
436 base_type = scope.parent_type.base_type
437 if scope.parent_scope is base_type.scope.parent_scope:
438 parent_slot = slot.slot_code(base_type.scope)
439 if parent_slot != '0':
440 entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name)
441 if entry.visibility != 'extern':
442 return parent_slot
443 return None
445 #------------------------------------------------------------------------------------------
446 #
447 # Signatures for generic Python functions and methods.
448 #
449 #------------------------------------------------------------------------------------------
451 pyfunction_signature = Signature("-*", "O")
452 pymethod_signature = Signature("T*", "O")
454 #------------------------------------------------------------------------------------------
455 #
456 # Signatures for simple Python functions.
457 #
458 #------------------------------------------------------------------------------------------
460 pyfunction_noargs = Signature("-", "O")
461 pyfunction_onearg = Signature("-O", "O")
463 #------------------------------------------------------------------------------------------
464 #
465 # Signatures for the various kinds of function that
466 # can appear in the type object and its substructures.
467 #
468 #------------------------------------------------------------------------------------------
470 unaryfunc = Signature("T", "O") # typedef PyObject * (*unaryfunc)(PyObject *);
471 binaryfunc = Signature("OO", "O") # typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
472 ibinaryfunc = Signature("TO", "O") # typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
473 ternaryfunc = Signature("OOO", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
474 iternaryfunc = Signature("TOO", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
475 callfunc = Signature("T*", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
476 inquiry = Signature("T", "i") # typedef int (*inquiry)(PyObject *);
477 lenfunc = Signature("T", "Z") # typedef Py_ssize_t (*lenfunc)(PyObject *);
479 # typedef int (*coercion)(PyObject **, PyObject **);
480 intargfunc = Signature("Ti", "O") # typedef PyObject *(*intargfunc)(PyObject *, int);
481 ssizeargfunc = Signature("TZ", "O") # typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
482 intintargfunc = Signature("Tii", "O") # typedef PyObject *(*intintargfunc)(PyObject *, int, int);
483 ssizessizeargfunc = Signature("TZZ", "O") # typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t);
484 intobjargproc = Signature("TiO", 'r') # typedef int(*intobjargproc)(PyObject *, int, PyObject *);
485 ssizeobjargproc = Signature("TZO", 'r') # typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
486 intintobjargproc = Signature("TiiO", 'r') # typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *);
487 ssizessizeobjargproc = Signature("TZZO", 'r') # typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
489 intintargproc = Signature("Tii", 'r')
490 ssizessizeargproc = Signature("TZZ", 'r')
491 objargfunc = Signature("TO", "O")
492 objobjargproc = Signature("TOO", 'r') # typedef int (*objobjargproc)(PyObject *, PyObject *, PyObject *);
493 getreadbufferproc = Signature("TiP", 'i') # typedef int (*getreadbufferproc)(PyObject *, int, void **);
494 getwritebufferproc = Signature("TiP", 'i') # typedef int (*getwritebufferproc)(PyObject *, int, void **);
495 getsegcountproc = Signature("TI", 'i') # typedef int (*getsegcountproc)(PyObject *, int *);
496 getcharbufferproc = Signature("TiS", 'i') # typedef int (*getcharbufferproc)(PyObject *, int, const char **);
497 readbufferproc = Signature("TZP", "Z") # typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **);
498 writebufferproc = Signature("TZP", "Z") # typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **);
499 segcountproc = Signature("TZ", "Z") # typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *);
500 charbufferproc = Signature("TZS", "Z") # typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **);
501 objargproc = Signature("TO", 'r') # typedef int (*objobjproc)(PyObject *, PyObject *);
502 # typedef int (*visitproc)(PyObject *, void *);
503 # typedef int (*traverseproc)(PyObject *, visitproc, void *);
505 destructor = Signature("T", "v") # typedef void (*destructor)(PyObject *);
506 # printfunc = Signature("TFi", 'r') # typedef int (*printfunc)(PyObject *, FILE *, int);
507 # typedef PyObject *(*getattrfunc)(PyObject *, char *);
508 getattrofunc = Signature("TO", "O") # typedef PyObject *(*getattrofunc)(PyObject *, PyObject *);
509 # typedef int (*setattrfunc)(PyObject *, char *, PyObject *);
510 setattrofunc = Signature("TOO", 'r') # typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *);
511 delattrofunc = Signature("TO", 'r')
512 cmpfunc = Signature("TO", "i") # typedef int (*cmpfunc)(PyObject *, PyObject *);
513 reprfunc = Signature("T", "O") # typedef PyObject *(*reprfunc)(PyObject *);
514 hashfunc = Signature("T", "l") # typedef long (*hashfunc)(PyObject *);
515 # typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
516 richcmpfunc = Signature("OOi", "O") # typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
517 getiterfunc = Signature("T", "O") # typedef PyObject *(*getiterfunc) (PyObject *);
518 iternextfunc = Signature("T", "O") # typedef PyObject *(*iternextfunc) (PyObject *);
519 descrgetfunc = Signature("TOO", "O") # typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *);
520 descrsetfunc = Signature("TOO", 'r') # typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *);
521 descrdelfunc = Signature("TO", 'r')
522 initproc = Signature("T*", 'r') # typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
523 # typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
524 # typedef PyObject *(*allocfunc)(struct _typeobject *, int);
526 getbufferproc = Signature("TBi", "r") # typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
527 releasebufferproc = Signature("TB", "v") # typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
530 #------------------------------------------------------------------------------------------
531 #
532 # Signatures for accessor methods of properties.
533 #
534 #------------------------------------------------------------------------------------------
536 property_accessor_signatures = {
537 '__get__': Signature("T", "O"),
538 '__set__': Signature("TO", 'r'),
539 '__del__': Signature("T", 'r')
540 }
542 #------------------------------------------------------------------------------------------
543 #
544 # Descriptor tables for the slots of the various type object
545 # substructures, in the order they appear in the structure.
546 #
547 #------------------------------------------------------------------------------------------
549 PyNumberMethods = (
550 MethodSlot(binaryfunc, "nb_add", "__add__"),
551 MethodSlot(binaryfunc, "nb_subtract", "__sub__"),
552 MethodSlot(binaryfunc, "nb_multiply", "__mul__"),
553 MethodSlot(binaryfunc, "nb_divide", "__div__", py3k = False),
554 MethodSlot(binaryfunc, "nb_remainder", "__mod__"),
555 MethodSlot(binaryfunc, "nb_divmod", "__divmod__"),
556 MethodSlot(ternaryfunc, "nb_power", "__pow__"),
557 MethodSlot(unaryfunc, "nb_negative", "__neg__"),
558 MethodSlot(unaryfunc, "nb_positive", "__pos__"),
559 MethodSlot(unaryfunc, "nb_absolute", "__abs__"),
560 MethodSlot(inquiry, "nb_nonzero", "__nonzero__"),
561 MethodSlot(unaryfunc, "nb_invert", "__invert__"),
562 MethodSlot(binaryfunc, "nb_lshift", "__lshift__"),
563 MethodSlot(binaryfunc, "nb_rshift", "__rshift__"),
564 MethodSlot(binaryfunc, "nb_and", "__and__"),
565 MethodSlot(binaryfunc, "nb_xor", "__xor__"),
566 MethodSlot(binaryfunc, "nb_or", "__or__"),
567 EmptySlot("nb_coerce", py3k = False),
568 MethodSlot(unaryfunc, "nb_int", "__int__", default="__long__"),
569 MethodSlot(unaryfunc, "nb_long", "__long__", default="__int__", py3k = "<RESERVED>"),
570 MethodSlot(unaryfunc, "nb_float", "__float__"),
571 MethodSlot(unaryfunc, "nb_oct", "__oct__", py3k = False),
572 MethodSlot(unaryfunc, "nb_hex", "__hex__", py3k = False),
574 # Added in release 2.0
575 MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__"),
576 MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__"),
577 MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__"),
578 MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__", py3k = False),
579 MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__"),
580 MethodSlot(ternaryfunc, "nb_inplace_power", "__ipow__"), # NOT iternaryfunc!!!
581 MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__"),
582 MethodSlot(ibinaryfunc, "nb_inplace_rshift", "__irshift__"),
583 MethodSlot(ibinaryfunc, "nb_inplace_and", "__iand__"),
584 MethodSlot(ibinaryfunc, "nb_inplace_xor", "__ixor__"),
585 MethodSlot(ibinaryfunc, "nb_inplace_or", "__ior__"),
587 # Added in release 2.2
588 # The following require the Py_TPFLAGS_HAVE_CLASS flag
589 MethodSlot(binaryfunc, "nb_floor_divide", "__floordiv__"),
590 MethodSlot(binaryfunc, "nb_true_divide", "__truediv__"),
591 MethodSlot(ibinaryfunc, "nb_inplace_floor_divide", "__ifloordiv__"),
592 MethodSlot(ibinaryfunc, "nb_inplace_true_divide", "__itruediv__"),
594 # Added in release 2.5
595 MethodSlot(unaryfunc, "nb_index", "__index__", flag = "Py_TPFLAGS_HAVE_INDEX")
596 )
598 PySequenceMethods = (
599 MethodSlot(lenfunc, "sq_length", "__len__"),
600 EmptySlot("sq_concat"), # nb_add used instead
601 EmptySlot("sq_repeat"), # nb_multiply used instead
602 SyntheticSlot("sq_item", ["__getitem__"], "0"), #EmptySlot("sq_item"), # mp_subscript used instead
603 MethodSlot(ssizessizeargfunc, "sq_slice", "__getslice__"),
604 EmptySlot("sq_ass_item"), # mp_ass_subscript used instead
605 SyntheticSlot("sq_ass_slice", ["__setslice__", "__delslice__"], "0"),
606 MethodSlot(cmpfunc, "sq_contains", "__contains__"),
607 EmptySlot("sq_inplace_concat"), # nb_inplace_add used instead
608 EmptySlot("sq_inplace_repeat"), # nb_inplace_multiply used instead
609 )
611 PyMappingMethods = (
612 MethodSlot(lenfunc, "mp_length", "__len__"),
613 MethodSlot(objargfunc, "mp_subscript", "__getitem__"),
614 SyntheticSlot("mp_ass_subscript", ["__setitem__", "__delitem__"], "0"),
615 )
617 PyBufferProcs = (
618 MethodSlot(getreadbufferproc, "bf_getreadbuffer", "__getreadbuffer__", py3k = False),
619 MethodSlot(getwritebufferproc, "bf_getwritebuffer", "__getwritebuffer__", py3k = False),
620 MethodSlot(getsegcountproc, "bf_getsegcount", "__getsegcount__", py3k = False),
621 MethodSlot(getcharbufferproc, "bf_getcharbuffer", "__getcharbuffer__", py3k = False),
623 MethodSlot(getbufferproc, "bf_getbuffer", "__getbuffer__", ifdef = "PY_VERSION_HEX >= 0x02060000"),
624 MethodSlot(releasebufferproc, "bf_releasebuffer", "__releasebuffer__", ifdef = "PY_VERSION_HEX >= 0x02060000")
625 )
627 #------------------------------------------------------------------------------------------
628 #
629 # The main slot table. This table contains descriptors for all the
630 # top-level type slots, beginning with tp_dealloc, in the order they
631 # appear in the type object.
632 #
633 #------------------------------------------------------------------------------------------
635 slot_table = (
636 ConstructorSlot("tp_dealloc", '__dealloc__'),
637 EmptySlot("tp_print"), #MethodSlot(printfunc, "tp_print", "__print__"),
638 EmptySlot("tp_getattr"),
639 EmptySlot("tp_setattr"),
640 MethodSlot(cmpfunc, "tp_compare", "__cmp__"),
641 MethodSlot(reprfunc, "tp_repr", "__repr__"),
643 SuiteSlot(PyNumberMethods, "PyNumberMethods", "tp_as_number"),
644 SuiteSlot(PySequenceMethods, "PySequenceMethods", "tp_as_sequence"),
645 SuiteSlot(PyMappingMethods, "PyMappingMethods", "tp_as_mapping"),
647 MethodSlot(hashfunc, "tp_hash", "__hash__"),
648 MethodSlot(callfunc, "tp_call", "__call__"),
649 MethodSlot(reprfunc, "tp_str", "__str__"),
651 SyntheticSlot("tp_getattro", ["__getattr__","__getattribute__"], "0"), #"PyObject_GenericGetAttr"),
652 SyntheticSlot("tp_setattro", ["__setattr__", "__delattr__"], "0"), #"PyObject_GenericSetAttr"),
654 SuiteSlot(PyBufferProcs, "PyBufferProcs", "tp_as_buffer"),
656 TypeFlagsSlot("tp_flags"),
657 DocStringSlot("tp_doc"),
659 GCDependentSlot("tp_traverse"),
660 GCDependentSlot("tp_clear"),
662 # Later -- synthesize a method to split into separate ops?
663 MethodSlot(richcmpfunc, "tp_richcompare", "__richcmp__"),
665 EmptySlot("tp_weaklistoffset"),
667 MethodSlot(getiterfunc, "tp_iter", "__iter__"),
668 MethodSlot(iternextfunc, "tp_iternext", "__next__"),
670 MethodTableSlot("tp_methods"),
671 MemberTableSlot("tp_members"),
672 GetSetSlot("tp_getset"),
674 BaseClassSlot("tp_base"), #EmptySlot("tp_base"),
675 EmptySlot("tp_dict"),
677 SyntheticSlot("tp_descr_get", ["__get__"], "0"),
678 SyntheticSlot("tp_descr_set", ["__set__", "__delete__"], "0"),
680 EmptySlot("tp_dictoffset"),
682 MethodSlot(initproc, "tp_init", "__init__"),
683 EmptySlot("tp_alloc"), #FixedSlot("tp_alloc", "PyType_GenericAlloc"),
684 InternalMethodSlot("tp_new"),
685 EmptySlot("tp_free"),
687 EmptySlot("tp_is_gc"),
688 EmptySlot("tp_bases"),
689 EmptySlot("tp_mro"),
690 EmptySlot("tp_cache"),
691 EmptySlot("tp_subclasses"),
692 EmptySlot("tp_weaklist"),
693 EmptySlot("tp_del"),
694 EmptySlot("tp_version_tag", ifdef="PY_VERSION_HEX >= 0x02060000"),
695 )
697 #------------------------------------------------------------------------------------------
698 #
699 # Descriptors for special methods which don't appear directly
700 # in the type object or its substructures. These methods are
701 # called from slot functions synthesized by Cython.
702 #
703 #------------------------------------------------------------------------------------------
705 MethodSlot(initproc, "", "__cinit__")
706 MethodSlot(destructor, "", "__dealloc__")
707 MethodSlot(objobjargproc, "", "__setitem__")
708 MethodSlot(objargproc, "", "__delitem__")
709 MethodSlot(ssizessizeobjargproc, "", "__setslice__")
710 MethodSlot(ssizessizeargproc, "", "__delslice__")
711 MethodSlot(getattrofunc, "", "__getattr__")
712 MethodSlot(setattrofunc, "", "__setattr__")
713 MethodSlot(delattrofunc, "", "__delattr__")
714 MethodSlot(descrgetfunc, "", "__get__")
715 MethodSlot(descrsetfunc, "", "__set__")
716 MethodSlot(descrdelfunc, "", "__delete__")
719 # Method flags for python-exposed methods.
721 method_noargs = "METH_NOARGS"
722 method_onearg = "METH_O"
723 method_varargs = "METH_VARARGS"
724 method_keywords = "METH_KEYWORDS"
725 method_coexist = "METH_COEXIST"