@@ -9,7 +9,6 @@ use crate::{
99 types:: { AsNumber , Constructor , Representable } ,
1010} ;
1111use core:: fmt:: { Debug , Formatter } ;
12- use malachite_bigint:: Sign ;
1312use num_traits:: Zero ;
1413
1514impl ToPyObject for bool {
@@ -42,46 +41,28 @@ impl PyObjectRef {
4241 if self . is ( & vm. ctx . false_value ) {
4342 return Ok ( false ) ;
4443 }
45- let rs_bool = if let Some ( nb_bool) = self . class ( ) . slots . as_number . boolean . load ( ) {
46- nb_bool ( self . as_object ( ) . number ( ) , vm) ?
47- } else {
48- // TODO: Fully implement AsNumber and remove this block
49- match vm. get_method ( self . clone ( ) , identifier ! ( vm, __bool__) ) {
50- Some ( method_or_err) => {
51- // If descriptor returns Error, propagate it further
52- let method = method_or_err?;
53- let bool_obj = method. call ( ( ) , vm) ?;
54- if !bool_obj. fast_isinstance ( vm. ctx . types . bool_type ) {
55- return Err ( vm. new_type_error ( format ! (
56- "__bool__ should return bool, returned type {}" ,
57- bool_obj. class( ) . name( )
58- ) ) ) ;
59- }
60-
61- get_value ( & bool_obj)
62- }
63- None => match vm. get_method ( self , identifier ! ( vm, __len__) ) {
64- Some ( method_or_err) => {
65- let method = method_or_err?;
66- let bool_obj = method. call ( ( ) , vm) ?;
67- let int_obj = bool_obj. downcast_ref :: < PyInt > ( ) . ok_or_else ( || {
68- vm. new_type_error ( format ! (
69- "'{}' object cannot be interpreted as an integer" ,
70- bool_obj. class( ) . name( )
71- ) )
72- } ) ?;
73-
74- let len_val = int_obj. as_bigint ( ) ;
75- if len_val. sign ( ) == Sign :: Minus {
76- return Err ( vm. new_value_error ( "__len__() should return >= 0" ) ) ;
77- }
78- !len_val. is_zero ( )
79- }
80- None => true ,
81- } ,
82- }
83- } ;
84- Ok ( rs_bool)
44+
45+ let slots = & self . class ( ) . slots ;
46+
47+ // 1. Try nb_bool slot first
48+ if let Some ( nb_bool) = slots. as_number . boolean . load ( ) {
49+ return nb_bool ( self . as_object ( ) . number ( ) , vm) ;
50+ }
51+
52+ // 2. Try mp_length slot (mapping protocol)
53+ if let Some ( mp_length) = slots. as_mapping . length . load ( ) {
54+ let len = mp_length ( self . as_object ( ) . mapping_unchecked ( ) , vm) ?;
55+ return Ok ( len != 0 ) ;
56+ }
57+
58+ // 3. Try sq_length slot (sequence protocol)
59+ if let Some ( sq_length) = slots. as_sequence . length . load ( ) {
60+ let len = sq_length ( self . as_object ( ) . sequence_unchecked ( ) , vm) ?;
61+ return Ok ( len != 0 ) ;
62+ }
63+
64+ // 4. Default: objects without __bool__ or __len__ are truthy
65+ Ok ( true )
8566 }
8667}
8768
0 commit comments