1use super::{PyComparisonOp, PyTypeSlots};
6use crate::builtins::descriptor::SlotFunc;
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum SlotOp {
15 Lt,
17 Le,
18 Eq,
19 Ne,
20 Gt,
21 Ge,
22 Left,
24 Right,
25 Delete,
27}
28
29impl SlotOp {
30 pub fn as_compare_op(&self) -> Option<PyComparisonOp> {
32 match self {
33 Self::Lt => Some(PyComparisonOp::Lt),
34 Self::Le => Some(PyComparisonOp::Le),
35 Self::Eq => Some(PyComparisonOp::Eq),
36 Self::Ne => Some(PyComparisonOp::Ne),
37 Self::Gt => Some(PyComparisonOp::Gt),
38 Self::Ge => Some(PyComparisonOp::Ge),
39 _ => None,
40 }
41 }
42
43 pub fn is_right(&self) -> bool {
45 matches!(self, Self::Right)
46 }
47}
48
49#[derive(Clone, Copy)]
51pub struct SlotDef {
52 pub name: &'static str,
54
55 pub accessor: SlotAccessor,
57
58 pub op: Option<SlotOp>,
60
61 pub doc: &'static str,
63}
64
65#[derive(Clone, Copy, Debug, PartialEq, Eq)]
70#[repr(u8)]
71pub enum SlotAccessor {
72 BfGetBuffer = 1,
74 BfReleaseBuffer = 2,
75
76 MpAssSubscript = 3,
78 MpLength = 4,
79 MpSubscript = 5,
80
81 NbAbsolute = 6,
83 NbAdd = 7,
84 NbAnd = 8,
85 NbBool = 9,
86 NbDivmod = 10,
87 NbFloat = 11,
88 NbFloorDivide = 12,
89 NbIndex = 13,
90 NbInplaceAdd = 14,
91 NbInplaceAnd = 15,
92 NbInplaceFloorDivide = 16,
93 NbInplaceLshift = 17,
94 NbInplaceMultiply = 18,
95 NbInplaceOr = 19,
96 NbInplacePower = 20,
97 NbInplaceRemainder = 21,
98 NbInplaceRshift = 22,
99 NbInplaceSubtract = 23,
100 NbInplaceTrueDivide = 24,
101 NbInplaceXor = 25,
102 NbInt = 26,
103 NbInvert = 27,
104 NbLshift = 28,
105 NbMultiply = 29,
106 NbNegative = 30,
107 NbOr = 31,
108 NbPositive = 32,
109 NbPower = 33,
110 NbRemainder = 34,
111 NbRshift = 35,
112 NbSubtract = 36,
113 NbTrueDivide = 37,
114 NbXor = 38,
115
116 SqAssItem = 39,
118 SqConcat = 40,
119 SqContains = 41,
120 SqInplaceConcat = 42,
121 SqInplaceRepeat = 43,
122 SqItem = 44,
123 SqLength = 45,
124 SqRepeat = 46,
125
126 TpAlloc = 47, TpBase = 48, TpBases = 49, TpCall = 50,
131 TpClear = 51, TpDealloc = 52, TpDel = 53,
134 TpDescrGet = 54,
135 TpDescrSet = 55,
136 TpDoc = 56, TpGetattr = 57, TpGetattro = 58,
139 TpHash = 59,
140 TpInit = 60,
141 TpIsGc = 61, TpIter = 62,
143 TpIternext = 63,
144 TpMethods = 64, TpNew = 65,
146 TpRepr = 66,
147 TpRichcompare = 67,
148 TpSetattr = 68, TpSetattro = 69,
150 TpStr = 70,
151 TpTraverse = 71, TpMembers = 72, TpGetset = 73, TpFree = 74, NbMatrixMultiply = 75,
158 NbInplaceMatrixMultiply = 76,
159
160 AmAwait = 77,
162 AmAiter = 78,
163 AmAnext = 79,
164 TpFinalize = 80,
165 AmSend = 81,
166}
167
168impl SlotAccessor {
169 pub fn is_reserved(&self) -> bool {
171 matches!(
172 self,
173 Self::BfGetBuffer
174 | Self::BfReleaseBuffer
175 | Self::TpAlloc
176 | Self::TpBase
177 | Self::TpBases
178 | Self::TpClear
179 | Self::TpDealloc
180 | Self::TpDoc
181 | Self::TpGetattr
182 | Self::TpIsGc
183 | Self::TpMethods
184 | Self::TpSetattr
185 | Self::TpTraverse
186 | Self::TpMembers
187 | Self::TpGetset
188 | Self::TpFree
189 | Self::TpFinalize
190 | Self::AmAwait
191 | Self::AmAiter
192 | Self::AmAnext
193 | Self::AmSend
194 )
195 }
196
197 pub fn is_number_binary(&self) -> bool {
199 matches!(
200 self,
201 Self::NbAdd
202 | Self::NbSubtract
203 | Self::NbMultiply
204 | Self::NbRemainder
205 | Self::NbDivmod
206 | Self::NbPower
207 | Self::NbLshift
208 | Self::NbRshift
209 | Self::NbAnd
210 | Self::NbXor
211 | Self::NbOr
212 | Self::NbFloorDivide
213 | Self::NbTrueDivide
214 | Self::NbMatrixMultiply
215 )
216 }
217
218 pub fn is_shared_slot(&self) -> bool {
227 matches!(
228 self,
229 Self::TpSetattro
230 | Self::TpRichcompare
231 | Self::TpDescrSet
232 | Self::SqAssItem
233 | Self::MpAssSubscript
234 ) || self.is_number_binary()
235 }
236
237 pub fn slot_name(&self) -> &'static str {
239 match self {
240 Self::BfGetBuffer => "bf_getbuffer",
241 Self::BfReleaseBuffer => "bf_releasebuffer",
242 Self::MpAssSubscript => "mp_ass_subscript",
243 Self::MpLength => "mp_length",
244 Self::MpSubscript => "mp_subscript",
245 Self::NbAbsolute => "nb_absolute",
246 Self::NbAdd => "nb_add",
247 Self::NbAnd => "nb_and",
248 Self::NbBool => "nb_bool",
249 Self::NbDivmod => "nb_divmod",
250 Self::NbFloat => "nb_float",
251 Self::NbFloorDivide => "nb_floor_divide",
252 Self::NbIndex => "nb_index",
253 Self::NbInplaceAdd => "nb_inplace_add",
254 Self::NbInplaceAnd => "nb_inplace_and",
255 Self::NbInplaceFloorDivide => "nb_inplace_floor_divide",
256 Self::NbInplaceLshift => "nb_inplace_lshift",
257 Self::NbInplaceMultiply => "nb_inplace_multiply",
258 Self::NbInplaceOr => "nb_inplace_or",
259 Self::NbInplacePower => "nb_inplace_power",
260 Self::NbInplaceRemainder => "nb_inplace_remainder",
261 Self::NbInplaceRshift => "nb_inplace_rshift",
262 Self::NbInplaceSubtract => "nb_inplace_subtract",
263 Self::NbInplaceTrueDivide => "nb_inplace_true_divide",
264 Self::NbInplaceXor => "nb_inplace_xor",
265 Self::NbInt => "nb_int",
266 Self::NbInvert => "nb_invert",
267 Self::NbLshift => "nb_lshift",
268 Self::NbMultiply => "nb_multiply",
269 Self::NbNegative => "nb_negative",
270 Self::NbOr => "nb_or",
271 Self::NbPositive => "nb_positive",
272 Self::NbPower => "nb_power",
273 Self::NbRemainder => "nb_remainder",
274 Self::NbRshift => "nb_rshift",
275 Self::NbSubtract => "nb_subtract",
276 Self::NbTrueDivide => "nb_true_divide",
277 Self::NbXor => "nb_xor",
278 Self::SqAssItem => "sq_ass_item",
279 Self::SqConcat => "sq_concat",
280 Self::SqContains => "sq_contains",
281 Self::SqInplaceConcat => "sq_inplace_concat",
282 Self::SqInplaceRepeat => "sq_inplace_repeat",
283 Self::SqItem => "sq_item",
284 Self::SqLength => "sq_length",
285 Self::SqRepeat => "sq_repeat",
286 Self::TpAlloc => "tp_alloc",
287 Self::TpBase => "tp_base",
288 Self::TpBases => "tp_bases",
289 Self::TpCall => "tp_call",
290 Self::TpClear => "tp_clear",
291 Self::TpDealloc => "tp_dealloc",
292 Self::TpDel => "tp_del",
293 Self::TpDescrGet => "tp_descr_get",
294 Self::TpDescrSet => "tp_descr_set",
295 Self::TpDoc => "tp_doc",
296 Self::TpGetattr => "tp_getattr",
297 Self::TpGetattro => "tp_getattro",
298 Self::TpHash => "tp_hash",
299 Self::TpInit => "tp_init",
300 Self::TpIsGc => "tp_is_gc",
301 Self::TpIter => "tp_iter",
302 Self::TpIternext => "tp_iternext",
303 Self::TpMethods => "tp_methods",
304 Self::TpNew => "tp_new",
305 Self::TpRepr => "tp_repr",
306 Self::TpRichcompare => "tp_richcompare",
307 Self::TpSetattr => "tp_setattr",
308 Self::TpSetattro => "tp_setattro",
309 Self::TpStr => "tp_str",
310 Self::TpTraverse => "tp_traverse",
311 Self::TpMembers => "tp_members",
312 Self::TpGetset => "tp_getset",
313 Self::TpFree => "tp_free",
314 Self::NbMatrixMultiply => "nb_matrix_multiply",
315 Self::NbInplaceMatrixMultiply => "nb_inplace_matrix_multiply",
316 Self::AmAwait => "am_await",
317 Self::AmAiter => "am_aiter",
318 Self::AmAnext => "am_anext",
319 Self::TpFinalize => "tp_finalize",
320 Self::AmSend => "am_send",
321 }
322 }
323
324 pub fn extract_from_slot_func(&self, slot_func: &SlotFunc) -> bool {
326 match self {
327 Self::TpHash => matches!(slot_func, SlotFunc::Hash(_)),
329 Self::TpRepr => matches!(slot_func, SlotFunc::Repr(_)),
330 Self::TpStr => matches!(slot_func, SlotFunc::Str(_)),
331 Self::TpCall => matches!(slot_func, SlotFunc::Call(_)),
332 Self::TpIter => matches!(slot_func, SlotFunc::Iter(_)),
333 Self::TpIternext => matches!(slot_func, SlotFunc::IterNext(_)),
334 Self::TpInit => matches!(slot_func, SlotFunc::Init(_)),
335 Self::TpDel => matches!(slot_func, SlotFunc::Del(_)),
336 Self::TpGetattro => matches!(slot_func, SlotFunc::GetAttro(_)),
337 Self::TpSetattro => {
338 matches!(slot_func, SlotFunc::SetAttro(_) | SlotFunc::DelAttro(_))
339 }
340 Self::TpDescrGet => matches!(slot_func, SlotFunc::DescrGet(_)),
341 Self::TpDescrSet => {
342 matches!(slot_func, SlotFunc::DescrSet(_) | SlotFunc::DescrDel(_))
343 }
344 Self::TpRichcompare => matches!(slot_func, SlotFunc::RichCompare(_, _)),
345
346 Self::NbPower | Self::NbInplacePower => {
348 matches!(slot_func, SlotFunc::NumTernary(_))
349 }
350 Self::NbBool => matches!(slot_func, SlotFunc::NumBoolean(_)),
352 Self::NbNegative
354 | Self::NbPositive
355 | Self::NbAbsolute
356 | Self::NbInvert
357 | Self::NbInt
358 | Self::NbFloat
359 | Self::NbIndex => matches!(slot_func, SlotFunc::NumUnary(_)),
360 Self::NbAdd
362 | Self::NbSubtract
363 | Self::NbMultiply
364 | Self::NbRemainder
365 | Self::NbDivmod
366 | Self::NbLshift
367 | Self::NbRshift
368 | Self::NbAnd
369 | Self::NbXor
370 | Self::NbOr
371 | Self::NbFloorDivide
372 | Self::NbTrueDivide
373 | Self::NbMatrixMultiply
374 | Self::NbInplaceAdd
375 | Self::NbInplaceSubtract
376 | Self::NbInplaceMultiply
377 | Self::NbInplaceRemainder
378 | Self::NbInplaceLshift
379 | Self::NbInplaceRshift
380 | Self::NbInplaceAnd
381 | Self::NbInplaceXor
382 | Self::NbInplaceOr
383 | Self::NbInplaceFloorDivide
384 | Self::NbInplaceTrueDivide
385 | Self::NbInplaceMatrixMultiply => matches!(slot_func, SlotFunc::NumBinary(_)),
386
387 Self::SqLength => matches!(slot_func, SlotFunc::SeqLength(_)),
389 Self::SqConcat | Self::SqInplaceConcat => matches!(slot_func, SlotFunc::SeqConcat(_)),
390 Self::SqRepeat | Self::SqInplaceRepeat => matches!(slot_func, SlotFunc::SeqRepeat(_)),
391 Self::SqItem => matches!(slot_func, SlotFunc::SeqItem(_)),
392 Self::SqAssItem => {
393 matches!(slot_func, SlotFunc::SeqSetItem(_) | SlotFunc::SeqDelItem(_))
394 }
395 Self::SqContains => matches!(slot_func, SlotFunc::SeqContains(_)),
396
397 Self::MpLength => matches!(slot_func, SlotFunc::MapLength(_)),
399 Self::MpSubscript => matches!(slot_func, SlotFunc::MapSubscript(_)),
400 Self::MpAssSubscript => {
401 matches!(
402 slot_func,
403 SlotFunc::MapSetSubscript(_) | SlotFunc::MapDelSubscript(_)
404 )
405 }
406
407 Self::TpNew => false,
409 _ => false, }
411 }
412
413 pub fn inherit_from_mro(&self, typ: &crate::builtins::PyType) {
415 let mro_guard = typ.mro.read();
417 let mro = &mro_guard[1..];
418
419 macro_rules! inherit_main {
420 ($slot:ident) => {{
421 let inherited = mro.iter().find_map(|cls| cls.slots.$slot.load());
422 typ.slots.$slot.store(inherited);
423 }};
424 }
425
426 macro_rules! inherit_number {
427 ($slot:ident) => {{
428 let inherited = mro.iter().find_map(|cls| cls.slots.as_number.$slot.load());
429 typ.slots.as_number.$slot.store(inherited);
430 }};
431 }
432
433 macro_rules! inherit_sequence {
434 ($slot:ident) => {{
435 let inherited = mro
436 .iter()
437 .find_map(|cls| cls.slots.as_sequence.$slot.load());
438 typ.slots.as_sequence.$slot.store(inherited);
439 }};
440 }
441
442 macro_rules! inherit_mapping {
443 ($slot:ident) => {{
444 let inherited = mro.iter().find_map(|cls| cls.slots.as_mapping.$slot.load());
445 typ.slots.as_mapping.$slot.store(inherited);
446 }};
447 }
448
449 match self {
450 Self::TpHash => inherit_main!(hash),
452 Self::TpRepr => inherit_main!(repr),
453 Self::TpStr => inherit_main!(str),
454 Self::TpCall => {
455 inherit_main!(call);
456 let inherited_vc = mro.iter().find_map(|cls| {
463 if cls.slots.call.load().is_some() {
464 cls.slots.vectorcall.load()
465 } else {
466 None
467 }
468 });
469 typ.slots.vectorcall.store(inherited_vc);
470 }
471 Self::TpIter => inherit_main!(iter),
472 Self::TpIternext => inherit_main!(iternext),
473 Self::TpInit => inherit_main!(init),
474 Self::TpNew => inherit_main!(new),
475 Self::TpDel => inherit_main!(del),
476 Self::TpGetattro => inherit_main!(getattro),
477 Self::TpSetattro => inherit_main!(setattro),
478 Self::TpDescrGet => inherit_main!(descr_get),
479 Self::TpDescrSet => inherit_main!(descr_set),
480 Self::TpRichcompare => inherit_main!(richcompare),
481
482 Self::NbAdd => inherit_number!(add),
484 Self::NbSubtract => inherit_number!(subtract),
485 Self::NbMultiply => inherit_number!(multiply),
486 Self::NbRemainder => inherit_number!(remainder),
487 Self::NbDivmod => inherit_number!(divmod),
488 Self::NbPower => inherit_number!(power),
489 Self::NbLshift => inherit_number!(lshift),
490 Self::NbRshift => inherit_number!(rshift),
491 Self::NbAnd => inherit_number!(and),
492 Self::NbXor => inherit_number!(xor),
493 Self::NbOr => inherit_number!(or),
494 Self::NbFloorDivide => inherit_number!(floor_divide),
495 Self::NbTrueDivide => inherit_number!(true_divide),
496 Self::NbMatrixMultiply => inherit_number!(matrix_multiply),
497 Self::NbInplaceAdd => inherit_number!(inplace_add),
498 Self::NbInplaceSubtract => inherit_number!(inplace_subtract),
499 Self::NbInplaceMultiply => inherit_number!(inplace_multiply),
500 Self::NbInplaceRemainder => inherit_number!(inplace_remainder),
501 Self::NbInplacePower => inherit_number!(inplace_power),
502 Self::NbInplaceLshift => inherit_number!(inplace_lshift),
503 Self::NbInplaceRshift => inherit_number!(inplace_rshift),
504 Self::NbInplaceAnd => inherit_number!(inplace_and),
505 Self::NbInplaceXor => inherit_number!(inplace_xor),
506 Self::NbInplaceOr => inherit_number!(inplace_or),
507 Self::NbInplaceFloorDivide => inherit_number!(inplace_floor_divide),
508 Self::NbInplaceTrueDivide => inherit_number!(inplace_true_divide),
509 Self::NbInplaceMatrixMultiply => inherit_number!(inplace_matrix_multiply),
510 Self::NbNegative => inherit_number!(negative),
512 Self::NbPositive => inherit_number!(positive),
513 Self::NbAbsolute => inherit_number!(absolute),
514 Self::NbInvert => inherit_number!(invert),
515 Self::NbBool => inherit_number!(boolean),
516 Self::NbInt => inherit_number!(int),
517 Self::NbFloat => inherit_number!(float),
518 Self::NbIndex => inherit_number!(index),
519
520 Self::SqLength => inherit_sequence!(length),
522 Self::SqConcat => inherit_sequence!(concat),
523 Self::SqRepeat => inherit_sequence!(repeat),
524 Self::SqItem => inherit_sequence!(item),
525 Self::SqAssItem => inherit_sequence!(ass_item),
526 Self::SqContains => inherit_sequence!(contains),
527 Self::SqInplaceConcat => inherit_sequence!(inplace_concat),
528 Self::SqInplaceRepeat => inherit_sequence!(inplace_repeat),
529
530 Self::MpLength => inherit_mapping!(length),
532 Self::MpSubscript => inherit_mapping!(subscript),
533 Self::MpAssSubscript => inherit_mapping!(ass_subscript),
534
535 _ => {}
537 }
538 }
539
540 pub fn copyslot_if_none(&self, typ: &crate::builtins::PyType, base: &crate::builtins::PyType) {
542 macro_rules! copy_main {
543 ($slot:ident) => {{
544 if typ.slots.$slot.load().is_none() {
545 if let Some(base_val) = base.slots.$slot.load() {
546 typ.slots.$slot.store(Some(base_val));
547 }
548 }
549 }};
550 }
551
552 macro_rules! copy_number {
553 ($slot:ident) => {{
554 if typ.slots.as_number.$slot.load().is_none() {
555 if let Some(base_val) = base.slots.as_number.$slot.load() {
556 typ.slots.as_number.$slot.store(Some(base_val));
557 }
558 }
559 }};
560 }
561
562 macro_rules! copy_sequence {
563 ($slot:ident) => {{
564 if typ.slots.as_sequence.$slot.load().is_none() {
565 if let Some(base_val) = base.slots.as_sequence.$slot.load() {
566 typ.slots.as_sequence.$slot.store(Some(base_val));
567 }
568 }
569 }};
570 }
571
572 macro_rules! copy_mapping {
573 ($slot:ident) => {{
574 if typ.slots.as_mapping.$slot.load().is_none() {
575 if let Some(base_val) = base.slots.as_mapping.$slot.load() {
576 typ.slots.as_mapping.$slot.store(Some(base_val));
577 }
578 }
579 }};
580 }
581
582 match self {
583 Self::TpHash => copy_main!(hash),
585 Self::TpRepr => copy_main!(repr),
586 Self::TpStr => copy_main!(str),
587 Self::TpCall => {
588 copy_main!(call);
589 if typ.slots.vectorcall.load().is_none()
591 && base.slots.call.load().is_some()
592 && let Some(base_val) = base.slots.vectorcall.load()
593 {
594 typ.slots.vectorcall.store(Some(base_val));
595 }
596 }
597 Self::TpIter => copy_main!(iter),
598 Self::TpIternext => copy_main!(iternext),
599 Self::TpInit => {
600 if typ.slots.init.load().is_none()
602 && let Some(base_val) = base.slots.init.load()
603 {
604 let slot_defined = base.base.as_ref().is_none_or(|bb| {
605 bb.slots.init.load().map(|v| v as usize) != Some(base_val as usize)
606 });
607 if slot_defined {
608 typ.slots.init.store(Some(base_val));
609 }
610 }
611 }
612 Self::TpNew => {} Self::TpDel => copy_main!(del),
614 Self::TpGetattro => copy_main!(getattro),
615 Self::TpSetattro => copy_main!(setattro),
616 Self::TpDescrGet => copy_main!(descr_get),
617 Self::TpDescrSet => copy_main!(descr_set),
618 Self::TpRichcompare => copy_main!(richcompare),
619
620 Self::NbAdd => copy_number!(add),
622 Self::NbSubtract => copy_number!(subtract),
623 Self::NbMultiply => copy_number!(multiply),
624 Self::NbRemainder => copy_number!(remainder),
625 Self::NbDivmod => copy_number!(divmod),
626 Self::NbPower => copy_number!(power),
627 Self::NbLshift => copy_number!(lshift),
628 Self::NbRshift => copy_number!(rshift),
629 Self::NbAnd => copy_number!(and),
630 Self::NbXor => copy_number!(xor),
631 Self::NbOr => copy_number!(or),
632 Self::NbFloorDivide => copy_number!(floor_divide),
633 Self::NbTrueDivide => copy_number!(true_divide),
634 Self::NbMatrixMultiply => copy_number!(matrix_multiply),
635 Self::NbInplaceAdd => copy_number!(inplace_add),
636 Self::NbInplaceSubtract => copy_number!(inplace_subtract),
637 Self::NbInplaceMultiply => copy_number!(inplace_multiply),
638 Self::NbInplaceRemainder => copy_number!(inplace_remainder),
639 Self::NbInplacePower => copy_number!(inplace_power),
640 Self::NbInplaceLshift => copy_number!(inplace_lshift),
641 Self::NbInplaceRshift => copy_number!(inplace_rshift),
642 Self::NbInplaceAnd => copy_number!(inplace_and),
643 Self::NbInplaceXor => copy_number!(inplace_xor),
644 Self::NbInplaceOr => copy_number!(inplace_or),
645 Self::NbInplaceFloorDivide => copy_number!(inplace_floor_divide),
646 Self::NbInplaceTrueDivide => copy_number!(inplace_true_divide),
647 Self::NbInplaceMatrixMultiply => copy_number!(inplace_matrix_multiply),
648 Self::NbNegative => copy_number!(negative),
650 Self::NbPositive => copy_number!(positive),
651 Self::NbAbsolute => copy_number!(absolute),
652 Self::NbInvert => copy_number!(invert),
653 Self::NbBool => copy_number!(boolean),
654 Self::NbInt => copy_number!(int),
655 Self::NbFloat => copy_number!(float),
656 Self::NbIndex => copy_number!(index),
657
658 Self::SqLength => copy_sequence!(length),
660 Self::SqConcat => copy_sequence!(concat),
661 Self::SqRepeat => copy_sequence!(repeat),
662 Self::SqItem => copy_sequence!(item),
663 Self::SqAssItem => copy_sequence!(ass_item),
664 Self::SqContains => copy_sequence!(contains),
665 Self::SqInplaceConcat => copy_sequence!(inplace_concat),
666 Self::SqInplaceRepeat => copy_sequence!(inplace_repeat),
667
668 Self::MpLength => copy_mapping!(length),
670 Self::MpSubscript => copy_mapping!(subscript),
671 Self::MpAssSubscript => copy_mapping!(ass_subscript),
672
673 _ => {}
675 }
676 }
677
678 pub fn get_slot_func(&self, slots: &PyTypeSlots) -> Option<SlotFunc> {
680 match self {
681 Self::TpHash => slots.hash.load().map(SlotFunc::Hash),
683 Self::TpRepr => slots.repr.load().map(SlotFunc::Repr),
684 Self::TpStr => slots.str.load().map(SlotFunc::Str),
685 Self::TpCall => slots.call.load().map(SlotFunc::Call),
686 Self::TpIter => slots.iter.load().map(SlotFunc::Iter),
687 Self::TpIternext => slots.iternext.load().map(SlotFunc::IterNext),
688 Self::TpInit => slots.init.load().map(SlotFunc::Init),
689 Self::TpNew => None, Self::TpDel => slots.del.load().map(SlotFunc::Del),
691 Self::TpGetattro => slots.getattro.load().map(SlotFunc::GetAttro),
692 Self::TpSetattro => slots.setattro.load().map(SlotFunc::SetAttro),
693 Self::TpDescrGet => slots.descr_get.load().map(SlotFunc::DescrGet),
694 Self::TpDescrSet => slots.descr_set.load().map(SlotFunc::DescrSet),
695 Self::TpRichcompare => slots
696 .richcompare
697 .load()
698 .map(|f| SlotFunc::RichCompare(f, PyComparisonOp::Eq)),
699
700 Self::NbAdd => slots.as_number.add.load().map(SlotFunc::NumBinary),
702 Self::NbSubtract => slots.as_number.subtract.load().map(SlotFunc::NumBinary),
703 Self::NbMultiply => slots.as_number.multiply.load().map(SlotFunc::NumBinary),
704 Self::NbRemainder => slots.as_number.remainder.load().map(SlotFunc::NumBinary),
705 Self::NbDivmod => slots.as_number.divmod.load().map(SlotFunc::NumBinary),
706 Self::NbPower => slots.as_number.power.load().map(SlotFunc::NumTernary),
707 Self::NbLshift => slots.as_number.lshift.load().map(SlotFunc::NumBinary),
708 Self::NbRshift => slots.as_number.rshift.load().map(SlotFunc::NumBinary),
709 Self::NbAnd => slots.as_number.and.load().map(SlotFunc::NumBinary),
710 Self::NbXor => slots.as_number.xor.load().map(SlotFunc::NumBinary),
711 Self::NbOr => slots.as_number.or.load().map(SlotFunc::NumBinary),
712 Self::NbFloorDivide => slots.as_number.floor_divide.load().map(SlotFunc::NumBinary),
713 Self::NbTrueDivide => slots.as_number.true_divide.load().map(SlotFunc::NumBinary),
714 Self::NbMatrixMultiply => slots
715 .as_number
716 .matrix_multiply
717 .load()
718 .map(SlotFunc::NumBinary),
719
720 Self::NbInplaceAdd => slots.as_number.inplace_add.load().map(SlotFunc::NumBinary),
722 Self::NbInplaceSubtract => slots
723 .as_number
724 .inplace_subtract
725 .load()
726 .map(SlotFunc::NumBinary),
727 Self::NbInplaceMultiply => slots
728 .as_number
729 .inplace_multiply
730 .load()
731 .map(SlotFunc::NumBinary),
732 Self::NbInplaceRemainder => slots
733 .as_number
734 .inplace_remainder
735 .load()
736 .map(SlotFunc::NumBinary),
737 Self::NbInplacePower => slots
738 .as_number
739 .inplace_power
740 .load()
741 .map(SlotFunc::NumTernary),
742 Self::NbInplaceLshift => slots
743 .as_number
744 .inplace_lshift
745 .load()
746 .map(SlotFunc::NumBinary),
747 Self::NbInplaceRshift => slots
748 .as_number
749 .inplace_rshift
750 .load()
751 .map(SlotFunc::NumBinary),
752 Self::NbInplaceAnd => slots.as_number.inplace_and.load().map(SlotFunc::NumBinary),
753 Self::NbInplaceXor => slots.as_number.inplace_xor.load().map(SlotFunc::NumBinary),
754 Self::NbInplaceOr => slots.as_number.inplace_or.load().map(SlotFunc::NumBinary),
755 Self::NbInplaceFloorDivide => slots
756 .as_number
757 .inplace_floor_divide
758 .load()
759 .map(SlotFunc::NumBinary),
760 Self::NbInplaceTrueDivide => slots
761 .as_number
762 .inplace_true_divide
763 .load()
764 .map(SlotFunc::NumBinary),
765 Self::NbInplaceMatrixMultiply => slots
766 .as_number
767 .inplace_matrix_multiply
768 .load()
769 .map(SlotFunc::NumBinary),
770
771 Self::NbNegative => slots.as_number.negative.load().map(SlotFunc::NumUnary),
773 Self::NbPositive => slots.as_number.positive.load().map(SlotFunc::NumUnary),
774 Self::NbAbsolute => slots.as_number.absolute.load().map(SlotFunc::NumUnary),
775 Self::NbInvert => slots.as_number.invert.load().map(SlotFunc::NumUnary),
776 Self::NbBool => slots.as_number.boolean.load().map(SlotFunc::NumBoolean),
777 Self::NbInt => slots.as_number.int.load().map(SlotFunc::NumUnary),
778 Self::NbFloat => slots.as_number.float.load().map(SlotFunc::NumUnary),
779 Self::NbIndex => slots.as_number.index.load().map(SlotFunc::NumUnary),
780
781 Self::SqLength => slots.as_sequence.length.load().map(SlotFunc::SeqLength),
783 Self::SqConcat => slots.as_sequence.concat.load().map(SlotFunc::SeqConcat),
784 Self::SqRepeat => slots.as_sequence.repeat.load().map(SlotFunc::SeqRepeat),
785 Self::SqItem => slots.as_sequence.item.load().map(SlotFunc::SeqItem),
786 Self::SqAssItem => slots.as_sequence.ass_item.load().map(SlotFunc::SeqSetItem),
787 Self::SqContains => slots.as_sequence.contains.load().map(SlotFunc::SeqContains),
788 Self::SqInplaceConcat => slots
789 .as_sequence
790 .inplace_concat
791 .load()
792 .map(SlotFunc::SeqConcat),
793 Self::SqInplaceRepeat => slots
794 .as_sequence
795 .inplace_repeat
796 .load()
797 .map(SlotFunc::SeqRepeat),
798
799 Self::MpLength => slots.as_mapping.length.load().map(SlotFunc::MapLength),
801 Self::MpSubscript => slots
802 .as_mapping
803 .subscript
804 .load()
805 .map(SlotFunc::MapSubscript),
806 Self::MpAssSubscript => slots
807 .as_mapping
808 .ass_subscript
809 .load()
810 .map(SlotFunc::MapSetSubscript),
811
812 _ => None,
814 }
815 }
816
817 pub fn get_slot_func_with_op(
819 &self,
820 slots: &PyTypeSlots,
821 op: Option<SlotOp>,
822 ) -> Option<SlotFunc> {
823 if op == Some(SlotOp::Delete) {
825 match self {
826 Self::TpSetattro => return slots.setattro.load().map(SlotFunc::DelAttro),
827 Self::TpDescrSet => return slots.descr_set.load().map(SlotFunc::DescrDel),
828 Self::SqAssItem => {
829 return slots.as_sequence.ass_item.load().map(SlotFunc::SeqDelItem);
830 }
831 Self::MpAssSubscript => {
832 return slots
833 .as_mapping
834 .ass_subscript
835 .load()
836 .map(SlotFunc::MapDelSubscript);
837 }
838 _ => {}
839 }
840 }
841 if op == Some(SlotOp::Right) {
843 match self {
844 Self::NbAdd => {
845 return slots
846 .as_number
847 .right_add
848 .load()
849 .map(SlotFunc::NumBinaryRight);
850 }
851 Self::NbSubtract => {
852 return slots
853 .as_number
854 .right_subtract
855 .load()
856 .map(SlotFunc::NumBinaryRight);
857 }
858 Self::NbMultiply => {
859 return slots
860 .as_number
861 .right_multiply
862 .load()
863 .map(SlotFunc::NumBinaryRight);
864 }
865 Self::NbRemainder => {
866 return slots
867 .as_number
868 .right_remainder
869 .load()
870 .map(SlotFunc::NumBinaryRight);
871 }
872 Self::NbDivmod => {
873 return slots
874 .as_number
875 .right_divmod
876 .load()
877 .map(SlotFunc::NumBinaryRight);
878 }
879 Self::NbPower => {
880 return slots
881 .as_number
882 .right_power
883 .load()
884 .map(SlotFunc::NumTernaryRight);
885 }
886 Self::NbLshift => {
887 return slots
888 .as_number
889 .right_lshift
890 .load()
891 .map(SlotFunc::NumBinaryRight);
892 }
893 Self::NbRshift => {
894 return slots
895 .as_number
896 .right_rshift
897 .load()
898 .map(SlotFunc::NumBinaryRight);
899 }
900 Self::NbAnd => {
901 return slots
902 .as_number
903 .right_and
904 .load()
905 .map(SlotFunc::NumBinaryRight);
906 }
907 Self::NbXor => {
908 return slots
909 .as_number
910 .right_xor
911 .load()
912 .map(SlotFunc::NumBinaryRight);
913 }
914 Self::NbOr => {
915 return slots
916 .as_number
917 .right_or
918 .load()
919 .map(SlotFunc::NumBinaryRight);
920 }
921 Self::NbFloorDivide => {
922 return slots
923 .as_number
924 .right_floor_divide
925 .load()
926 .map(SlotFunc::NumBinaryRight);
927 }
928 Self::NbTrueDivide => {
929 return slots
930 .as_number
931 .right_true_divide
932 .load()
933 .map(SlotFunc::NumBinaryRight);
934 }
935 Self::NbMatrixMultiply => {
936 return slots
937 .as_number
938 .right_matrix_multiply
939 .load()
940 .map(SlotFunc::NumBinaryRight);
941 }
942 _ => {}
943 }
944 }
945 if let Self::TpRichcompare = self
947 && let Some(cmp_op) = op.and_then(|o| o.as_compare_op())
948 {
949 return slots
950 .richcompare
951 .load()
952 .map(|f| SlotFunc::RichCompare(f, cmp_op));
953 }
954 self.get_slot_func(slots)
956 }
957}
958
959pub fn find_slot_defs_by_name(name: &str) -> impl Iterator<Item = &'static SlotDef> {
961 SLOT_DEFS.iter().filter(move |def| def.name == name)
962}
963
964pub const SLOT_DEFS_COUNT: usize = SLOT_DEFS.len();
966
967pub static SLOT_DEFS: &[SlotDef] = &[
969 SlotDef {
971 name: "__init__",
972 accessor: SlotAccessor::TpInit,
973 op: None,
974 doc: "Initialize self. See help(type(self)) for accurate signature.",
975 },
976 SlotDef {
977 name: "__new__",
978 accessor: SlotAccessor::TpNew,
979 op: None,
980 doc: "Create and return a new object. See help(type) for accurate signature.",
981 },
982 SlotDef {
983 name: "__del__",
984 accessor: SlotAccessor::TpDel,
985 op: None,
986 doc: "Called when the instance is about to be destroyed.",
987 },
988 SlotDef {
989 name: "__repr__",
990 accessor: SlotAccessor::TpRepr,
991 op: None,
992 doc: "Return repr(self).",
993 },
994 SlotDef {
995 name: "__str__",
996 accessor: SlotAccessor::TpStr,
997 op: None,
998 doc: "Return str(self).",
999 },
1000 SlotDef {
1001 name: "__hash__",
1002 accessor: SlotAccessor::TpHash,
1003 op: None,
1004 doc: "Return hash(self).",
1005 },
1006 SlotDef {
1007 name: "__call__",
1008 accessor: SlotAccessor::TpCall,
1009 op: None,
1010 doc: "Call self as a function.",
1011 },
1012 SlotDef {
1013 name: "__iter__",
1014 accessor: SlotAccessor::TpIter,
1015 op: None,
1016 doc: "Implement iter(self).",
1017 },
1018 SlotDef {
1019 name: "__next__",
1020 accessor: SlotAccessor::TpIternext,
1021 op: None,
1022 doc: "Implement next(self).",
1023 },
1024 SlotDef {
1026 name: "__getattribute__",
1027 accessor: SlotAccessor::TpGetattro,
1028 op: None,
1029 doc: "Return getattr(self, name).",
1030 },
1031 SlotDef {
1032 name: "__getattr__",
1033 accessor: SlotAccessor::TpGetattro,
1034 op: None,
1035 doc: "Implement getattr(self, name).",
1036 },
1037 SlotDef {
1038 name: "__setattr__",
1039 accessor: SlotAccessor::TpSetattro,
1040 op: None,
1041 doc: "Implement setattr(self, name, value).",
1042 },
1043 SlotDef {
1044 name: "__delattr__",
1045 accessor: SlotAccessor::TpSetattro,
1046 op: Some(SlotOp::Delete),
1047 doc: "Implement delattr(self, name).",
1048 },
1049 SlotDef {
1051 name: "__eq__",
1052 accessor: SlotAccessor::TpRichcompare,
1053 op: Some(SlotOp::Eq),
1054 doc: "Return self==value.",
1055 },
1056 SlotDef {
1057 name: "__ne__",
1058 accessor: SlotAccessor::TpRichcompare,
1059 op: Some(SlotOp::Ne),
1060 doc: "Return self!=value.",
1061 },
1062 SlotDef {
1063 name: "__lt__",
1064 accessor: SlotAccessor::TpRichcompare,
1065 op: Some(SlotOp::Lt),
1066 doc: "Return self<value.",
1067 },
1068 SlotDef {
1069 name: "__le__",
1070 accessor: SlotAccessor::TpRichcompare,
1071 op: Some(SlotOp::Le),
1072 doc: "Return self<=value.",
1073 },
1074 SlotDef {
1075 name: "__gt__",
1076 accessor: SlotAccessor::TpRichcompare,
1077 op: Some(SlotOp::Gt),
1078 doc: "Return self>value.",
1079 },
1080 SlotDef {
1081 name: "__ge__",
1082 accessor: SlotAccessor::TpRichcompare,
1083 op: Some(SlotOp::Ge),
1084 doc: "Return self>=value.",
1085 },
1086 SlotDef {
1088 name: "__get__",
1089 accessor: SlotAccessor::TpDescrGet,
1090 op: None,
1091 doc: "Return an attribute of instance, which is of type owner.",
1092 },
1093 SlotDef {
1094 name: "__set__",
1095 accessor: SlotAccessor::TpDescrSet,
1096 op: None,
1097 doc: "Set an attribute of instance to value.",
1098 },
1099 SlotDef {
1100 name: "__delete__",
1101 accessor: SlotAccessor::TpDescrSet,
1102 op: Some(SlotOp::Delete),
1103 doc: "Delete an attribute of instance.",
1104 },
1105 SlotDef {
1109 name: "__len__",
1110 accessor: SlotAccessor::MpLength,
1111 op: None,
1112 doc: "Return len(self).",
1113 },
1114 SlotDef {
1115 name: "__getitem__",
1116 accessor: SlotAccessor::MpSubscript,
1117 op: None,
1118 doc: "Return self[key].",
1119 },
1120 SlotDef {
1121 name: "__setitem__",
1122 accessor: SlotAccessor::MpAssSubscript,
1123 op: None,
1124 doc: "Set self[key] to value.",
1125 },
1126 SlotDef {
1127 name: "__delitem__",
1128 accessor: SlotAccessor::MpAssSubscript,
1129 op: Some(SlotOp::Delete),
1130 doc: "Delete self[key].",
1131 },
1132 SlotDef {
1134 name: "__len__",
1135 accessor: SlotAccessor::SqLength,
1136 op: None,
1137 doc: "Return len(self).",
1138 },
1139 SlotDef {
1140 name: "__getitem__",
1141 accessor: SlotAccessor::SqItem,
1142 op: None,
1143 doc: "Return self[key].",
1144 },
1145 SlotDef {
1146 name: "__setitem__",
1147 accessor: SlotAccessor::SqAssItem,
1148 op: None,
1149 doc: "Set self[key] to value.",
1150 },
1151 SlotDef {
1152 name: "__delitem__",
1153 accessor: SlotAccessor::SqAssItem,
1154 op: Some(SlotOp::Delete),
1155 doc: "Delete self[key].",
1156 },
1157 SlotDef {
1158 name: "__contains__",
1159 accessor: SlotAccessor::SqContains,
1160 op: None,
1161 doc: "Return key in self.",
1162 },
1163 SlotDef {
1165 name: "__add__",
1166 accessor: SlotAccessor::NbAdd,
1167 op: Some(SlotOp::Left),
1168 doc: "Return self+value.",
1169 },
1170 SlotDef {
1171 name: "__radd__",
1172 accessor: SlotAccessor::NbAdd,
1173 op: Some(SlotOp::Right),
1174 doc: "Return value+self.",
1175 },
1176 SlotDef {
1177 name: "__iadd__",
1178 accessor: SlotAccessor::NbInplaceAdd,
1179 op: None,
1180 doc: "Implement self+=value.",
1181 },
1182 SlotDef {
1183 name: "__sub__",
1184 accessor: SlotAccessor::NbSubtract,
1185 op: Some(SlotOp::Left),
1186 doc: "Return self-value.",
1187 },
1188 SlotDef {
1189 name: "__rsub__",
1190 accessor: SlotAccessor::NbSubtract,
1191 op: Some(SlotOp::Right),
1192 doc: "Return value-self.",
1193 },
1194 SlotDef {
1195 name: "__isub__",
1196 accessor: SlotAccessor::NbInplaceSubtract,
1197 op: None,
1198 doc: "Implement self-=value.",
1199 },
1200 SlotDef {
1201 name: "__mul__",
1202 accessor: SlotAccessor::NbMultiply,
1203 op: Some(SlotOp::Left),
1204 doc: "Return self*value.",
1205 },
1206 SlotDef {
1207 name: "__rmul__",
1208 accessor: SlotAccessor::NbMultiply,
1209 op: Some(SlotOp::Right),
1210 doc: "Return value*self.",
1211 },
1212 SlotDef {
1213 name: "__imul__",
1214 accessor: SlotAccessor::NbInplaceMultiply,
1215 op: None,
1216 doc: "Implement self*=value.",
1217 },
1218 SlotDef {
1219 name: "__mod__",
1220 accessor: SlotAccessor::NbRemainder,
1221 op: Some(SlotOp::Left),
1222 doc: "Return self%value.",
1223 },
1224 SlotDef {
1225 name: "__rmod__",
1226 accessor: SlotAccessor::NbRemainder,
1227 op: Some(SlotOp::Right),
1228 doc: "Return value%self.",
1229 },
1230 SlotDef {
1231 name: "__imod__",
1232 accessor: SlotAccessor::NbInplaceRemainder,
1233 op: None,
1234 doc: "Implement self%=value.",
1235 },
1236 SlotDef {
1237 name: "__divmod__",
1238 accessor: SlotAccessor::NbDivmod,
1239 op: Some(SlotOp::Left),
1240 doc: "Return divmod(self, value).",
1241 },
1242 SlotDef {
1243 name: "__rdivmod__",
1244 accessor: SlotAccessor::NbDivmod,
1245 op: Some(SlotOp::Right),
1246 doc: "Return divmod(value, self).",
1247 },
1248 SlotDef {
1249 name: "__pow__",
1250 accessor: SlotAccessor::NbPower,
1251 op: Some(SlotOp::Left),
1252 doc: "Return pow(self, value, mod).",
1253 },
1254 SlotDef {
1255 name: "__rpow__",
1256 accessor: SlotAccessor::NbPower,
1257 op: Some(SlotOp::Right),
1258 doc: "Return pow(value, self, mod).",
1259 },
1260 SlotDef {
1261 name: "__ipow__",
1262 accessor: SlotAccessor::NbInplacePower,
1263 op: None,
1264 doc: "Implement self**=value.",
1265 },
1266 SlotDef {
1267 name: "__lshift__",
1268 accessor: SlotAccessor::NbLshift,
1269 op: Some(SlotOp::Left),
1270 doc: "Return self<<value.",
1271 },
1272 SlotDef {
1273 name: "__rlshift__",
1274 accessor: SlotAccessor::NbLshift,
1275 op: Some(SlotOp::Right),
1276 doc: "Return value<<self.",
1277 },
1278 SlotDef {
1279 name: "__ilshift__",
1280 accessor: SlotAccessor::NbInplaceLshift,
1281 op: None,
1282 doc: "Implement self<<=value.",
1283 },
1284 SlotDef {
1285 name: "__rshift__",
1286 accessor: SlotAccessor::NbRshift,
1287 op: Some(SlotOp::Left),
1288 doc: "Return self>>value.",
1289 },
1290 SlotDef {
1291 name: "__rrshift__",
1292 accessor: SlotAccessor::NbRshift,
1293 op: Some(SlotOp::Right),
1294 doc: "Return value>>self.",
1295 },
1296 SlotDef {
1297 name: "__irshift__",
1298 accessor: SlotAccessor::NbInplaceRshift,
1299 op: None,
1300 doc: "Implement self>>=value.",
1301 },
1302 SlotDef {
1303 name: "__and__",
1304 accessor: SlotAccessor::NbAnd,
1305 op: Some(SlotOp::Left),
1306 doc: "Return self&value.",
1307 },
1308 SlotDef {
1309 name: "__rand__",
1310 accessor: SlotAccessor::NbAnd,
1311 op: Some(SlotOp::Right),
1312 doc: "Return value&self.",
1313 },
1314 SlotDef {
1315 name: "__iand__",
1316 accessor: SlotAccessor::NbInplaceAnd,
1317 op: None,
1318 doc: "Implement self&=value.",
1319 },
1320 SlotDef {
1321 name: "__xor__",
1322 accessor: SlotAccessor::NbXor,
1323 op: Some(SlotOp::Left),
1324 doc: "Return self^value.",
1325 },
1326 SlotDef {
1327 name: "__rxor__",
1328 accessor: SlotAccessor::NbXor,
1329 op: Some(SlotOp::Right),
1330 doc: "Return value^self.",
1331 },
1332 SlotDef {
1333 name: "__ixor__",
1334 accessor: SlotAccessor::NbInplaceXor,
1335 op: None,
1336 doc: "Implement self^=value.",
1337 },
1338 SlotDef {
1339 name: "__or__",
1340 accessor: SlotAccessor::NbOr,
1341 op: Some(SlotOp::Left),
1342 doc: "Return self|value.",
1343 },
1344 SlotDef {
1345 name: "__ror__",
1346 accessor: SlotAccessor::NbOr,
1347 op: Some(SlotOp::Right),
1348 doc: "Return value|self.",
1349 },
1350 SlotDef {
1351 name: "__ior__",
1352 accessor: SlotAccessor::NbInplaceOr,
1353 op: None,
1354 doc: "Implement self|=value.",
1355 },
1356 SlotDef {
1357 name: "__floordiv__",
1358 accessor: SlotAccessor::NbFloorDivide,
1359 op: Some(SlotOp::Left),
1360 doc: "Return self//value.",
1361 },
1362 SlotDef {
1363 name: "__rfloordiv__",
1364 accessor: SlotAccessor::NbFloorDivide,
1365 op: Some(SlotOp::Right),
1366 doc: "Return value//self.",
1367 },
1368 SlotDef {
1369 name: "__ifloordiv__",
1370 accessor: SlotAccessor::NbInplaceFloorDivide,
1371 op: None,
1372 doc: "Implement self//=value.",
1373 },
1374 SlotDef {
1375 name: "__truediv__",
1376 accessor: SlotAccessor::NbTrueDivide,
1377 op: Some(SlotOp::Left),
1378 doc: "Return self/value.",
1379 },
1380 SlotDef {
1381 name: "__rtruediv__",
1382 accessor: SlotAccessor::NbTrueDivide,
1383 op: Some(SlotOp::Right),
1384 doc: "Return value/self.",
1385 },
1386 SlotDef {
1387 name: "__itruediv__",
1388 accessor: SlotAccessor::NbInplaceTrueDivide,
1389 op: None,
1390 doc: "Implement self/=value.",
1391 },
1392 SlotDef {
1393 name: "__matmul__",
1394 accessor: SlotAccessor::NbMatrixMultiply,
1395 op: Some(SlotOp::Left),
1396 doc: "Return self@value.",
1397 },
1398 SlotDef {
1399 name: "__rmatmul__",
1400 accessor: SlotAccessor::NbMatrixMultiply,
1401 op: Some(SlotOp::Right),
1402 doc: "Return value@self.",
1403 },
1404 SlotDef {
1405 name: "__imatmul__",
1406 accessor: SlotAccessor::NbInplaceMatrixMultiply,
1407 op: None,
1408 doc: "Implement self@=value.",
1409 },
1410 SlotDef {
1412 name: "__neg__",
1413 accessor: SlotAccessor::NbNegative,
1414 op: None,
1415 doc: "Return -self.",
1416 },
1417 SlotDef {
1418 name: "__pos__",
1419 accessor: SlotAccessor::NbPositive,
1420 op: None,
1421 doc: "Return +self.",
1422 },
1423 SlotDef {
1424 name: "__abs__",
1425 accessor: SlotAccessor::NbAbsolute,
1426 op: None,
1427 doc: "Return abs(self).",
1428 },
1429 SlotDef {
1430 name: "__invert__",
1431 accessor: SlotAccessor::NbInvert,
1432 op: None,
1433 doc: "Return ~self.",
1434 },
1435 SlotDef {
1436 name: "__bool__",
1437 accessor: SlotAccessor::NbBool,
1438 op: None,
1439 doc: "Return self != 0.",
1440 },
1441 SlotDef {
1442 name: "__int__",
1443 accessor: SlotAccessor::NbInt,
1444 op: None,
1445 doc: "Return int(self).",
1446 },
1447 SlotDef {
1448 name: "__float__",
1449 accessor: SlotAccessor::NbFloat,
1450 op: None,
1451 doc: "Return float(self).",
1452 },
1453 SlotDef {
1454 name: "__index__",
1455 accessor: SlotAccessor::NbIndex,
1456 op: None,
1457 doc: "Return self converted to an integer, if self is suitable for use as an index into a list.",
1458 },
1459 SlotDef {
1461 name: "__add__",
1462 accessor: SlotAccessor::SqConcat,
1463 op: None,
1464 doc: "Return self+value.",
1465 },
1466 SlotDef {
1467 name: "__mul__",
1468 accessor: SlotAccessor::SqRepeat,
1469 op: None,
1470 doc: "Return self*value.",
1471 },
1472 SlotDef {
1473 name: "__rmul__",
1474 accessor: SlotAccessor::SqRepeat,
1475 op: None,
1476 doc: "Return value*self.",
1477 },
1478 SlotDef {
1479 name: "__iadd__",
1480 accessor: SlotAccessor::SqInplaceConcat,
1481 op: None,
1482 doc: "Implement self+=value.",
1483 },
1484 SlotDef {
1485 name: "__imul__",
1486 accessor: SlotAccessor::SqInplaceRepeat,
1487 op: None,
1488 doc: "Implement self*=value.",
1489 },
1490];
1491
1492#[cfg(test)]
1493mod tests {
1494 use super::*;
1495
1496 #[test]
1497 fn test_find_by_name() {
1498 let len_defs: Vec<_> = find_slot_defs_by_name("__len__").collect();
1500 assert_eq!(len_defs.len(), 2);
1501
1502 let init_defs: Vec<_> = find_slot_defs_by_name("__init__").collect();
1504 assert_eq!(init_defs.len(), 1);
1505
1506 let add_defs: Vec<_> = find_slot_defs_by_name("__add__").collect();
1508 assert_eq!(add_defs.len(), 2); }
1510
1511 #[test]
1512 fn test_slot_op() {
1513 assert_eq!(SlotOp::Lt.as_compare_op(), Some(PyComparisonOp::Lt));
1515 assert_eq!(SlotOp::Eq.as_compare_op(), Some(PyComparisonOp::Eq));
1516 assert_eq!(SlotOp::Left.as_compare_op(), None);
1517
1518 assert!(SlotOp::Right.is_right());
1520 assert!(!SlotOp::Left.is_right());
1521 }
1522}