33 *
44 * The MIT License (MIT)
55 *
6- * Copyright (c) 2013, 2014 Damien P. George
6+ * Copyright (c) 2013-2017 Damien P. George
77 *
88 * Permission is hereby granted, free of charge, to any person obtaining a copy
99 * of this software and associated documentation files (the "Software"), to deal
@@ -57,23 +57,13 @@ STATIC bool is_set_or_frozenset(mp_obj_t o) {
5757 ;
5858}
5959
60+ // This macro is shorthand for mp_check_self to verify the argument is a set.
61+ #define check_set (o ) mp_check_self(MP_OBJ_IS_TYPE(o, &mp_type_set))
62+
6063// This macro is shorthand for mp_check_self to verify the argument is a
6164// set or frozenset for methods that operate on both of these types.
6265#define check_set_or_frozenset (o ) mp_check_self(is_set_or_frozenset(o))
6366
64- // This function is used to verify the argument for methods that modify
65- // the set object, and raises an exception if the arg is a frozenset.
66- STATIC void check_set (mp_obj_t o ) {
67- #if MICROPY_PY_BUILTINS_FROZENSET
68- if (MP_OBJ_IS_TYPE (o , & mp_type_frozenset )) {
69- // Mutable method called on frozenset; emulate CPython behavior, eg:
70- // AttributeError: 'frozenset' object has no attribute 'add'
71- mp_raise_msg (& mp_type_AttributeError , "'frozenset' has no such attribute" );
72- }
73- #endif
74- mp_check_self (MP_OBJ_IS_TYPE (o , & mp_type_set ));
75- }
76-
7767STATIC void set_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
7868 (void )kind ;
7969 mp_obj_set_t * self = MP_OBJ_TO_PTR (self_in );
@@ -188,26 +178,16 @@ STATIC mp_obj_t set_clear(mp_obj_t self_in) {
188178}
189179STATIC MP_DEFINE_CONST_FUN_OBJ_1 (set_clear_obj , set_clear );
190180
191- STATIC mp_obj_t set_copy_as_mutable (mp_obj_t self_in ) {
181+ STATIC mp_obj_t set_copy (mp_obj_t self_in ) {
182+ check_set_or_frozenset (self_in );
192183 mp_obj_set_t * self = MP_OBJ_TO_PTR (self_in );
193-
194184 mp_obj_set_t * other = m_new_obj (mp_obj_set_t );
195- other -> base .type = & mp_type_set ;
185+ other -> base .type = self -> base . type ;
196186 mp_set_init (& other -> set , self -> set .alloc );
197187 other -> set .used = self -> set .used ;
198188 memcpy (other -> set .table , self -> set .table , self -> set .alloc * sizeof (mp_obj_t ));
199-
200189 return MP_OBJ_FROM_PTR (other );
201190}
202-
203- STATIC mp_obj_t set_copy (mp_obj_t self_in ) {
204- check_set_or_frozenset (self_in );
205-
206- mp_obj_t other = set_copy_as_mutable (self_in );
207- ((mp_obj_base_t * )MP_OBJ_TO_PTR (other ))-> type = ((mp_obj_base_t * )MP_OBJ_TO_PTR (self_in ))-> type ;
208-
209- return other ;
210- }
211191STATIC MP_DEFINE_CONST_FUN_OBJ_1 (set_copy_obj , set_copy );
212192
213193STATIC mp_obj_t set_discard (mp_obj_t self_in , mp_obj_t item ) {
@@ -224,25 +204,23 @@ STATIC mp_obj_t set_diff_int(size_t n_args, const mp_obj_t *args, bool update) {
224204 check_set (args [0 ]);
225205 self = args [0 ];
226206 } else {
227- check_set_or_frozenset (args [0 ]);
228- self = set_copy_as_mutable (args [0 ]);
207+ self = set_copy (args [0 ]);
229208 }
230209
231-
232210 for (size_t i = 1 ; i < n_args ; i ++ ) {
233211 mp_obj_t other = args [i ];
234212 if (self == other ) {
235213 set_clear (self );
236214 } else {
215+ mp_set_t * self_set = & ((mp_obj_set_t * )MP_OBJ_TO_PTR (self ))-> set ;
237216 mp_obj_t iter = mp_getiter (other , NULL );
238217 mp_obj_t next ;
239218 while ((next = mp_iternext (iter )) != MP_OBJ_STOP_ITERATION ) {
240- set_discard ( self , next );
219+ mp_set_lookup ( self_set , next , MP_MAP_LOOKUP_REMOVE_IF_FOUND );
241220 }
242221 }
243222 }
244223
245- ((mp_obj_base_t * )MP_OBJ_TO_PTR (self ))-> type = ((mp_obj_base_t * )MP_OBJ_TO_PTR (args [0 ]))-> type ;
246224 return self ;
247225}
248226
@@ -333,16 +311,16 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool
333311 other = MP_OBJ_TO_PTR (set_make_new (& mp_type_set , 1 , 0 , & other_in ));
334312 cleanup_other = true;
335313 }
336- bool out = true ;
314+ mp_obj_t out = mp_const_true ;
337315 if (proper && self -> set .used == other -> set .used ) {
338- out = false ;
316+ out = mp_const_false ;
339317 } else {
340318 mp_obj_iter_buf_t iter_buf ;
341319 mp_obj_t iter = set_getiter (MP_OBJ_FROM_PTR (self ), & iter_buf );
342320 mp_obj_t next ;
343321 while ((next = set_it_iternext (iter )) != MP_OBJ_STOP_ITERATION ) {
344322 if (!mp_set_lookup (& other -> set , next , MP_MAP_LOOKUP )) {
345- out = false ;
323+ out = mp_const_false ;
346324 break ;
347325 }
348326 }
@@ -354,7 +332,7 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool
354332 if (cleanup_other ) {
355333 set_clear (MP_OBJ_FROM_PTR (other ));
356334 }
357- return mp_obj_new_bool ( out ) ;
335+ return out ;
358336}
359337STATIC mp_obj_t set_issubset (mp_obj_t self_in , mp_obj_t other_in ) {
360338 return set_issubset_internal (self_in , other_in , false);
@@ -409,7 +387,7 @@ STATIC mp_obj_t set_remove(mp_obj_t self_in, mp_obj_t item) {
409387STATIC MP_DEFINE_CONST_FUN_OBJ_2 (set_remove_obj , set_remove );
410388
411389STATIC mp_obj_t set_symmetric_difference_update (mp_obj_t self_in , mp_obj_t other_in ) {
412- check_set (self_in );
390+ check_set_or_frozenset (self_in ); // can be frozenset due to call from set_symmetric_difference
413391 mp_obj_set_t * self = MP_OBJ_TO_PTR (self_in );
414392 mp_obj_t iter = mp_getiter (other_in , NULL );
415393 mp_obj_t next ;
@@ -421,10 +399,8 @@ STATIC mp_obj_t set_symmetric_difference_update(mp_obj_t self_in, mp_obj_t other
421399STATIC MP_DEFINE_CONST_FUN_OBJ_2 (set_symmetric_difference_update_obj , set_symmetric_difference_update );
422400
423401STATIC mp_obj_t set_symmetric_difference (mp_obj_t self_in , mp_obj_t other_in ) {
424- check_set_or_frozenset (self_in );
425- mp_obj_t self_out = set_copy_as_mutable (self_in );
402+ mp_obj_t self_out = set_copy (self_in );
426403 set_symmetric_difference_update (self_out , other_in );
427- ((mp_obj_base_t * )MP_OBJ_TO_PTR (self_out ))-> type = ((mp_obj_base_t * )MP_OBJ_TO_PTR (self_in ))-> type ;
428404 return self_out ;
429405}
430406STATIC MP_DEFINE_CONST_FUN_OBJ_2 (set_symmetric_difference_obj , set_symmetric_difference );
@@ -578,6 +554,19 @@ const mp_obj_type_t mp_type_set = {
578554};
579555
580556#if MICROPY_PY_BUILTINS_FROZENSET
557+ STATIC const mp_rom_map_elem_t frozenset_locals_dict_table [] = {
558+ { MP_ROM_QSTR (MP_QSTR_copy ), MP_ROM_PTR (& set_copy_obj ) },
559+ { MP_ROM_QSTR (MP_QSTR_difference ), MP_ROM_PTR (& set_diff_obj ) },
560+ { MP_ROM_QSTR (MP_QSTR_intersection ), MP_ROM_PTR (& set_intersect_obj ) },
561+ { MP_ROM_QSTR (MP_QSTR_isdisjoint ), MP_ROM_PTR (& set_isdisjoint_obj ) },
562+ { MP_ROM_QSTR (MP_QSTR_issubset ), MP_ROM_PTR (& set_issubset_obj ) },
563+ { MP_ROM_QSTR (MP_QSTR_issuperset ), MP_ROM_PTR (& set_issuperset_obj ) },
564+ { MP_ROM_QSTR (MP_QSTR_symmetric_difference ), MP_ROM_PTR (& set_symmetric_difference_obj ) },
565+ { MP_ROM_QSTR (MP_QSTR_union ), MP_ROM_PTR (& set_union_obj ) },
566+ { MP_ROM_QSTR (MP_QSTR___contains__ ), MP_ROM_PTR (& mp_op_contains_obj ) },
567+ };
568+ STATIC MP_DEFINE_CONST_DICT (frozenset_locals_dict , frozenset_locals_dict_table );
569+
581570const mp_obj_type_t mp_type_frozenset = {
582571 { & mp_type_type },
583572 .name = MP_QSTR_frozenset ,
@@ -586,7 +575,7 @@ const mp_obj_type_t mp_type_frozenset = {
586575 .unary_op = set_unary_op ,
587576 .binary_op = set_binary_op ,
588577 .getiter = set_getiter ,
589- .locals_dict = (mp_obj_dict_t * )& set_locals_dict ,
578+ .locals_dict = (mp_obj_dict_t * )& frozenset_locals_dict ,
590579};
591580#endif
592581
0 commit comments