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